Zachodniopomorski Uniwersytet Technologiczny WYDZIAŁ ELEKTRYCZNY Katedra Inżynierii Systemów, Sygnałów i Elektroniki LABORATORIUM Podstawy Programowania Mikroprocesorów i Procesorów DSP Przetworniki DAC i ADC w mikrokontrolerach STM32F3 Opracował: mgr inż. Andrzej Biedka 1 Przetwornik cyfrowo-analogowy (ang. Digital to Analog Converter) jest urządzeniem elektronicznym zmieniającym n-bitowy sygnał cyfrowy na postać analogową, o wartościach dyskretnych, zależnych od rozdzielczości danego przetwornika. Oprócz wejściowych sygnałów cyfrowych konieczne jest podanie napięcia stałego o wysokiej stabilności, będącego napięciem odniesienia. Sygnałem wyjściowym przetwornika DAC może być zależnie od konstrukcji wartość napięcia lub prądu. Vref + VOUT DAC Vref - dn d2 d1 d0 Rys. 1. Symbol przetwornika cyfrowo-analogowego. Napięcie uzyskiwane na wyjściu przetwornika określone jest zależnością: VOUT = Vref x Data Input 2n n Zatem, zakres zmian napięcia wyjściowego wyniesie od 0 do Vref (1 – 1/2 ). Podstawowymi parametrami przetworników DAC są; • rozdzielczość przetwornika określona ilością bitów wejściowego sygnału cyfrowego, • zakres generowanego napięcia/prądu wyjściowego, zależny od napięcia odniesienia, • maksymalny czas ustalania napięcia wyjściowego, przy zmianie cyfrowego sygnału wejściowego z wartości minimalnej na maksymalną, • maksymalna częstotliwość zmian cyfrowego sygnału wejściowego dla sąsiednich próbek, przy zachowaniu prawidłowego odtwarzania napięcia/prądu wyjściowego, • maksymalny prąd wyjściowy lub minimalna rezystancja obciążenia przetwornika. • błędy liniowości przetwarzania, skali, monotoniczności. Mikrokontroler STM32F303RE zawiera dwa niezależne kanały przetworników DAC. Uproszczony schemat blokowy pojedynczego kanału przedstawiony jest na rysunku 2. TSELx SWTRIGx TIM2_TRGO TIM4_TRGO TIM6_TRGO TIM7_TRGO TIM8_TRGO TIM15_TRGO CR DHR8 Układ sterujący DHR12L DHR12R EXTI_9 DMA_Req. VDDA DOR x1 Vref + (3,3V) Vref - BOFF VOUT DAC Rys. 2. Uproszczony schemat blokowy pojedynczego kanału DAC µC STM32F303RE 2 Wejścia napięcia odniesienia są wewnętrznie połączone z obwodem zasilania bloków analogowych: ADC, DAC, komparatorów. Standardowo stosuje się do tego celu napięcie o wartości 3,3V. Przy konieczności uzyskania dużej dokładności pracy bloków analogowych należy je zasilać z precyzyjnego, liniowego stabilizatora napięcia. Rejestr DOR (Data Output Register) będący bezpośrednim źródłem sygnału cyfrowego dla przetwornika jest niedostępny do zapisu, można jedynie odczytywać jego zawartość. Ładowanie danych do rejestru DOR odbywa się za pośrednictwem rejestrów tymczasowych DHR (Data Hold Register). Każdy z kanałów posiada trzy rejestry tymczasowe przeznaczone do pracy autonomicznej (Single Mode) oraz trzy rejestry współdzielone z kanałem drugim, przeznaczone do pracy symultanicznej (Dual Mode) dwóch kanałów. Każdy z rejestrów tymczasowych DHR przeznaczony jest do przyjmowania innego formatu danych przesyłanych do przetwornika DAC. Tabela 1. Formatowanie danych przy pracy autonomicznej kanału DAC Prezentacja formatu Typ formatowania Rejestr Justowanie 8-bit do prawej DHR8 Justowanie 12-bit do lewej DHR12L Justowanie 12-bit do prawej DHR12R Źródło: STM32F303 – RM 0316 Wyboru formatu danych wysyłanych do przetwornika dokonuje się przez skierowanie danych do właściwego rejestru DHR. Układ sterujący kanału prześle słowo danych do dodatkowego rejestru roboczego w formacie 12-bitowego słowa, gotowego do przesłania do rejestru DOR: • słowo 8-bitowe z rejestru DHR8 zostanie przesunięte w lewo o 4 bity, na pozycje [11:0] • słowo 12-bitowe z rejestru DHR12L zostanie przesunięte w prawo o 4 bity, na pozycje [11:0] • słowo 12-bitowe z rejestru DHR12R zostanie przesłane bez zmian, na pozycje [11:0] Przesyłanie słów do rejestru DOR może być synchronizowane dwojako: • w trybie automatycznym - po wpisaniu danych do rejestru DHR następuje ich przepisanie (z uwzględnieniem justowania) do rejestru DOR po czasie równym jednemu cyklowi magistrali APB1 • w trybie wyzwalania sprzętowego – dane wpisane do rejestru DHR zostaną przepisane (z uwzględnieniem justowania) do rejestru DOR po wystąpieniu sygnału wyzwalającego (trigger) i po upływie dodatkowych trzech cykli magistrali PCLK1. Dla zachowania precyzji równych odstępów czasu generowania kolejnych próbek sygnału wyjściowego korzystniejszy jest tryb wyzwalania sprzętowego, w którym np.: timer wyznacza dokładne odcinki czasu i sprzętowo wymusza przepisanie kolejnych, wcześniej przygotowanych w rejestrze DHR próbek do rejestru wyjściowego DOR. Sygnał wyzwalający może pochodzić z timerów, z sygnału zewnętrznego podawanego przez pin mikrokontrolera lub z bitu ustawianego programowo w rejestrze sterującym. Rezystancja wyjściowa przetwornika DAC jest stosunkowo duża – wynosi ok. 15 kΩ. Dla prawidłowej pracy przyłączony do wyjścia DAC odbiornik powinien mieć rezystancję wejściową rzędu kilkuset k Ω. W celu zwiększenia wydajności prądowej zastosowano w obwodzie wyjściowym wzmacniacz prądu (bufor) pozwalający na zmniejszenie rezystancji obciążenia do wartości ok. 5kΩ. Bufor jest domyślnie włączony, można go wyłączyć ustawiając bit BOFFx w rejestrze DAC_CR. Niestety bufor charakteryzuje się nasyceniem napięcia wyjściowego ograniczającym dynamikę sygnału o maksymalnie 200 mV w pobliżu napięcia VDDA i VSSA, czyli przy napięciu zasilania 3,3 V maksymalna amplituda napięcia wyjściowego wyniesie: 3,3 V – 2 x 0,2V = 2,9 V. W mikrokontrolerze STM32F303RE wyprowadzenia kanałów DAC są współdzielone z liniami portu GPIOA: PA4 i PA5. Ponieważ w module NUCLEO-F303RE linia PA5 jest wykorzystywana do sterowania diodą LED (obciążona jest obwodem szeregowym diody LED i rezystora 510 omów) nie jest możliwe jej wykorzystanie jako wyjścia DAC. Zatem będziemy stosować wyjście DAC_1 dostępne jako funkcja dodatkowa linii PA4. 3 Przykładowy program generatora przebiegu piłokształtnego przedstawiony jest na poniższym listingu: volatile int Pila = 0; int main(void) { // Generator sygnalu pilozebnego // GPIOA RCC->AHBENR |= RCC_AHBENR_GPIOAEN; GPIOA->MODER |= GPIO_MODER_MODER5_0; GPIOA->MODER |= GPIO_MODER_MODER4; // DAC1_O1 (wyjscie PA4) RCC->APB1ENR |= RCC_APB1ENR_DAC1EN; DAC->CR |= DAC_CR_EN1; // PA5 -> wyjscie, LED zielony // PA4 -> funkcja analog, DAC // odblokowanie zegara DAC z magistrali APB1 // odblokowanie kanalu 1 DAC1 // timer 2 RCC->CFGR |= RCC_CFGR_PPRE1_DIV1; // preskaler magistrali APB1 RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // odblokowanie zegara TIM2 z magistrali APB1 TIM2->PSC = 2; // preskaler timera = 2 TIM2->ARR = 50; // rejestr przepelnienia = 50; 2 x 50 = 100, czyli 8MHz / 100 = 80kHz TIM2->CR1 |= TIM_CR1_CEN; // start licznika TIM2->DIER |= TIM_DIER_UIE; // odblokowanie przerwania NVIC_EnableIRQ(TIM2_IRQn); while(1); return 0; } void TIM2_IRQHandler(void){ if(TIM2->SR& TIM_SR_UIF){ TIM2->SR= ~TIM_SR_UIF; // kasowanie flagi zgloszenia Pila++; if(Pila > 255) Pila = 0; // obliczenie probki DAC->DHR8R1 = Pila; // laduj do rej. tymczasowego 8-bitowego } } Zadania: 1. Zmodyfikować program do funkcji generatora przebiegu trójkątnego o różnym nachyleniu zboczy. 2. Zmodyfikować program do funkcji generatora przebiegu sinusoidalnego. 3. W programie z pkt. 2 wyeliminować zniekształcenia wynikające z nasycenia bufora wyjściowego. 4 Przetwornik analogowo-cyfrowy (ang. Analog to Digital Converter) jest urządzeniem elektronicznym zmieniającym sygnał analogowy na n-bitowy sygnał cyfrowy, o wartościach dyskretnych, zależnych od rozdzielczości danego przetwornika. Przetwornik ADC wymaga podania napięcia stałego o wysokiej stabilności, będącego napięciem odniesienia. Najpopularniejszym typem przetworników ADC stosowanych w mikrokontrolerach jest przetwornik z sukcesywną aproksymacją. VIN dn ADC Vref + d1 d0 Vref - Rys. 3. Symbol przetwornika analogowo-cyfrowego. Podstawowymi parametrami przetworników ADC są; • rozdzielczość przetwornika określona ilością bitów wyjściowego sygnału cyfrowego, • zakres przetwarzanego napięcia wejściowego, zależny od napięcia odniesienia, • maksymalny czas przetwarzania, • maksymalna częstotliwość cyklu pracy przetwornika, • ilość przełączanych kanałów wejściowych przetwornika, • rodzaj pracy wejść: niesymetryczne (ang. single-ended), różnicowe (ang. differential) • błędy liniowości przetwarzania, skali, monotoniczności. Mikrokontroler STM32F303RE zawiera cztery niezależne przetworniki ADC. Uproszczony schemat blokowy pojedynczego kanału przedstawiony jest na rysunku 4. VDDA ADCx_IN1 ADCx_IN2 MPX1 ADEN VINP SMPx Vref + DR ADC VINN ADCx_IN15 CS Vref - ADC Int START DMA req. OVRMOD MPX2 wybór zbocza MPX3 S/W trigger EXT0 EXT1 VDD EXT15 ADRDY ALIGN EOC RES EOS CONT OVR Blok sterowania EXTEN EXTSEL Rys. 4. Uproszczony schemat blokowy przetwornika analogowo-cyfrowego STM32. Przedstawiony wyżej schemat blokowy obejmuje układy pracujące w zwykłym trybie pracy (ang. regular conversions) oraz przy użyciu niesymetrycznego wejścia (ang. single-ended input). Włączenie zasilania danego przetwornika realizowane jest łącznikiem sterowanym bitem ADEN. Przy pomocy multipleksera analogowego MPX1 wybierane jest wejście (pin mikrokontrolera), z którego będzie mierzone napięcie. Klucz SMPx łączy wyjście bufora z kondensatorem próbkowania napięcia mierzonego. Czas załączenia klucza jest ustawiany w rejestrach ADCx_SMPR1 i ADCx_SMPR2. Źródłem sygnału inicjującego przetwarzanie może być bit ADSTART zawarty w rejestrze ADCx_CR lub jedno z wejść EXTx, wybierane multiplekserem cyfrowym MPX2. Sygnały EXTx, są przypisane wyjściom TRGO timerów zgodnie z tablicą 90 z pliku Reference Manual mikrokontrolera. Dzięki temu po uruchomieniu właściwego 5 timera możliwe jest precyzyjne uruchamianie kolejnych cykli przetwarzania. Bity EXTEN z rejestru ADCx_CFG umożliwiają wybór zbocza sygnału wyzwalającego przetwarzanie. Po ukończeniu przetwarzania wynik zostaje załadowany do rejestru danych DR oraz zostaje ustawiona flaga EOC. Pracę przetwornika można skonfigurować przy pomocy bitów: Tabela 2. Podstawowe bity konfiguracji ADC Nazwa RES Opis Zakres Ustawianie rozdzielczości przetwarzania ADC 6, 8, 10, 12 bitów ALIGN Justowanie wyniku Do lewej, do prawej w rejestrze 16-bitowym CONT Jednokrotne wyzwalanie lub praca sekwencyjna OVRMOD (ang. Overrun Mode) nadpisywanie lub nie wyniku przetwarzania, gdy wynik poprzedni nie został odczytany Podstawowe flagi stanu przetwarzania są sygnalizowane przy pomocy bitów: Tabela 2. Podstawowe bity statusu pracy ADC Nazwa ADRDY Opis Flaga gotowości przetwornika, w szczególności istotna po włączeniu ADC EOC Flaga końca przetwarzania EOS Flaga końca sekwencji przetwarzania OVR Flaga wystąpienia nadpisania wyniku przetwarzania Przetwornik może generować żądanie obsługi przerwania oraz może współpracować z kanałem DMA. W mikrokontrolerach STM32 każdy przetwornik ADC może pracować w trybie zwykłej sekwencji kolejnych przetworzeń (ang. regular sequence), w którym określa się kolejność i numer kanału, z którego pobierane będzie napięcie do pomiaru. W sekwencji można zawrzeć od 1 do 16 pomiarów. Zaprogramowanie sekwencji odbywa się w rejestrach (litera x w nazwach rejestrów oznacza numer przetwornika z zakresu 1 - 4): • ADCx_SQR1, - cztery pierwsze pomiary w sekwencji • ADCx_SQR2, - pomiary 5 – 9 w sekwencji • ADCx_SQR3, - pomiary 10 – 14 w sekwencji • ADCx_SQR4, - pomiary 15 i 16 w sekwencji W każdym kroku programowanej sekwencji (pozycje SQn[4:0], gdzie n oznacza numer kroku) wpisać należy binarnie numer kanału wejściowego. W pozycjach bitów L[3:0] należy wpisać binarnie ilość kroków sekwencji, przy czym dla pojedynczego przetworzenia należy wpisać 0. Bity L[3:0] – długość zwykłej sekwencji przetwarzania 0000 – 1 konwersja 0001 – 2 konwersje ••• 1111 – 16 konwersji Rys. 5. Opis rejestru ADCx_SQR1 - źródło STM32F303 Reference Manual. 6 Innym trybem pracy przetworników ADC jest tryb sekwencji wtrącanej (ang. injected sequence) posiadający własny rejestr sekwencji ADCx_JSQR. Sekwencja wtrącana pozwala na zaprogramowanie 1 – 4 kroków. Można ją zastosować na przykład do pomiaru/pomiarów wykonywanych rzadziej: temperatura otoczenia, napięcie baterii zasilającej. Przetworniki ADC posiadają wewnętrzny układ autokalibracji pozwalający na kompensację błędów wynikających z rozrzutów produkcyjnych elementów przetwornika jak również źródła napięcia odniesienia. Uruchomienie autokalibracji następuje przez ustawienie bitu ADC_CR_ADCAL w rejestrze ADCx_CR. Bit ten jest kasowany sprzętowo po zakończeniu kalibracji. Przykładowy program wykorzystujący przetwornik ADC przedstawiony jest na poniższym listingu: int main(void) { int ii, Wynik ; // program pracy ADC, wynik wyswietlany binarnie na porcie GPIOC // GPIO RCC->AHBENR |= RCC_AHBENR_GPIOAEN; GPIOA->MODER |= GPIO_MODER_MODER5_0; // PA5 - LED GPIOA->MODER |= GPIO_MODER_MODER1; // linia PA1 - analog RCC->AHBENR |= RCC_AHBENR_GPIOCEN; GPIOC->MODER = GPIO_MODER_MODER7_0 | GPIO_MODER_MODER6_0 | GPIO_MODER_MODER5_0 | GPIO_MODER_MODER4_0 | GPIO_MODER_MODER3_0 | GPIO_MODER_MODER2_0 | GPIO_MODER_MODER1_0 | GPIO_MODER_MODER0_0; // ADC RCC->AHBENR |= RCC_AHBENR_ADC12EN; // taktowanie bloku ADC12 z magistrali AHB ADC1_2_COMMON ->CCR |= ADC12_CCR_CKMODE_0; // taktowanie ACD12 zegarem HCLK ADC1->CR &= ~ADC_CR_ADVREGEN_1; // zablokowanie stanu default zasilania ADC ADC1->CR |= ADC_CR_ADVREGEN_0; // odblokowanie zasilania ADC // kalibracja ADC ADC1-> CR &= (~ADC_CR_ADCALDIF); // single ended channel //start calibration procedure ADC1-> CR |= (ADC_CR_ADCAL); // start kalibracji while((ADC1-> CR) & (ADC_CR_ADCAL)); // czekaj na koniec ADC1->CR |= ADC_CR_ADEN; // wlacz ADC1 while( ! (ADC1->ISR & ADC_ISR_ADRD) ); // czekaj na wlaczenie ADC // ladowanie rejestru sekwencji przetwarzania // dla pojedynczego przetwarzania licznik ma wartosc domyslna ADC1->SQR1 = 2 << 6; // numer kanalu ADC = 2 dla linii portu PA1 while(1) { ADC1->CR |= ADC_CR_ADSTART; // nastepne przetwarzanie while( ! (ADC1->ISR & ADC_ISR_EOC) ); // czekaj na koniec przetwarzania Wynik = ADC1->DR; // czytaj wynik i kasuj flage 'ADC_ISR_EOC' GPIOC->ODR = Wynik >>= 4 ; // wpisz wynik (8 bitow) do portu GPIOC GPIOA->ODR ^= GPIO_ODR_5; // negacja linii PA5, LED jako bit kontrolny ii = 0xffff; while(--ii); // czekaj... } return 0; } 7