W tym poście chciałbym opisać sposób obsługi układu ADC na rejestrach mikrokontrolera STM32F4.
Podłączenie:
ADC zostało wyprowadzone na następujące piny:
Wszystkie ADC taktowane są z linii APB2 z dzielnikiem 2.
ADC1:
- ADC Kanał 0 - PA0
- ADC Kanał 1 - PA1
- ADC Kanał 2 - PA2
- ADC Kanał 3 - PA3
- ADC Kanał 4 - PA4
- ADC Kanał 5 - PA5
- ADC Kanał 6 - PA6
- ADC Kanał 7 - PA7
- ADC Kanał 8 - PB0
- ADC Kanał 9 - PB1
- ADC Kanał 10 - PC0
- ADC Kanał 11 - PC1
- ADC Kanał 12 - PC2
- ADC Kanał 13 - PC3
- ADC Kanał 14 - PC4
- ADC Kanał 15 - PC5
ADC2:
- ADC Kanał 0 - PA0
- ADC Kanał 1 - PA1
- ADC Kanał 2 - PA2
- ADC Kanał 3 - PA3
- ADC Kanał 4 - PA4
- ADC Kanał 5 - PA5
- ADC Kanał 6 - PA6
- ADC Kanał 7 - PA7
- ADC Kanał 8 - PB0
- ADC Kanał 9 - PB1
- ADC Kanał 10 - PC0
- ADC Kanał 11 - PC1
- ADC Kanał 12 - PC2
- ADC Kanał 13 - PC3
- ADC Kanał 14 - PC4
- ADC Kanał 15 - PC5
ADC3:
- ADC Kanał 0 - PA0
- ADC Kanał 1 - PA1
- ADC Kanał 2 - PA2
- ADC Kanał 3 - PA3
- ADC Kanał 4 - PF6
- ADC Kanał 5 - PF7
- ADC Kanał 6 - PF8
- ADC Kanał 7 - PF9
- ADC Kanał 8 - PF10
- ADC Kanał 9 - PF3
- ADC Kanał 10 - PC0
- ADC Kanał 11 - PC1
- ADC Kanał 12 - PC2
- ADC Kanał 13 - PC3
- ADC Kanał 14 - PC4
- ADC Kanał 15 - PC5
Programowanie:
Poniżej przedstawię poszczególne części kodu wraz z opisem rejestrów dla ADC.
Na samym początku należy włączyć zegar dla odpowiedniego zegara ADC1.
- RCC->APB2ENR |= 0x00000100;
W przypadku korzystania z ADC2 należy wprowadzić linijkę poniżej itd. dla kolejnych ADC.
- RCC->APB2ENR |= 0x00000200;
Kolejnym elementem jest wyłączenie DMA, ponieważ chce skorzystać z samego ADC:
Rejestr CCR wygląda następująco:
Ustawia się odpowiednie wartości w sekcji MULTI. Tutaj można ustawić różne rodzaje trybów pracy (RM0090 str. 432.)
Włączenie ADC1:
W tym celu jak widać powyżej należy się odnieść do rejestru drugiego kontrolnego:
W tym rejestrze należy bit 0 ustawić na 1 aby ADC został włączony. Dodatkowo rejestr pozwala na ustawienie trybów konwersji, DMA, ułożenia danych, przerwań od odpowiednich timerów itp.
Ustawienie danych w rejestrze sekwencji,
Tym razem trzeba przejść do sekwencji. Wygląda on następująco:
Włączenie pinu PA2 dla ADC2.
Następne operacje będą już wykonywane w pętli while. Należy rozpocząć od włączenie konwersji danych:
Dalej należy już tylko pobrać dane z ADC1 za pomocą odpowiedniego rejestru:
Ostatnim z wykorzystywanych rejestrów jest DR.
Cały kod prezentuje się w następujący sposób:
- ADC->CCR = 0x00000006;
Rejestr CCR wygląda następująco:
Ustawia się odpowiednie wartości w sekcji MULTI. Tutaj można ustawić różne rodzaje trybów pracy (RM0090 str. 432.)
Włączenie ADC1:
- ADC1->CR2 = 0x00000001;
W tym celu jak widać powyżej należy się odnieść do rejestru drugiego kontrolnego:
W tym rejestrze należy bit 0 ustawić na 1 aby ADC został włączony. Dodatkowo rejestr pozwala na ustawienie trybów konwersji, DMA, ułożenia danych, przerwań od odpowiednich timerów itp.
Ustawienie danych w rejestrze sekwencji,
- ADC1->SQR3 = 0x00000002;
Tym razem trzeba przejść do sekwencji. Wygląda on następująco:
Włączenie pinu PA2 dla ADC2.
- GPIOA->MODER |= 0x00000030;
Następne operacje będą już wykonywane w pętli while. Należy rozpocząć od włączenie konwersji danych:
- ADC1->CR2 |= ADC_CR2_SWSTART;
W tym przypadku rozpoczyna się konwersja poprzez ustawienie bitu 30 w rejestrze CR2. Wartość zostaje ustawiona programowo, gdy konwersja się zakończy część sprzętowa zmienia wartość w rejestrze z 0 na 1.
Dalej należy już tylko pobrać dane z ADC1 za pomocą odpowiedniego rejestru:
- ADC1_result = (int16_t)ADC1->DR;
Ostatnim z wykorzystywanych rejestrów jest DR.
Cały kod prezentuje się w następujący sposób:
- int main ()
- {
- int16_t ADC_result = 0;
- RCC->APB2ENR |= 0x00000100;
- ADC->CCR = 0x00000006;
- ADC1->CR2 = 0x00000001;
- ADC1->SQR3 = 0x00000002;
- GPIOA->MODER |= 0x00000030;
- while (1)
- {
- ADC1->CR2 |= ADC_CR2_SWSTART;
- ADC1_result = (int16_t)ADC1->DR;
- }
- }
Bibliografia
[1] Reference manual RM0090