MM32F3270系列的ADC支持注入通道功能,每個ADC模塊具有4個注入通道。每個注入通道具有獨立的數(shù)據(jù)寄存器,注入通道具有比規(guī)則通道更高的優(yōu)先級。
規(guī)則通道是按照指定的通道順序進行轉換。注入通道是指在規(guī)則通道轉換過程中,如果突然需要進行其他某個通道的采樣,則會在規(guī)則通道該次轉換完成后停止轉換,進行注入通道轉換直到轉換結束,再繼續(xù)規(guī)則通道轉換。
在一些特定場合使用ADC時可能會遇到很多情況,不僅僅簡單的按規(guī)則通道來采樣,有時候需要立刻采樣,這就要用到注入通道。
注入通道模式介紹
注入通道工作模式分為自動注入和事件注入兩種模式:
a) 自動注入:任意通道工作完成后自動開始注入通道工作;
b) 事件注入:注入事件到來, A/D轉換完成當前轉換后開始注入通道轉換,完成注入通道轉換后繼續(xù)執(zhí)行任意通道轉換。
自動注入轉換模式
任意通道配置通道轉換完成后,自動開始注入通道轉換。如果任意通道是連續(xù)掃描模式,需要清除ADST才能停止轉換。配置自動注入轉換模式應禁止注入事件發(fā)生。
自動注入模式-通道轉換時序圖
事件注入工作模式
注入事件下禁止自動注入模式。注入事件發(fā)生后(包括軟件和觸發(fā)),如果當前轉換正在進行,則完成當前轉換后開始注入通道轉換。
任意通道轉換時注入事件轉換通道時序圖
在注入通道轉換期間有任意通道事件產生,注入轉換不會結束,但會保存任意通道事件。完成本次轉換序列后,開始任意通道事件的轉換。
注入通道轉換時任意事件轉換通道發(fā)生時序圖
使用觸發(fā)開始注入通道轉換,必須保證觸發(fā)事件的間隔長與注入序列,注入通道轉換期間發(fā)生注入事件將被忽略。
觸發(fā)信號
ADC轉換的觸發(fā)源包括軟件觸發(fā)、定時器和外部事件。
在觸發(fā)信號產生后,延時N個PCLK2的時鐘周期再開始采樣。如果是觸發(fā)掃描模式,只有第一個通道采樣被延時,其余通道是在上一個采樣結束后立即開始。
設置ADC_ANY_CR寄存器的JTRGEN位可以使用外部事件觸發(fā)注入通道轉換。設置ADC_ANY_CR寄存器的JTRGSEL位可以選擇注入通道外部觸發(fā)源。
具體的外部觸發(fā)源選擇情況,可以參考AD控制寄存器(ADC_ADCR.TRGSEL 或ADC_ANY_CR.JTRGSEL)相關位的描述。外部觸發(fā)可設置延時控制,具體參考AD控制寄存器(ADC_ADCR.TRGSHIFT 或 ADC_ANY_CR.J TRGSHIFT)相關位的描述。
實驗
本次實驗使用ADC的注入通道:將ADC1的通道0配置為規(guī)則通道模式,通過軟件觸發(fā),并使用DMA傳輸數(shù)據(jù)。將ADC1的通道1配置為注入通道模式,通過外部事件觸發(fā),并使用中斷,在中斷服務子程序中,就可以獲取AD值。
開始只有ADC1的通道0進行AD轉換,通道1不進行AD轉換。當外部事件發(fā)生后,通道0當前轉換結束后停止,通道1開始進行轉換直至結束,通道0繼續(xù)進行AD轉換,經MCU處理將電壓數(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復用為外部中斷/事件線。
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中斷服務函數(shù)
外部事件觸發(fā)ADC注入通道采樣,轉換完成便會觸發(fā)ADC中斷,在中斷服務子程序中獲取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中斷服務函數(shù)
規(guī)則通道使用DMA中斷進行數(shù)據(jù)傳輸,在DMA中斷服務函數(shù)中調用ADCFilter()函數(shù)對獲取的AD值做濾波處理。
void DMA1_Channel1_IRQHandler(void) { if(DMA_GetITStatus(DMA1_IT_TC1)) { DMA_ClearITPendingBit(DMA1_IT_TC1); ADCFilter(); } }
主函數(shù)
示例中將獲取的AD值與3.3V比對,轉換為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。
運行程序,開始時只有ADC1通道0(規(guī)則通道)進行AD轉換。給PB12一個下降沿信號,此時外部事件觸發(fā)ADC1通道1(注入通道)進行AD轉換,通道0當前轉換完成后停止AD轉換,通道1進行轉換直到結束,通道0進行AD轉換。串口調試助手顯示如下:
各通道輸出數(shù)據(jù)和采樣電壓一致,與預期相符。在一些ADC應用場合中,通常將注入通道和規(guī)則通道混合使用,在規(guī)則通道轉換的過程中立刻進行注入通道采樣,充分發(fā)揮ADC外設的特性。
來源:靈動MM32MCU
審核編輯:湯梓紅
-
mcu
+關注
關注
146文章
16665瀏覽量
347743 -
adc
+關注
關注
97文章
6296瀏覽量
542410 -
時序圖
+關注
關注
2文章
57瀏覽量
22407
發(fā)布評論請先 登錄
相關推薦
評論