STM32 ADC轉換
阿新 • • 發佈:2018-12-20
簡介
STM32的ADC是12位逐次逼近型的模擬數字轉換器,ADC模組讀到的資料是12位的資料,是從0到4095(111111111111)的值,當把ADC引腳接了GND,讀到的就是0,當把ADC引腳接了VDD,讀到的就是4095。STM32最多支援18個通道,可最多測量16個外部和2個內部訊號源,ADC的各通道可以單次,連續,掃描或者間斷模式執行。
ADC相關結構體和庫函式
typedef struct { uint32_t ADC_Mode;//ADC模式:配置ADC_CR1暫存器的位[19:16] :DUALMODE[3:0]位 FunctionalState ADC_ScanConvMode; //是否使用掃描模式。ADC_CR1位8:SCAN位 FunctionalState ADC_ContinuousConvMode; //單次轉換OR連續轉換:ADC_CR2的位1:CONT uint32_t ADC_ExternalTrigConv; //觸發方式:ADC_CR2的位[19:17] :EXTSEL[2:0] uint32_t ADC_DataAlign; //對齊方式:左對齊還是右對齊:ADC_CR2的位11:ALIGN uint8_t ADC_NbrOfChannel;//規則通道序列長度:ADC_SQR1的位[23:20]: L[3:0] }ADC_InitTypeDef; //初始化,配置ADC模式、單次連續掃描模式、外部觸發方式、對齊方式、規則序列長度 void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) { ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//獨立模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE;//不開啟掃描 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//單次轉換模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//觸發軟體 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//ADC資料右對齊 ADC_InitStructure.ADC_NbrOfChannel = 1;//順序進行規則轉換的ADC通道的數目 ADC_Init(ADC1, &ADC_InitStructure); } void ADC_DeInit(ADC_TypeDef* ADCx);//恢復預設值 void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);//使能ADC //使能或者失能指定的ADC的中斷 void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState); //ADC使能軟體轉換 void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState); //設定ADC的規則組通道、轉化順序和取樣時間,其中ADC_Channel指定了通過本函式來設定的ADC通道, 可以是0~17,ADC_SampleTime設定了選中通道的ADC取樣時間 void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime); //獲取最近一次ADCx規則組的轉換結果 uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx); void ADC_ResetCalibration(ADC_TypeDef* ADCx);//重置指定的ADC的校準暫存器 //獲取ADC重置校準暫存器的狀態 FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx); void ADC_StartCalibration(ADC_TypeDef* ADCx);//開始指定ADC的校準 FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);//獲取ADC的校準狀態
ADC配置的一般步驟:
1、開啟PA口時鐘和ADC1時鐘,設定PA1為模擬輸入。呼叫函式:GPIO_Init();APB2PeriphClockCmd();
2、復位ADC1,同時設定ADC1分頻因子。呼叫函式:ADC_DeInit(ADC1);RCC_ADCCLKConfig(RCC_PCLK2_Div6);
3、初始化ADC1引數,設定ADC1的工作模式以及規則序列的相關資訊。呼叫函式:void ADC_Init();
4、使能ADC並校準。呼叫函式:ADC_Cmd();
5、配置規則通道引數。呼叫函式:ADC_RegularChannelConfig();
6、開啟軟體轉換:ADC_SoftwareStartConvCmd(ADC1);
7、等待轉換完成,讀取ADC值。呼叫函式:ADC_GetConversionValue(ADC1)。
示例程式碼:
//初始化ADC,這裡我們僅以規則通道為例,我們預設將開啟通道0~3 void Adc_Init(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; //使能ADC1通道時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //設定ADC分頻因子6 72M/6=12,ADC最大時間不能超過14M RCC_ADCCLKConfig(RCC_PCLK2_Div6); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//PA1 作為模擬通道輸入引腳 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//模擬輸入引腳 GPIO_Init(GPIOA, &GPIO_InitStructure); ADC_DeInit(ADC1); //復位ADC1 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC1和ADC2工作在獨立模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模數轉換工作在單通道模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//模數轉換工作在單次轉換模式 //轉換由軟體而不是外部觸發啟動 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC資料右對齊 ADC_InitStructure.ADC_NbrOfChannel = 1; //順序進行規則轉換的ADC通道的數目 ADC_Init(ADC1, &ADC_InitStructure); //根據指定的引數初始化外設ADCx的暫存器 ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1 ADC_ResetCalibration(ADC1); //使能復位校準 while(ADC_GetResetCalibrationStatus(ADC1)); //等待復位校準結束 ADC_StartCalibration(ADC1); //開啟AD校準 while(ADC_GetCalibrationStatus(ADC1)); //等待校準結束 } //獲得ADC值,ch:通道值 0~3 u16 Get_Adc(u8 ch) { //設定指定ADC的規則組通道,一個序列,取樣時間239.5週期 ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的軟體轉換啟動功能 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待轉換結束 return ADC_GetConversionValue(ADC1); //返回最近一次ADC1規則組的轉換結果 }