Mikrokontrolery STM32 - Wykorzystanie ADC i DMA.pdf

(916 KB) Pobierz
116-120_stm32.indd
PODZESPOŁY
Mikrokontrolery STM32
Wykorzystanie ADC i DMA
Otaczająca nas rzeczywistość ma postać analogową, zatem
każdy system mikroprocesorowy, który ma pracować w oparciu
o informacje pochodzące z tej rzeczywistości, musi być wyposażony
w przetworniki A/C. Większość z obecnie produkowanych
mikrokontrolerów posiada już wbudowane ADC na tyle dobrej
jakości, że często są one wystarczające dla poprawnego działania
aplikacji. Odpada zatem konieczność stosowania zewnętrznych
przetworników, co poprawia niezawodność i upraszcza budowę
urządzenia. W artykule przestawiamy w jaki sposób rozpocząć pracę
z ADC i DMA wbudowanymi w mikrokontrolery STM32. Wszystkie
projekty zostały przygotowane i uruchomione na płycie ewaluacyjnej
STM3210B-EVAL.
symalnie cztery. Zasadnicza różnica pomiędzy
tymi dwiema grupami polega na tym, że kon-
wersja kanałów należących do injected group
ma wyższy priorytet, niż regular group . Jeżeli
wykonanie przetwarzania A/C jest krytyczne
i nie może być mowy o jakichkolwiek opóź-
nieniach, to wówczas należy konwersję wyko-
nać przy pomocy kanałów ADC należących do
injected group . Jeżeli konwersja regular group
jest w trakcie wykonywania i MCU otrzyma
żądanie wykonania konwersji grupy „wstrzy-
kiwanej”, to wtedy następuje zawieszenie
przetwarzania na jej rzecz. W momencie, gdy
proces jej przetwarzania zostanie zakończony,
to wywłaszczona konwersja zostaje wznowio-
na od momentu jej przerwania. Zachowanie to
pokazano na rys. 2 . Ponadto injected group
ma oddzielne rejestry danych dla każdego
z kanałów pomiarowych, czyli w sumie cztery,
co zaznaczono na rys. 1.
Każda nieco bardziej zaawansowana aplikacja
wykorzystująca przetworniki A/C, wymaga specy-
ficznego podejścia. Z tego powodu producenci
mikrokontrolerów implementują w swoich ADC
coraz bardziej wymyślne tryby ich działania. Jest
to najczęściej ściśle związane z możliwymi za-
stosowaniami, do których przeznaczony jest
mikrokontroler. Również i w STM32 mamy do
dyspozycji kilka trybów działania ADC:
• ciągła lub jednorazowa konwersja pojedyn-
czego kanału, lub wielu kanałów,
• tryb nieciągły ( discontinuous ),
• jednoczesna praca dwóch przetworników,
• wyzwalanie przetwornika za pomocą timera
lub zewnętrznego przerwania.
Przetwornik jest również wyposażony
w sprzętowy, analogowy Watchdog, który ma
ustawiane progi (niski i wysoki), po przekrocze-
niu których może być generowane przerwanie.
Do tego wszystkiego możemy również ustawić
czas próbkowania sygnału. Dla potrzeb projek-
Każdy z mikrokontrolerów, należący do ro-
dziny STM32, jest wyposażony w przynajmniej
jeden przetwornik analogowo-cyfrowy oraz
sprzętowy kontroler DMA. Aby oswoić się nieco
z przetwarzaniem A/C, uruchomimy na począ-
tek prostą aplikację. Jej zadaniem będzie poka-
zywanie na wyświetlaczu LCD w formie wykre-
su U=f(t), wartości napięcia na doprowadzeniu
PC4, do którego dołączony jest potencjometr
RV1. Poznamy sposób, w jaki przetworniki są
konfigurowane i obsługiwane, co pozwoli na
zbudowanie bardziej skomplikowanych apli-
kacji. Gdy ADC będzie już pracował zgodnie
z założeniami, to wykorzystamy możliwości ja-
kie drzemią w kontrolerze DMA w połączeniu
z ADC. Materiały do projektów są dostępne
na stronie paprocki.wemif.net oraz na płycie
CD-EP1/2009B dołączonej do numeru. W pierw-
szej kolejności jednak zapoznamy się nieco bliżej
z budową przetworników A/C, w które wypo-
sażone są mikrokontrolery STM32.
wykonać dwa pomiary prądu dokładnie w tym
samym czasie. Oczywistym jest, że taka jedno-
czesna praca obydwu przetworników może być
wykorzystywana również wszędzie tam, gdzie
jest wymagany równoczesny pomiar kilku na-
pięć (lub pośrednio – prądów).
Wbudowane w mikrokontroler przetworniki
A/C są wyposażone w układy kalibracji. Dzięki
nim znacznie zmniejsza się błąd przetwarzania
wynikający z niedokładności pojemności kon-
densatorów pamiętających próbkowane na-
pięcie. Typowo pojemność takich kondensato-
rów wynosi 12 pF, jednak wykonywane są one
z pewną tolerancją, zatem wartość pojemności
może odbiegać od deklarowanej. Wpływ różnic
pojemności na wynik pomiaru niwelowany jest
w czasie kalibracji.
Z rys. 1 wynika, że ADC może przetwarzać
sygnały w dwóch grupach: regular group (re-
gularna) oraz injected group („wstrzykiwana”).
Wyjaśnimy pokrótce, na czym polegają różnice
w obsłudze tych dwóch grup.
Regular group – jest to grupa podstawowa,
do której możemy przypisać do szesnastu kana-
łów pomiarowych, w odróżnieniu od injected
group , do której mogą być przypisane mak-
Budowa przetwornika analogowo–
cyfrowego
Zamontowany na płytce ewaluacyjnej układ
STM32F103VB ma wbudowane dwa 12-bito-
we 16-kanałowe ADC, które mogą pracować
w wielu różnych trybach. Na rys. 1 przed-
stawiono uproszczoną budowę przetwornika
analogowo–cyfrowego zaimplementowanego
w wykorzystywanym przez nas mikrokontro-
lerze. Nasz bohater ma wbudowane dwa takie
przetworniki oznaczone jako ADC1 i ADC2.
Firma ST umieszczając w swoich produktach
wielokrotne, autonomiczne przetworniki ana-
logowo-cyfrowe, zrobiła ukłon w kierunku
konstruktorów wykorzystujących w swoich
aplikacjach bezszczotkowe silniki trójfazowe
prądu stałego. W tego typu rozwiązaniach,
aby kontrolować parametry pracy silnika, należy
Rys. 1. Uproszczony schemat blokowy przetwornika A/D
116
ELEKTRONIKA PRAKTYCZNA 1/2009
652389368.049.png 652389368.050.png 652389368.051.png 652389368.052.png 652389368.001.png 652389368.002.png 652389368.003.png 652389368.004.png 652389368.005.png 652389368.006.png 652389368.007.png 652389368.008.png 652389368.009.png 652389368.010.png 652389368.011.png
Wykorzystanie ADC i DMA
tów przykładowych przedstawionych w artykule
zostanie użyty tryb ciągły, z pomiarem jednego
lub dwóch kanałów.
Rys. 2. Ilustracja przerwy w konwersji grupy sygnałów regular na rzecz injected
Pomiar w trybie ciągłym
Na l ist. 1 przedstawiono program, który rea-
lizuje odczyt napięcia na nóżce PC4 mikrokontro-
lera (wyprowadzenie 33 dla obudowy LQFP100).
Na płytce STM3210B-EVAL wyprowadzenie to jest
podłączone do potencjometru RV1. Wartość napię-
cia zasilającego PC4 wskazywana jest na graficznym
wyświetlaczu LCD w formie wykresu U=f(t).
Z noty katalogowej mikrokontrolera
STM32F103VB można odczytać, że domyślną
funkcją alternatywną tego wyprowadzenia jest
ADC12_IN14, zatem będziemy korzystać z 14
kanału przetwornika. W tym przykładzie (jak
również w pozostałych) są wykorzystywane
standardowe funkcje obsługi LCD dostarczane
przez firmę ST. Są dobrze opisane w dokumen-
tacji, toteż nie będziemy się nimi szczegółowo
zajmować.
Aby przetwornik analogowo–cyfrowy działał
poprawnie, należy go w pierwszej kolejności
skonfigurować odpowiednio do potrzeb apli-
kacji. Będziemy korzystać z pierwszego prze-
twornika ADC1, o czym poinformujemy MCU
w odpowiednim miejscu. Tak, jak miało to miej-
sce w przypadku innych układów peryferyjnych
(artykuły w EP11/08 i EP12/08), konfigurowa-
nie ADC odbywa się poprzez wypełnianie pól
struktury inicjującej i późniejsze jej przekazanie
do odpowiedniej funkcji.
Po utworzeniu zmiennej ADC_InitStruct roz-
poczynamy wypełnianie jej pól. Pierwszy pa-
rametr określa, czy przetwornik ma pracować
samodzielnie, czy też wraz z drugim ADC. Dla
nas interesujący jest tryb pracy niezależnej ( inde-
pendent ). Ponieważ przetwarzamy tylko jeden
kanał, to wyłączamy opcję skanowania wielu ka-
nałów oraz włączamy pracę ciągłą ( continuous ).
Taki sposób pracy jest symbolicznie przedstawio-
ny na rys. 3 .
W naszym przykładzie nie będziemy korzy-
stać z wyzwalania ADC za pomocą np. któregoś
z timerów, czy też przerwania zewnętrznego,
zatem informujemy o tym MCU.
Wbudowany w mikrokontrolery STM32
przetwornik daje możliwość programowego
ustalenia, czy dane zapisywane do rejestru DR
( Data Register ) przetwornika mają być wyrów-
List. 1. Program odczytujący napięcie przyłożone do PC4
void RCC_Conf(void);
void NVIC_Conf(void);
void GPIO_Conf(void);
void SysTick_Conf(void);
int index = 0;
int wyniki[320] = {0};
int main(void)
{
ADC_InitTypeDef ADC_InitStruct;
RCC_Conf(); NVIC_Conf(); GPIO_Conf();
SysTick_Conf(); // SysTick wykorzystywany przez funkcje Delay()
// Jeden przetwornik, pracujacy niezaleznie
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
// Pomiar jednego kanalu, wylacz opcje skanowania
ADC_InitStruct.ADC_ScanConvMode = DISABLE;
// Wlacz pomiar w trybie ciaglym
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
// Nie bedzie wyzwalania zewnetrznego
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
// Dane wyrownane do prawej - znaczacych bedzie 12 mlodszych bitow
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
// Jeden kanal
ADC_InitStruct.ADC_NbrOfChannel = 1;
// Inicjuj przetwornik
ADC_Init(ADC1, &ADC_InitStruct);
// Grupa regularna, czas probkowania 71,5 cykla czyli 5,1us
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_71Cycles5);
// Wlacz ADC1
ADC_Cmd(ADC1, ENABLE);
// Resetuj rejestry kalibracyjne
ADC_ResetCalibration(ADC1);
// Czekaj, az skonczy resetowac
while(ADC_GetResetCalibrationStatus(ADC1));
// Start kalibracji ADC1
ADC_StartCalibration(ADC1);
// Czekaj na zakonczenie kalibracji ADC1
while(ADC_GetCalibrationStatus(ADC1));
// Start przetwarzania
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
// Inicjalizuj LCD
STM3210B_LCD_Init();
// Wyczysc LCD, tlo niebieskie
LCD_Clear(Blue);
while(1)
{
Delay(1); // Odswierzanie co 10ms
if(index==320) index=0; // wyswietlacz posiada 320 kolumn
// Czyszczenie LCD ze starych danych
LCD_SetCursor(wyniki[index], 320 - index);
LCD_WriteRAMWord(Blue);
// Odczytanie wartosci a ADC i obliczenia:
// 12 bitow = 4096 poziomow
// 240 wierszy LCD, zatem 4096/240 = 17
wyniki[index] = ADC_GetConversionValue(ADC1) / 17;
LCD_SetCursor(wyniki[index], 320 - index); // rysowanie punktow
LCD_WriteRAMWord(Red);
index++;
}
}
Rys. 3. Uproszczony schemat pracy A/D
w trybie pomiaru pojedynczego kanału
ELEKTRONIKA PRAKTYCZNA 1/2009
117
652389368.012.png 652389368.013.png 652389368.014.png 652389368.015.png 652389368.016.png 652389368.017.png 652389368.018.png 652389368.019.png
PODZESPOŁY
nywane do lewej, czy do prawej strony. Tutaj
używamy standardowego wyrównywania do
prawej, zatem znaczących jest 12 młodszych
bitów rejestru DR. Ostatnią informacją konfi-
guracyjną jest deklaracja liczby wykorzystywa-
nych kanałów przetwornika. Jako powiedzia-
no wcześniej, w naszym przypadku pomiar
będzie wykonywany z użyciem pojedynczego
kanału.
Analogicznie jak dla innych układów pery-
feryjnych, nazwa funkcji inicjujące jest zbieżna
z nazwą układu peryferyjnego i nastawy prze-
twornika analogowo-cyfrowego wprowadzane
są pomocą funkcji ADC_Init() .
Po konfiguracji przetwornika, należy doko-
nać wyboru, czy ADC ma pracować w grupie
injected , czy regular . Służy do tego funkcja
ADC_RegularChannelConfig() . W naszym przy-
kładzie przetwarzany jest jeden kanał w grupie
regularnej. Ponadto poprzez tę samą funkcję
jest ustalany czas, jaki będzie przeznaczony na
próbkowanie sygnału.
Po wykonaniu wszystkich niezbędnych
wstępnych czynności konfiguracyjnych, włą-
czamy przetwornik ADC1 wywołując funkcję
ADC_Cmd() . Aby uzyskać możliwie dokładny
wynik przetwarzania, musimy jeszcze dokonać
kalibracji ADC. W związku z tym, najpierw
zerujemy ustawienia kalibracyjne, czekamy na
wykonanie tego polecenia, a następnie każemy
przetwornikowi skalibrować się i również cze-
kamy na zakończenie operacji. Teraz można już
rozpocząć (programowo) właściwe przetwa-
rzanie, za co odpowiada funkcja ADC_Softwa-
reStartConvCmd() . Od tego momentu rejestr
danych DR jest aktualizowany cyklicznie, po
zakończeniu każdej konwersji. Po odczytaniu
jego wartości możemy już ją według potrzeb
dalej przetwarzać. W tym przykładzie, po prze-
liczeniach jest ona wyświetlana na LCD w po-
staci wykresu. W efekcie otrzymujemy bardzo
prosty rejestrator przebiegów analogowych,
w którym długość rekordu wynosi 320 próbek,
a napięcie jest próbkowane co 10 ms.
mowanie czasu, który będzie przeznaczony na
próbkowanie sygnału. Ma to szczególne znacze-
nie przy dopasowywaniu pracy ADC do środo-
wiska, w którym wykonywane są pomiary. Ste-
rując czasem próbkowania można optymalnie
dobierać nastawy w zależności od impedancji,
jaka jest podłączona do wejścia pomiarowego
przetwornika. Pozwala to na zminimalizowanie
błędów wynikających z niedopasowania ADC.
Maksymalna częstotliwość, z jaką może pra-
cować wbudowany w mikrokontrolery prze-
twornik analogowo-cyfrowy, wynosi 1 MHz
(czas konwersji 1 m s). Aby osiągnąć taki wynik,
należy ustawić częstotliwość taktowania szyny,
do której jest podłączony ADC, na 14, 28 lub
56 MHz. Sam przetwornik może być taktowany
z maksymalną częstotliwością równą 14 MHz.
W związku z tym, że sygnały zegarowe moż-
na dzielić tylko przez wartości będące potęgą
liczby dwa, maksymalna częstotliwość sygnału
zegarowego rdzenia, dla którego jest możliwe
osiągnięcie czasu konwersji równego 1 m s, to
56 MHz. W takim przypadku dzielnik częstotli-
wości ADC będzie wynosił cztery, co da w efek-
cie 14 MHz.
Generalnie czas konwersji jest wyznaczany
z zależności:
T = programowany czas próbkowania
+12,5 cyklu zegarowego
Minimalny programowany czas próbkowa-
nia jest równy 1,5 cyklu zegarowego. Podsu-
mowując, minimalny czas konwersji wynosi
1,5+12,5=14 cykli, a skoro częstotliwość
taktowania wynosi 14 MHz, to całkowity czas
przetwarzania A/C wynosi 1 m s.
Żeby przetwornik pracował z takim czasem
konwersji, należy w funkcji konfiguracji sygna-
łów zegarowych i resetu RCC_Conf(), zmodyfi-
kować linijkę odpowiadającą za mnożnik sygna-
łu PLL. Musi to być wykonane w taki sposób,
aby z podłączonego do mikrokontrolera rezo-
natora 8 MHz uzyskać częstotliwość 56 MHz.
Mnożnik „razy 7” można ustawić podając go
jako parametr wywołania funkcji:
RCC_PLLConfig(RCC_PLLSource_HSE_
Div1, RCC_PLLMul_7);
Następnym krokiem prowadzącym do uzy-
skania wymaganej w naszym przypadku czę-
stotliwości taktowania ADC równej 14 MHz,
jest podzielenie częstotliwości taktującej we-
wnętrzną szynę danych, do której podłączony
jest ADC (magistrala APB2), przez 4. Aby tego
dokonać, należy w funkcji RCC_Conf() umieścić
linię kodu:
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
Zapewni to częstotliwość taktowania ADC1
równą 14 MHz, a w konsekwencji czas prze-
twarzania równy 1 m s.
Programowany czas próbkowania
Wróćmy jeszcze raz do zagadnienia czasu
próbkowania. Przetwornik A/C, w jaki wyposa-
żony jest nasz mikrokontroler umożliwia (nieza-
leżnie dla każdego kanału, patrz rys. 2) progra-
List. 2. Program demonstrujący wyniki pomiaru napięcia na PC4 i pomiaru temperatury
#define ADC1_DR_Address ((u32)0x4001244C)
int index = 0;
int wyniki_RV1[320] = {0};
u16 temperatura;
char wynik_temperatura[8] = {0};
u16 ADCVal[2];
int main(void)
{
ADC_InitTypeDef ADC_InitStruct;
RCC_Conf(); NVIC_Conf(); GPIO_Conf(); SysTick_Conf(); DMA_Conf();
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
// Pomiar wielu kanalow, wlacz opcje skanowania
ADC_InitStruct.ADC_ScanConvMode = ENABLE;
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
// Dwa kanaly
ADC_InitStruct.ADC_NbrOfChannel = 2;
ADC_Init(ADC1, &ADC_InitStruct);
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_
71Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_
239Cycles5);
// Wlaczenie czujnika temperatury
ADC_TempSensorVrefintCmd(ENABLE);
// Wlaczenie DMA
ADC_DMACmd(ADC1, ENABLE);
ADC_Cal(); // Kalibracja ADC1
// Inicjalizuj LCD
STM3210B_LCD_Init();
// Wyczysc LCD, tlo niebieskie
LCD_Clear(Blue);
while(1)
{
Delay(1); // Odswierzanie co 10ms
if(index==320) index=0; // wyswietlacz posiada 320 kolumn
LCD_SetCursor(wyniki_RV1[index], 320 - index);
wyniki_RV1[index] = ADCVal[0] / 17;
temperatura = (1430 - ADCVal[1]*0.805) / 4.3 + 25;
LCD_SetCursor(wyniki_RV1[index], 320 - index);
Wiele kanałów w trybie ciągłym
Często aplikacja wymaga pomiaru kilku
napięć. Wówczas wykorzystuje się kilka wejść
pomiarowych przetwornika analogowo-cyfro-
wego. W przypadku mikrokontrolerów STM32
nie ma potrzeby wykonywania oddzielnych
LCD_WriteRAMWord(Red);
sprintf(wynik_temperatura, „T=%d stC”, temperatura);
// Odswierzanie temperatury co okolo 320ms
if(!(index % 32))
LCD_DisplayStringLine(1,(u8*)wynik_temperatura);
index++;
}
}
118
ELEKTRONIKA PRAKTYCZNA 1/2009
LCD_WriteRAMWord(Blue);
// Pomiar temperatury i obliczenia
652389368.020.png
Wykorzystanie ADC i DMA
przełączając go z trybu czuwania do normal-
nej pracy. Należy to zrobić wywołując funkcję
ADC_TempSensorVrefintCmd() . Dalej, po uru-
chomieniu przetwornika i zakończeniu kon-
wersji, musimy przeliczyć wartość, która jest
zawarta w rejestrze danych ADC, na wartość
wyrażoną w stopniach Celsjusza. Równanie
pozwalające obliczyć aktualną wartość tempera-
tury jest następujące:
tach. Jeśli by wszystkie napięcia wyrazić w wol-
tach, to trzeba by było mnożyć i dzielić przez
bardzo małe liczby, co nie jest ani przejrzyste,
ani efektywne. W tym równaniu można wszyst-
kie napięci a wy razić w miliwoltach, ponieważ
i tak one się skracają. Wróćmy do meritum.
Podstawiając otrzymane napięcia do równania
otrzymujemy:
T
( )
C
=
1430
mV
1436
mV
+
25
mV
V
V
( )
4
T
o
C
=
25
SE�SE
+
25
o
C
Avg
_
Slope
Rys. 4. Uproszczony schemat pracy A/D
w trybie skanowania kanałów pomiarowych
Poszczegó lne j ego składniki to:
V 25 – napięcie w temperaturze 25°C, może się
zawierać w granicach 1,34 do 1,52 V, typowo
wynosi 1,43 V;
V SENSE – zmierzona wartość napięcia czujnika
temperatury;
Avg_Slope stała wartość , może przyjmować
wartości z przedziału 4 do 4,6 , typowo wy-
nosi 4,3 .
W przed stawio nym przykład zie zost ały
przyjęte wart ośc i typowe, cz yli odpowiednio
V 25 =1,43 V, Avg_Slope= 4,3 . Ab y l epiej
zrozumieć, w jak i sp osób jest obliczana tem-
peratura przel ic zymy jeden przykład. Załóżmy,
że wartoś ć z miennej ADC Val[1 ], a tym samym
wynik pom iaru, wynosi 1785. Potrzebu jem y tą
wartość wyrażoną w wol tach, a zatem skoro
napięcie odn iesienia wynosi 3, 3 V, to roz dzie l-
czość przetwarzania:
Ostateczny wynik:
T = 23°C
Taka wartość zostanie wyświetlona na LCD.
Należy pamiętać, że pomiary temperatury są
obarczone błędem ±1,5°C.
Wynik ten można osiągnąć po przeprowa-
dzeniu kalibracji. Jeśli kalibracja nie zostanie
wykonana, to błąd pomiaru może być większy.
Kalibracja polega na odczycie wyniku pomia-
ru temperatury przy 25°C. Na jego podstawie
można wprowadzić stosowne poprawki do
równania podanego przez producenta.
pomiarów dla każdego z kanałów. Proces ten
jest zautomatyzowany. Do tego celu służy tryb
przemiatania (skanowania) wejść. Wybiera-
jąc ten tryb ustalamy, które kanały mają być
przetwarzane, w jakiej kolejności i jaki ma być
czas ich próbkowania.
Aby pokazać jak działa ten tryb, uruchomi-
my program, który będzie pokazywał na wy-
świetlaczu LCD graficznywynikpomiarunapię-
cia na potencjometrze RV1 oraz temperaturę
mikrokontrolera w formie liczbowej. Dodatko-
wo, nieco na wyrost, czasy próbkowania dla
pomiaru napięcia i temperatury będą różne,
a przetwornik będzie pracował w trybie cią-
głym. Na rys. 4 jest pokazano w sposób po-
glądowy zasada tego pomiaru, natomiast sto-
sowny program został umieszczony na list. 2 .
Powtarzający się w stosunku do programu
z list.1 kod źródłowy, został umieszczony
w funkcjach, aby niepotrzebnie nie zaciem-
niać istotnych funkcji. Można zauważyć, że
w odróżnieniu od poprzedniego przykładu,
tutaj włączamy opcję skanowania (przemiata-
nia) kanałów, informujemy, że przetwarzane
będą dwa (a nie jak poprzednio jeden) kanały.
To są wszystkie zmiany, jakich należy dokonać
podczas wypełniania struktury inicjującej prze-
twornik. Następnie ustalamy grupy kanałów,
ich kolejność przetwarzania i czasy próbko-
wania.
Dane z przetwornika są przesyłane za po-
mocą kanału 1 DMA bezpośrednio do pamięci
o rozmiarze dwóch 16–bitowych komórek.
Ten fragment pamięci to nic innego jak tablica,
której zadaniem jest przechowywanie wyni-
ków pomiarów. Są one następnie przeliczane
i wyświetlane na LCD.
Dodatkowego komentarza może wymagać
odczyt napięcia z czujnika temperatury. Czuj-
nik ten jest widziany z perspektywy mikro-
kontrolera jako kanał 16 (ADC12_IN16), zatem
taki wybieramy do konwersji. Producent zale-
ca, aby czas próbkowania wynosił minimum
17 m s, więc ustalamy czas próbkowania na
239,5 cyklu, co przekłada się na czas 17,1 m s.
Następnie trzeba włączyć czujnik temperatury,
4,6 C
4,6 C
mV
o
mV
o
DMA
W poprzednim przykładzie został wykorzy-
stany kontroler DMA, zatem warto nieco bliżej
zapoznać się z jego budową i zasadą działa-
nia.
Wiele zadań we współczesnych systemach
cyfrowych polega na przesyłaniu danych z jed-
nego miejsca w pamięci do drugiego. Stąd zro-
dziło się pytanie: po co angażować do tego celu
CPU? Jeżeli dane są tylko kopiowane lub prze-
noszone z miejsca na miejsce, to nie ma potrze-
by wykorzystywania mocy obliczeniowej i reje-
strów CPU. Zrodziła się wówczas idea budowy
U r
=
3
V
805
µ
V
0
805
mV
4095
o
Stąd warto ść z przetwornika wyrażona w m V
będzie wynosić:
( )
U T
=
1785 �
0
805
mV
1436
mV
o
Wyjaśnienia może wym agać jeszcze, dlaczego
napięcia wyraża my w miliwoltach, a nie wol-
List. 3. Funkcje konfigurująceDMA
void DMA_Conf(void)
{
// Ustawienia domyslne DMA
DMA_DeInit(DMA1_Channel1);
// Adres rejestru danych ADC (Data Register)
DMA_InitStruct.DMA_PeripheralBaseAddr = ADC1_DR_Address;
// Adres pamieci, pod jaki beda zapisywane dane
DMA_InitStruct.DMA_MemoryBaseAddr = (u32)&ADCVal;
// Kierunek: zrodlem jest ADC
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
// Rozmiar burora: dwa kanaly = rozmiar bufora 2
DMA_InitStruct.DMA_BufferSize = 2;
// Wylaczenie licznika inkrementujacego adres dla peryferia
// i wlaczenie go dla pamieci
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
// Dane 12 - bitowe, zatem wystarczy pol slowa
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_
HalfWord;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
// Wylaczenie przesylania z pamieci do pamieci
DMA_Init(DMA1_Channel1, &DMA_InitStruct);
// Wlacz DMA
DMA_Cmd(DMA1_Channel1, ENABLE);
}
ELEKTRONIKA PRAKTYCZNA 1/2009
119
o
mV
o
C
// Dane beda przesylane ciagle
// Priorytet wysoki
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
652389368.021.png 652389368.022.png 652389368.023.png 652389368.024.png 652389368.025.png 652389368.026.png 652389368.027.png 652389368.028.png 652389368.029.png 652389368.030.png 652389368.031.png 652389368.032.png 652389368.033.png 652389368.034.png 652389368.035.png 652389368.036.png 652389368.037.png 652389368.038.png 652389368.039.png 652389368.040.png 652389368.041.png 652389368.042.png 652389368.043.png 652389368.044.png 652389368.045.png
 
