STM32f103的數(shù)電采集電路的ADC多通道采集程序
STM32擁有1~3個(gè)ADC(STM32F101/102系列只有1個(gè)ADC),這些ADC可以獨(dú)立使用,也可以使用雙重模式(提高采樣率)。STM32的ADC是12位逐次逼近型的模擬數(shù)字轉(zhuǎn)換器。它有18個(gè)通道,可測(cè)量16個(gè)外部和2個(gè)內(nèi)部信號(hào)源。各通道的A/D轉(zhuǎn)換可以單次、連續(xù)、掃描或間斷模式執(zhí)行。ADC的結(jié)果可以左對(duì)齊或右對(duì)齊方式存儲(chǔ)在16位數(shù)據(jù)寄存器中。
ADC模數(shù)轉(zhuǎn)換設(shè)置的一般步驟可以總結(jié)為如下幾個(gè)步驟:
1.ADC時(shí)鐘使能,GPIO時(shí)鐘使能
2.ADC復(fù)位
3.ADC端口模式設(shè)置
4.ADC參數(shù)初始化
5.開啟中斷并且初始化NVIC(如果需要開啟中斷才需要這個(gè)步驟)
6.使能ADC
7.編寫中斷處理函數(shù)
前端采集模塊采用的單個(gè)ADC的多通道連續(xù)采樣的工作模式。主要用于ECG心電信號(hào)的電壓大小獲取,并將獲取值經(jīng)行存儲(chǔ)處理。經(jīng)過考慮片上資源的分配優(yōu)化和IO口設(shè)計(jì),采用多通道同時(shí)采樣可以視為滑動(dòng)平均濾波器,可以平滑信號(hào),達(dá)到去除噪聲的效果,另一方面要保證IO口的數(shù)量和工作間隔時(shí)間,最終設(shè)計(jì)為4通道連續(xù)采樣。前端采集模塊采用了ADC1的通道4、5、6、7,并占用PA4、5、6、7的I/O口作為AD輸入端,并采用DMA傳輸方式進(jìn)行(詳情請(qǐng)轉(zhuǎn)至3.1.4)。這樣的設(shè)計(jì)保證了ADC轉(zhuǎn)換的時(shí)間不受主線程的干擾,同時(shí)保證了數(shù)據(jù)間隔時(shí)間是不變的,從而可以保證了從下至上的時(shí)序是不變的,最大的好處是保證了ADC的轉(zhuǎn)換時(shí)間大大減少。
ADC多通道+DMA配置函數(shù)
//初始化ADC1
//這里采用多通道連續(xù)采樣,并用DMA1的通道傳送
//我們默認(rèn)將開啟通道10~13
//相應(yīng)管腳PC0~3
voidAdc_Multi_Init(void)
{
ADC_InitTypeDefADC_InitStructure;
GPIO_InitTypeDefGPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);//使能ADC1通道時(shí)鐘
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//設(shè)置ADC分頻因子672M/6=12,ADC最大時(shí)間不能超過14M
//PA1作為模擬通道輸入引腳
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模擬輸入引腳
GPIO_Init(GPIOA,&GPIO_InitStructure);
ADC_DeInit(ADC1);//復(fù)位ADC1,將外設(shè)ADC1的全部寄存器重設(shè)為缺省值
ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC工作模式:ADC1和ADC2工作在獨(dú)立模式
ADC_InitStructure.ADC_ScanConvMode=ENABLE;//模數(shù)轉(zhuǎn)換工作在掃描模式
ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//模數(shù)轉(zhuǎn)換工作在連續(xù)轉(zhuǎn)換模式
ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//轉(zhuǎn)換由軟件而不是外部觸發(fā)啟動(dòng)
ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//ADC數(shù)據(jù)右對(duì)齊
ADC_InitStructure.ADC_NbrOfChannel=4;//順序進(jìn)行規(guī)則轉(zhuǎn)換的ADC通道的數(shù)目
ADC_Init(ADC1,&ADC_InitStructure);//根據(jù)ADC_InitStruct中指定的參數(shù)初始化外設(shè)ADCx的寄存器
ADC_RegularChannelConfig(ADC1,ADC_Channel_4,1,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_5,2,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_6,3,ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_7,4,ADC_SampleTime_239Cycles5);
//開啟ADC的DMA支持(要實(shí)現(xiàn)DMA功能,還需獨(dú)立配置DMA通道等參數(shù))
ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1,ENABLE);//使能指定的ADC1
ADC_ResetCalibration(ADC1);//使能復(fù)位校準(zhǔn)
while(ADC_GetResetCalibrationStatus(ADC1));//等待復(fù)位校準(zhǔn)結(jié)束
ADC_StartCalibration(ADC1);//開啟AD校準(zhǔn)
while(ADC_GetCalibrationStatus(ADC1));//等待校準(zhǔn)結(jié)束
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能指定的ADC1的軟件轉(zhuǎn)換啟動(dòng)功能
}
//單次獲得ADC值
//ch:通道值0~3
u16Get_Adc(u8ch)
{
u16tempADC=0;
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//等待轉(zhuǎn)換結(jié)束
tempADC=ADC_GetConversionValue(ADC1);
//設(shè)置指定ADC的規(guī)則組通道,一個(gè)序列,采樣時(shí)間
ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5);//ADC1,ADC通道,采樣時(shí)間為239.5周期
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能指定的ADC1的軟件轉(zhuǎn)換啟動(dòng)功能
returntempADC;//返回最近一次ADC1規(guī)則組的轉(zhuǎn)換結(jié)果
}