Elvis Napisano Luty 20, 2011 Udostępnij Napisano Luty 20, 2011 Poprzednia część kursu. [Kurs] Programowanie ARM LPC1114 cz.6 - ADC W tym odcinku zajmiemy się działaniem przetwornika analogowo-cyfrowego (ang. Analog-to-Digital Converter). Mikrokontroler LPC1114 jest wyposażony w jeden, 10-bitowy przetwornik. Wejście przetwornika podłączone jest przez multiplekser do 8 wejść procesora. Możemy wybrać, sygnał z którego wejścia chcemy odczytać. • AD0 - P0.11 • AD1 - P1.0 • AD2 - P1.1 • AD3 - P1.2 • AD4 - P1.3 • AD5 - P1.4 • AD6 - P1.10 • AD7 - P1.11 Na płytce ZL32ARM znajdziemy potencjometr P1 podłączony do pinu P0.11, czyli kanału AD0 przetwornika A/C. Obracając potencjometrem możemy zmieniać napięcie podawane na wejście przetwornika. Przetwornik zmienia napięcie na liczby. Jak wiemy przetwornik jest 10-bitowy. Oznacza to, że pozwala na odczyt 2^10, czyli 1024 poziomów napięcia. Są one reprezentowane jako liczby od 0, do 1023. Jeśli na wejście przetwornika podamy napięcie 0V, odczytamy wartość 0, gdy napięcie 3.3V, odczytamy 1023. Ogólnie przeliczenie z napięcia, na wartość wyraża wzór: ADC = 1023 * Vad / 3.3 Podobnie, mając odczytaną wartość z przetwornika, możemy obliczyć napięcie na przetworniku: Vad = 3.3 * ADC / 1023 Gdy znamy podstawy działania przetwornika, czas napisać program odczytujący wartość z przetwornika. W pliku program16.zip znajdziemy omawiany program. Opis zaczniemy niejako od końca. Mamy dwie funkcje: adc_init() adc_get(int channel) Pierwszą należy wywołać raz na początku programu. Druga funkcja odczytuje wartość z przetwornika o podanym numerze. Wykorzystamy wcześniej podane układy peryferyjne, aby w zależności od wartości z przetwornika: • regulować częstotliwość migania diody LED • wysyłać odczytaną wartość z przetwornika przez RS-232 • sterować prędkością silnika zależnie od położenia potencjometru Pętla główna programu wygląda następująco: while(1) { val = adc_get(0); uart_send_int(val); uart_send("\n"); if (val>=0) { pwm_set(val/10, 100-val/10); GPIOClear(LED_1); delay(val/50); GPIOSet(LED_1); delay(20-val/50); } } Funkcja uart_send_int wysyła wartość liczbową (odczytaną z przetwornika) przez RS-232. Funkcja pwm_set służy do sterowania prędkością silników robota. Opóźnienia (funkcja delay) regulują częstotliwość migania diody. Program jak widać jest bardzo krótki, Poniżej rezultat działania: Teraz zajmijmy się funkcjami obsługującymi konwerter. • adc_init() Ta funkcja ma dwa zadania. Po pierwsze musi uruchomić przetwornik (domyślnie wyłączony, aby oszczędzać prąd). Realizują to następujące instrukcje: LPC_SYSCON->PDRUNCFG &= ~0x0010; LPC_SYSCON->SYSAHBCLKCTRL |= 0x2000; Kolejnym krokiem jest ustawienie funkcji pinów przetwornika. Na razie wykorzystamy tylko kanał AD0: LPC_IOCON->R_PIO0_11 = 0x02; • adc_get Przed konwersją ustawiamy parametry pracy przetwornika. Realizuje to linia: LPC_ADC->CR = ADCR_CLKDIV|(1<<channel); channel to numer kanału, z którego będziemy odczytywać dane (u nas 0). Natomiast stała ADCR_CLKDIV określa dzielnik zegara dla przetwornika A/C. Procesor jak pamiętamy działa z częstotliwością 48MHz. Natomiast przetwornik wymaga zegara o częstotliwości co najwyżej 4.5MHz. Musimy więc podzielić częstotliwość zegara systemowego przez 11 (48MHz/11 = 4.36MHz). Możemy podać większą wartość dzielnika, natomiast należy unikać przekraczania częstotliwości 4.5MHz - może to spowodować błędne działanie przetwornika. Stała ADCR_CLKDIV zawiera wartość dzielnika pomniejszoną o 1. Chcemy używać dzielnik 11, więc definiujemy: #define ADCR_CLKDIV (10<<8) Dalej następuje uruchomienie konwertera: LPC_ADC->CR |= 0x01000000; Oczekiwanie na zakończenie konwersji: while (((val=LPC_ADC->GDR) & 0x80000000)==0); Na koniec wyłączenie konwertera i zapisanie wyniku: LPC_ADC->CR &= ~0x01000000; if ((val & 0x40000000)==0) { result = (val>>6) & 0x3ff; } Jeśli jest to nieco zawiłe, nie należy się poddawać, w przykładowych programach znajdziemy gotową funkcję obsługi konwertera. Więcej kanałów przetwornika Umiemy już odczytywać dane z kanału 0 (AD0), czas odczytać wszystkie 8 kanałów. Kolejny przykład znajdziemy w pliku program17.zip. Funkcje dotyczące przetwornika A/C zostały przeniesione do nowego modułu (pliki adc.h oraz adc.c). Tym razem wszystkie piny podłączone do konwertera są ustawiane jako wejścia przetwornika analogowo-cyfrowego: LPC_IOCON->R_PIO0_11 = 0x02; // P0.11 <- AD0 LPC_IOCON->R_PIO1_0 = 0x02; // P1.0 <- AD1 LPC_IOCON->R_PIO1_1 = 0x02; // P1.1 <- AD2 LPC_IOCON->R_PIO1_2 = 0x02; // P1.2 <- AD3 LPC_IOCON->SWDIO_PIO1_3 = 0x02; // P1.3 <- AD4 LPC_IOCON->PIO1_4 = 0x01; // P1.4 <- AD5 LPC_IOCON->PIO1_10 = 0x01; // P1.10 <- AD6 LPC_IOCON->PIO1_11 = 0x01; // P1.11 <- AD7 Ponieważ przesyłamy znacznie więcej danych przez RS-232, zwiększona została prędkość transmisji. Zamiast jak dotychczas 9600, dane wysyłane są z prędkością 115200. Poniżej widzimy rezultat działania programu: Odczyt z kanału AD0 możemy regulować potencjometrem, pozostałe wymagają podłączenia źródła sygnału. Ponieważ docelowym przykładem będzie robot, pozostałe wejścia zostaną podłączone do optoelementów. Napięcie na przetworniku będzie się zmieniało w zależności od koloru podłoża. program16.zip program17.zip 1 Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!