PODZESPOŁY
danych, przy czym maksymalny rozmiar takiego
bloku może wynosić 65535.
przesyłu danych z przetwornika ADC do pamięci
(czyli w efekcie do zmiennej). Funkcję konfiguru-
jącą DMA przedstawiono na list. 3 . Ponadto, aby
kontroler DMA pracował poprawnie, w pierwszej
kolejności należy włączyć jego sygnał zegarowy,
umieszczając w funkcji RCC_Conf() linijkę:
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_
DMA1, ENABLE);
System priorytetów obsługi
kanałów DMA.
Kontroler DMA, wbudowany w mikrokontro-
lery STM32 rozróżnia cztery programowo usta-
lane priorytety:
• najwyższy ( very high priority ),
• wysoki ( high priority ),
• średni ( medium priority ),
• niski ( low priority ).
Każdemu z dostępnych kanałów można
przyporządkować któryś z wyżej wymienionych
priorytetów. Powstaje jednak pytanie, co się
dzieje w chwili, gdy pojawiają się dwa żądania
dostępu do kontrolera DMA z dwóch kanałów
o takim samym programowym priorytecie?
W takim przypadku pierwszeństwo ma kanał
o mniejszym numerze, wyjaśnia to rys. 5 . Przy-
kładowo priorytet wysoki mają kanały 1 i 5, ale
gdy obydwa zażądają dostępu do DMA w tym
samym czasie, to w pierwszej kolejności zostanie
obsłużony kanał 1.
Wykorzystany w poprzedniej aplikacji (na
list. 2) kontroler DMA został skonfigurowany do
Rys. 5. Priorytety obsługi kanałów DMA
Podsumowanie
Przedstawione w artykule przykłady ukazują
tylko niewielką część możliwości, jakie oferują
konstruktorom przetworniki A/C wbudowane
w mikrokontrolery STM32. Ogromna różnorod-
ność trybów pracy oraz elastyczność konfiguracji
sprawiają, że te peryferia mogą być wykorzysty-
wane w aplikacjach, w których do niedawna
niezbędne było używanie zewnętrznych prze-
tworników. Gdy do współpracy z ADC zostanie
wykorzystany kontroler DMA, to w konsekwencji
programista otrzymuje system zdolny przetwa-
rzać spore ilości informacji, pozostawiając jeszcze
dużo wolnych zasobów CPU. Wolną moc oblicze-
niową mikrokontrolera można w takim przypad-
ku wykorzystać do realizacji innych zadań.
Krzysztof Paprocki
układu służącego do transmisji bloków danych
w pamięci. Układy z tej grupy noszą nazwę
kontrolerów DMA ( Direct Memory Access ). Zaj-
mują się całą pracą związaną z kopiowaniem
i przenoszeniem dużych bloków danych, zwal-
niając tym samym z tego obowiązku CPU.
Mikrokontroler STM32F103VB jest wyposa-
żony w 7-kanałowy kontroler DMA o ustawia-
nej na 8, 16 lub 32 bity długości słowa danych.
Każdemu z kanałów można przypisać określo-
ny priorytet. Możliwa jest transmisja pomiędzy
dwoma układami peryferyjnymi, z układu pe-
ryferyjnego do pamięci, z pamięci do układu
peryferyjnego oraz z pamięci do pamięci. Dane
można pojedynczo lub w postaci całych bloków
R
E
K
L
A
M
A
120
ELEKTRONIKA PRAKTYCZNA 1/2009
652389368.046.png 652389368.047.png 652389368.048.png
Zgłoś jeśli naruszono regulamin