poniedziałek, 14 września 2015

[3] STM32F4 - ADC

W tym poście chciałbym przedstawić działanie ADC w STM32F4. Przykład zaprezentuje w oparciu o odczyt danych z potencjometru.

Podłączenie


W podłączeniu nie ma niczego skomplikowanego. Jeden pin podłączamy do PC0 (środkowy), pozostałe do masy i do zasilania 5V.

Program


Program dokonuje konwersji danych odczytanych z potencjometru. W pierwszej funkcji tj. KonfiguracjaADC następuje odpowiednie ustawienie potrzebnych danych oraz kalibracja. KonwersjaADC odczytuje dane z ADC, które następnie przesyła do funkcji głównej. Wszystkie informacje odnośnie każdej z linijek podałem bezpośrednio w kodzie do programu.

#include "defines.h"
 
#include "stm32f4xx.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_adc.h"
 
int WartoscPrzetwo = 0; // wartosc odczytana z ADC
 
void KonfiguracjaADC(void);
int KonwersjaADC(void);
 
int main(void)
{
 //Rozpoczecie konfiguracji
 KonfiguracjaADC();                
 while(1)
 {
  //Odczytanie przetworzonej wartosci
  WartoscPrzetwo = KonwersjaADC();        
  }
}
void KonfiguracjaADC()
{
 ADC_InitTypeDef ADC_Init_Structure;
 GPIO_InitTypeDef GPIO_Init_Structure;
 
 //Konfiguracja zegarów
 //ADC1 podlaczone do APB2
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
 //Zegar dla portu ADC
 RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOCEN, ENABLE);
 
 //Konfiguracja pinu analogowego
 //Kanal 10 podlaczony do PC0
 GPIO_Init_Structure.GPIO_Pin = GPIO_Pin_0;
 GPIO_Init_Structure.GPIO_Mode = GPIO_Mode_AN;
 GPIO_Init_Structure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_Init(GPIOC, &GPIO_Init_Structure);
 
 //Konfiguracja ADC
 ADC_DeInit();
 //Przetworzone dane wyrównane do prawej
 ADC_Init_Structure.ADC_DataAlign = ADC_DataAlign_Right;
 //Dane wejsciowe przetwarzane w 12 bitowy numer z duza dokladnoscia, max 4096
 ADC_Init_Structure.ADC_Resolution = ADC_Resolution_12b;
 //Konwersacja jest ciagla przetwarzanie wiecej niz jeden raz
 ADC_Init_Structure.ADC_ContinuousConvMode = ENABLE;
 ADC_Init_Structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
 //Bez wyzwalania zewnetrznego
 ADC_Init_Structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
 //Liczba konwersji
 ADC_Init_Structure.ADC_NbrOfConversion = 1;
 //Pomiar jednego kanalu, skanowanie kanalow zostalo wylaczone
 ADC_Init_Structure.ADC_ScanConvMode = DISABLE;    
 //Inicjalizacja ADC
 ADC_Init(ADC1, &ADC_Init_Structure);
 
 
 //Wybranie kanalu z którego bedzie odczytywane
 //ADC kanal 10, GPIOC1, Czestotliwosc probkowania = 1Mhz
 ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_144Cycles);
 
 //Wlaczenie konwersji ADC
 ADC_Cmd(ADC1,ENABLE);
}
 
int KonwersjaADC()
{
 //Rozpoczecie konwersji
 ADC_SoftwareStartConv(ADC1);
 //Przetwarzanie
 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); 
 //Zwrócenie przetworzonych danych
 return ADC_GetConversionValue(ADC1);       
}