本帖最后由 sujingliang 于 2025-6-15 21:18 编辑
本文目的:实现ADC采集将结果通过LCD显示,在ADC采集时采用多通道采集方式
参考例程:
LibSamples_MM32F0120_V1.13.4\Samples\LibSamples\ADC\ADC_AnyChannel_ContinuousScan_DMA_Interrupt
LibSamples_MM32F0120_V1.13.4\Samples\LibSamples\ADC\ADC_InternalVoltageSensor
示例中缺省采集通道ADC1_VIN[3],对应管脚PA3,可以通过调节电位器改变PB3的ADC输入电压。
为实现多通道采集,将增加采集通道ADC1_VIN[10],对应管脚PB3。
另外再增加参考电压采集通道。
因此将实现对3个通道的采集。
1、ADC初始化配置
void ADC_Configure(void)
{
ADC_InitTypeDef ADC_InitStruct;
DMA_InitTypeDef DMA_InitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC, ENABLE);
ADC_StructInit(&ADC_InitStruct);
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStruct.ADC_Prescaler = ADC_Prescaler_16;
ADC_InitStruct.ADC_Mode = ADC_Mode_Continue;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_Init(ADC1, &ADC_InitStruct);
ADC_DMACmd(ADC1, ENABLE);
ADC_SampleTimeConfig(ADC1, ADC_Channel_3, ADC_SampleTime_240_5);
ADC_SampleTimeConfig(ADC1, ADC_Channel_10, ADC_SampleTime_240_5);
ADC_SampleTimeConfig(ADC1, ADC_Channel_VoltReference, ADC_SampleTime_240_5);
ADC_AnyChannelNumCfg(ADC1, 2);
ADC_AnyChannelSelect(ADC1, ADC_AnyChannel_0, ADC_Channel_3);
ADC_AnyChannelSelect(ADC1, ADC_AnyChannel_1, ADC_Channel_10);
ADC_AnyChannelSelect(ADC1, ADC_AnyChannel_2, ADC_Channel_VoltReference);
ADC_AnyChannelCmd(ADC1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB, ENABLE);
//ADC1_VIN[3]
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//ADC1_VIN[10]
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStruct);
ADC_Cmd(ADC1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);
DMA_DeInit(DMA_Channel1);
DMA_StructInit(&DMA_InitStruct);
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->ADDATA);
DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)ADC_Buffer;
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStruct.DMA_BufferSize = 30;
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
DMA_InitStruct.DMA_Auto_Reload = DMA_Auto_Reload_Disable;
DMA_Init(DMA_Channel1, &DMA_InitStruct);
DMA_ClearFlag(DMA_FLAG_TC1);
DMA_ITConfig(DMA_Channel1, DMA_IT_TC, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = DMA_Channel1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority = 0x01;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
DMA_Cmd(DMA_Channel1, ENABLE);
}
其中,
ADC_SampleTimeConfig(ADC1, ADC_Channel_3, ADC_SampleTime_240_5);
ADC_SampleTimeConfig(ADC1, ADC_Channel_10, ADC_SampleTime_240_5);
ADC_SampleTimeConfig(ADC1, ADC_Channel_VoltReference, ADC_SampleTime_240_5);
ADC_AnyChannelNumCfg(ADC1, 2);//3个通道
ADC_AnyChannelSelect(ADC1, ADC_AnyChannel_0, ADC_Channel_3); //通道3
ADC_AnyChannelSelect(ADC1, ADC_AnyChannel_1, ADC_Channel_10); //通道10
ADC_AnyChannelSelect(ADC1, ADC_AnyChannel_2, ADC_Channel_VoltReference);//参考电压通道
ADC_AnyChannelCmd(ADC1, ENABLE);
数据采集采用DMA搬运,结果保存在:
uint16_t ADC_Buffer[30];
2、中断处理
void DMA_Channel1_IRQHandler(void)
{
if (RESET != DMA_GetITStatus(DMA_IT_TC1))
{
ADC_DMA_InterruptFlag = 1;
DMA_ClearITPendingBit(DMA_IT_TC1);
}
}
在采集中断发生后,修改采集标识。
3、实验程序
void ADC_AnyChannel_ContinuousScan_DMA_Interrupt_Sample(void)
{
uint8_t i = 0;
uint32_t Sum1 = 0;
uint32_t Sum2 = 0;
uint32_t Sum3 = 0;
char buf[16]={0};
float Voltage1,Voltage2, Voltage3;
printf("\r\nTest %s", __FUNCTION__);
SPI_Configure();
ili9341_Init();
GUI_Clear(COLOR_Blue);
GUI_Write16CnChar(10,16,"灵动微F0121开发板",COLOR_White,COLOR_Blue);
GUI_WriteASCII8x16(10,40,"Hello 21ic",COLOR_White,COLOR_Blue);
GUI_WriteASCII8x16(10,56,"Hello MM32F0121",COLOR_White,COLOR_Blue);
Gui_DrawRect(0,80,240,50,COLOR_Red);
Gui_DrawRect(0,130,240,50,COLOR_Green);
Gui_DrawRect(0,180,240,50,COLOR_Purple);
Gui_DrawRect(0,230,240,90,COLOR_Black);
ADC_Configure();
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while (1)
{
if (0 != ADC_DMA_InterruptFlag)
{
ADC_DMA_InterruptFlag = 0;
Sum1 = 0;
Sum2 = 0;
Sum3 = 0;
for (i = 0; i < 30; i++)
{
if(i%3==0){
Sum1 += ADC_Buffer[i];
}else if(i%3==1){
Sum2 += ADC_Buffer[i];
}else{
Sum3 += ADC_Buffer[i];
}
}
Voltage1 = (float)Sum1 / (float)10.0 * (float)3.3 / (float)4096.0;
Voltage2 = (float)Sum2 / (float)10.0 * (float)3.3 / (float)4096.0;
Voltage3 = (float)Sum3 / (float)10.0 * (float)3.3 / (float)4096.0;
printf("\r\nPOT Voltage1 = %0.2f,Voltage2 = %0.2f,refVoltage = %0.2f", Voltage1,Voltage2,Voltage3);
sprintf(buf,"%0.2f",Voltage1);
GUI_Write16CnChar(10,100,"Vol1:",COLOR_White,COLOR_Red);
GUI_WriteASCII_BIG(60,80,buf,COLOR_White,COLOR_Red);
GUI_Write16CnChar(170,100,"V",COLOR_White,COLOR_Red);
sprintf(buf,"%0.2f",Voltage2);
GUI_Write16CnChar(10,150,"Vol2:",COLOR_White,COLOR_Green);
GUI_WriteASCII_BIG(60,130,buf,COLOR_White,COLOR_Green);
GUI_Write16CnChar(170,150,"V",COLOR_White,COLOR_Green);
sprintf(buf,"%0.2f",Voltage3);
GUI_Write16CnChar(10,200,"Ref:",COLOR_White,COLOR_Purple);
GUI_WriteASCII_BIG(60,180,buf,COLOR_White,COLOR_Purple);
GUI_Write16CnChar(170,200,"V",COLOR_White,COLOR_Purple);
}
}
}
DMA搬运的数据中,按顺序分别为vol1(PA3),vol2(PB3),ref。
每个通道取10次数据平均做为结果。
|
|