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
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »