MM32F3270系列的ADC支持注入通道功能,每個(gè)ADC模塊具有4個(gè)注入通道。每個(gè)注入通道具有獨(dú)立的數(shù)據(jù)寄存器,注入通道具有比規(guī)則通道更高的優(yōu)先級(jí)。
規(guī)則通道是按照指定的通道順序進(jìn)行轉(zhuǎn)換。注入通道是指在規(guī)則通道轉(zhuǎn)換過程中,如果突然需要進(jìn)行其他某個(gè)通道的采樣,則會(huì)在規(guī)則通道該次轉(zhuǎn)換完成后停止轉(zhuǎn)換,進(jìn)行注入通道轉(zhuǎn)換直到轉(zhuǎn)換結(jié)束,再繼續(xù)規(guī)則通道轉(zhuǎn)換。
在一些特定場(chǎng)合使用ADC時(shí)可能會(huì)遇到很多情況,不僅僅簡(jiǎn)單的按規(guī)則通道來采樣,有時(shí)候需要立刻采樣,這就要用到注入通道。
注入通道模式介紹
注入通道工作模式分為自動(dòng)注入和事件注入兩種模式:
a) 自動(dòng)注入:任意通道工作完成后自動(dòng)開始注入通道工作;
b) 事件注入:注入事件到來, A/D轉(zhuǎn)換完成當(dāng)前轉(zhuǎn)換后開始注入通道轉(zhuǎn)換,完成注入通道轉(zhuǎn)換后繼續(xù)執(zhí)行任意通道轉(zhuǎn)換。
自動(dòng)注入轉(zhuǎn)換模式
任意通道配置通道轉(zhuǎn)換完成后,自動(dòng)開始注入通道轉(zhuǎn)換。如果任意通道是連續(xù)掃描模式,需要清除ADST才能停止轉(zhuǎn)換。配置自動(dòng)注入轉(zhuǎn)換模式應(yīng)禁止注入事件發(fā)生。
自動(dòng)注入模式-通道轉(zhuǎn)換時(shí)序圖
事件注入工作模式
注入事件下禁止自動(dòng)注入模式。注入事件發(fā)生后(包括軟件和觸發(fā)),如果當(dāng)前轉(zhuǎn)換正在進(jìn)行,則完成當(dāng)前轉(zhuǎn)換后開始注入通道轉(zhuǎn)換。
任意通道轉(zhuǎn)換時(shí)注入事件轉(zhuǎn)換通道時(shí)序圖
在注入通道轉(zhuǎn)換期間有任意通道事件產(chǎn)生,注入轉(zhuǎn)換不會(huì)結(jié)束,但會(huì)保存任意通道事件。完成本次轉(zhuǎn)換序列后,開始任意通道事件的轉(zhuǎn)換。
注入通道轉(zhuǎn)換時(shí)任意事件轉(zhuǎn)換通道發(fā)生時(shí)序圖
使用觸發(fā)開始注入通道轉(zhuǎn)換,必須保證觸發(fā)事件的間隔長(zhǎng)與注入序列,注入通道轉(zhuǎn)換期間發(fā)生注入事件將被忽略。
觸發(fā)信號(hào)
ADC轉(zhuǎn)換的觸發(fā)源包括軟件觸發(fā)、定時(shí)器和外部事件。
在觸發(fā)信號(hào)產(chǎn)生后,延時(shí)N個(gè)PCLK2的時(shí)鐘周期再開始采樣。如果是觸發(fā)掃描模式,只有第一個(gè)通道采樣被延時(shí),其余通道是在上一個(gè)采樣結(jié)束后立即開始。
設(shè)置ADC_ANY_CR寄存器的JTRGEN位可以使用外部事件觸發(fā)注入通道轉(zhuǎn)換。設(shè)置ADC_ANY_CR寄存器的JTRGSEL位可以選擇注入通道外部觸發(fā)源。
具體的外部觸發(fā)源選擇情況,可以參考AD控制寄存器(ADC_ADCR.TRGSEL 或ADC_ANY_CR.JTRGSEL)相關(guān)位的描述。外部觸發(fā)可設(shè)置延時(shí)控制,具體參考AD控制寄存器(ADC_ADCR.TRGSHIFT 或 ADC_ANY_CR.J TRGSHIFT)相關(guān)位的描述。
實(shí)驗(yàn)
本次實(shí)驗(yàn)使用ADC的注入通道:將ADC1的通道0配置為規(guī)則通道模式,通過軟件觸發(fā),并使用DMA傳輸數(shù)據(jù)。將ADC1的通道1配置為注入通道模式,通過外部事件觸發(fā),并使用中斷,在中斷服務(wù)子程序中,就可以獲取AD值。
開始只有ADC1的通道0進(jìn)行AD轉(zhuǎn)換,通道1不進(jìn)行AD轉(zhuǎn)換。當(dāng)外部事件發(fā)生后,通道0當(dāng)前轉(zhuǎn)換結(jié)束后停止,通道1開始進(jìn)行轉(zhuǎn)換直至結(jié)束,通道0繼續(xù)進(jìn)行AD轉(zhuǎn)換,經(jīng)MCU處理將電壓數(shù)據(jù)打印出來。
程序設(shè)計(jì)
ADC1 配置初始化
void ADC1BasicConfigWithParameter(void) { ADC_InitTypeDef ADC_InitStruct; ADC_TypeDef* ADCn; ADCn = ADC1; ADC_StructInit( ADC_InitStruct); ADCxClockSet(ADCn, ENABLE); ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; ADC_InitStruct.ADC_PRESCARE = ADC_PCLK2_PRESCARE_16; ADC_InitStruct.ADC_Mode = ADC_Mode_Continue; ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; ADC_Init(ADCn, ADC_InitStruct); ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 0, ADC_SMPR1_SAMCTL0_240_5); ADC_InjectedSequencerConfig(ADC1, ADC_ANY_CR_JTRGSEL_EXTI12, ADC_ANY_CR_JTRGSHIFT_64); ADC_InjectedSequencerLengthConfig(ADC1, ADC_Inject_Seqen_Len1); ADC_InjectedSequencerChannelConfig(ADC1, ADC_InjectedChannel_1, ADC_Channel_1); ADC1->ANYCR |= (1<<4); DMAInit(); ADC_DMACmd(ADCn, ENABLE); ADC_Cmd(ADCn, ENABLE); }
外部事件初始化
ADC觸發(fā)源選擇外部事件觸發(fā)方式,配置EXTI_Line12下降沿觸發(fā)外部中斷,通過PB12復(fù)用為外部中斷/事件線。
void EXTIX_Init(void) { EXTI_InitTypeDef EXTI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2ENR_SYSCFG, ENABLE); //Set to pull-up input RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB, ENABLE); GPIO_StructInit( GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, GPIO_InitStructure); //GPIOB.12 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource12); EXTI_StructInit( EXTI_InitStructure); EXTI_InitStructure.EXTI_Line = EXTI_Line12; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event; //Falling edge trigger EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init( EXTI_InitStructure); }
ADC1中斷服務(wù)函數(shù)
外部事件觸發(fā)ADC注入通道采樣,轉(zhuǎn)換完成便會(huì)觸發(fā)ADC中斷,在中斷服務(wù)子程序中獲取AD值。
void ADC1_2_IRQHandler(void) { if(RESET != ADC_SREXT_JEOSIF) { ADC1->SREXT |= (1 << 20); //Clear the bit by writing about 1 ADCVAL = ADC_GetInjectedCurrentConvertedValue(ADC1); Flag_InjectConvert = 1; if(RESET != EXTI_GetFlagStatus(EXTI_Line12)) { EXTI_ClearITPendingBit(EXTI_Line12); } } }
DMA中斷服務(wù)函數(shù)
規(guī)則通道使用DMA中斷進(jìn)行數(shù)據(jù)傳輸,在DMA中斷服務(wù)函數(shù)中調(diào)用ADCFilter()函數(shù)對(duì)獲取的AD值做濾波處理。
void DMA1_Channel1_IRQHandler(void) { if(DMA_GetITStatus(DMA1_IT_TC1)) { DMA_ClearITPendingBit(DMA1_IT_TC1); ADCFilter(); } }
主函數(shù)
示例中將獲取的AD值與3.3V比對(duì),轉(zhuǎn)換為ADC輸入通道的電壓,并間隔300ms打印。
s32 main(void) { DELAY_Init(); CONSOLE_Init(115200); ADC1_ConfigInit(); ADC_SoftwareStartConvCmd(ADC1, ENABLE); while(1) { if(Flag_InjectConvert) { Flag_InjectConvert = 0; fValue = ((float)ADCVAL / 4095) * 3.3; // ADC injection channel printf("ADC1_CH_1 = %fVrnn", fValue); } if(Flag_ADCFilter) { Flag_ADCFilter = 0; //Convert the filtered value to voltage ADCVolatge = ((float)ADCFilterValue / 4095) * 3.3; //ADC regular channels printf("ADC1_CH_0 = %fVrnn", ADCVolatge); ADC_SoftwareStartConvCmd(ADC1, ENABLE); } DELAY_Ms(300); } }
演示
在開發(fā)板上將PA0(ADC1通道0)連接板上GND,將PA1(ADC1通道1)連接板上3.3V。
運(yùn)行程序,開始時(shí)只有ADC1通道0(規(guī)則通道)進(jìn)行AD轉(zhuǎn)換。給PB12一個(gè)下降沿信號(hào),此時(shí)外部事件觸發(fā)ADC1通道1(注入通道)進(jìn)行AD轉(zhuǎn)換,通道0當(dāng)前轉(zhuǎn)換完成后停止AD轉(zhuǎn)換,通道1進(jìn)行轉(zhuǎn)換直到結(jié)束,通道0進(jìn)行AD轉(zhuǎn)換。串口調(diào)試助手顯示如下:
各通道輸出數(shù)據(jù)和采樣電壓一致,與預(yù)期相符。在一些ADC應(yīng)用場(chǎng)合中,通常將注入通道和規(guī)則通道混合使用,在規(guī)則通道轉(zhuǎn)換的過程中立刻進(jìn)行注入通道采樣,充分發(fā)揮ADC外設(shè)的特性。
來源:靈動(dòng)MM32MCU
審核編輯:湯梓紅
-
mcu
+關(guān)注
關(guān)注
146文章
17149瀏覽量
351224 -
adc
+關(guān)注
關(guān)注
98文章
6498瀏覽量
544683 -
時(shí)序圖
+關(guān)注
關(guān)注
2文章
58瀏覽量
22446
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論