STM32F1進(jìn)行ADC采樣轉(zhuǎn)換,通過(guò)中斷獲取采樣后的數(shù)據(jù)
該主題比上一主題主要是使用了中斷
1.main.c文件
#include "stm32f10x.h" #include "adc.h" #include "usart1.h" uint16_t adc_val = 0; uint8_t cnt = 0; void delay(void) { uint32_t t = 0; for(t = 0; t < 0xfffef; t ++); } int main(void) { USART1_Init(); ADC1_Init_Config(); //ADC規(guī)則通道配置 ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_239Cycles5); //RANK:數(shù)值越小,越先轉(zhuǎn)換;這里通道2,第一個(gè)進(jìn)行AD轉(zhuǎn)換;要是有多個(gè)通道的話,設(shè)定先后順序 // ADC采樣周期計(jì)算公式 = ADC_SampleTime_xxxCycles5 + 12.5個(gè)周期,這里是256個(gè)周期,頻率設(shè)置成了12MHz,所以采樣時(shí)間 = 256/12MHz = 21.3us,采樣時(shí)間長(zhǎng),采樣會(huì)準(zhǔn)確些 //ADC采樣前先進(jìn)行校準(zhǔn)動(dòng)作 ADC_ResetCalibration(ADC1);//復(fù)位校準(zhǔn) while(ADC_GetResetCalibrationStatus(ADC1) != RESET); //平時(shí)是1,復(fù)位完成變成0 ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1) != RESET);//平時(shí)是1,校準(zhǔn)完成變成0 while(1) { ADC_SoftwareStartConvCmd(ADC1, ENABLE); //軟件啟動(dòng)AD轉(zhuǎn)換功能 // while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //平時(shí)是0,轉(zhuǎn)換完成變成1 ;這次使用的中斷,轉(zhuǎn)換完成會(huì)進(jìn)入中斷,讀取數(shù)據(jù)。用的ADC_GetITStatus函數(shù) printf("AD-VALUE:%d--- %.3f\r\n", cnt,(float)adc_val/4096.0*3.3);//這里注意需要除以4096.0,如果寫成了整數(shù),打印輸出就會(huì)變成0.0了 delay(); } }
和前篇的差異標(biāo)紅處理展示;
2.adc.c文件
#include "adc.h" void ADC1_Init_Config(void) { ADC_InitTypeDef ADC_InitStruct; //1.配置ADC的GPIO引腳 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//輸入功能不用設(shè)置輸出速度參數(shù) GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; //2.配置時(shí)鐘,GPIOA時(shí)鐘和ADC1外設(shè)時(shí)鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1, ENABLE); //PA2 ADC_IN2 GPIO_Init(GPIOA, &GPIO_InitStruct); //3.配置ADC模式相關(guān)參數(shù) ADC_InitStruct.ADC_ContinuousConvMode = DISABLE; //設(shè)置成連續(xù)轉(zhuǎn)換模式(ENABLE)或者單次轉(zhuǎn)換模式(DISABLE) ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//數(shù)據(jù)右對(duì)齊,12位的數(shù)據(jù),右對(duì)齊不用處理高位,高位就是0 ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //若是選擇外部觸發(fā)轉(zhuǎn)換,選擇對(duì)應(yīng)的觸發(fā)條件,否則設(shè)置為不使用外部觸發(fā) ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//多種模式組合,選擇一種 ADC_InitStruct.ADC_NbrOfChannel = 1;//需要轉(zhuǎn)換的通道數(shù),這里只有1個(gè)通道要轉(zhuǎn)換 ADC_InitStruct.ADC_ScanConvMode = DISABLE;//多通道掃描轉(zhuǎn)換(ENABLE),或者是單通道轉(zhuǎn)換(DISABLE),這里選擇單通道轉(zhuǎn)換 //4.配置ADC時(shí)鐘不能超過(guò)14MHz 系統(tǒng)時(shí)鐘72MHz進(jìn)行6分頻,12MHz RCC_ADCCLKConfig(RCC_PCLK2_Div6); //5.ADC1初始化 ADC_Init(ADC1, &ADC_InitStruct); //6.ADC中斷使能 ,看到中斷,要想到NVIC配置 ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE); //7.進(jìn)行中斷相關(guān)設(shè)置 ADC_NVIC_Config(); //8.ADC1功能使能 ADC_Cmd(ADC1, ENABLE); }
3.新增加了nvic.c文件
#include "nvic.h" void ADC_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStruct; NVIC_InitStruct.NVIC_IRQChannel = ADC1_2_IRQn; //ADC中斷功能 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; //搶占優(yōu)先級(jí) NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; //響應(yīng)優(yōu)先級(jí) NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //中斷組配置 NVIC_Init(&NVIC_InitStruct); }
4.中斷函數(shù)返回ADC采樣數(shù)據(jù)
void ADC1_2_IRQHandler(void) { if(ADC_GetITStatus(ADC1, ADC_IT_EOC)) //如果,ADC1轉(zhuǎn)換結(jié)束,則讀取數(shù)據(jù) { adc_val = ADC_GetConversionValue(ADC1); if(cnt < 200)cnt ++; } ADC_ClearITPendingBit(ADC1, ADC_IT_EOC); //讀取完后,清除標(biāo)志位 }
雖然設(shè)置的是單次轉(zhuǎn)換【ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;】,但是因?yàn)樵谥骱瘮?shù),主循環(huán)中,一段時(shí)間進(jìn)行一次軟件啟動(dòng)AD轉(zhuǎn)換,所以AD一直出來(lái)新的采樣值。

浙公網(wǎng)安備 33010602011771號(hào)