[MM32硬件] 【灵动微电子MM32F0121测评】7、ADC采样实验

[复制链接]
 楼主| sujingliang 发表于 2025-6-15 21:17 | 显示全部楼层 |阅读模式
本帖最后由 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

7.png
示例中缺省采集通道ADC1_VIN[3],对应管脚PA3,可以通过调节电位器改变PB3的ADC输入电压。
为实现多通道采集,将增加采集通道ADC1_VIN[10],对应管脚PB3。
另外再增加参考电压采集通道。
因此将实现对3个通道的采集。

1、ADC初始化配置

  1. void ADC_Configure(void)
  2. {
  3.     ADC_InitTypeDef  ADC_InitStruct;
  4.     DMA_InitTypeDef  DMA_InitStruct;
  5.     GPIO_InitTypeDef GPIO_InitStruct;
  6.     NVIC_InitTypeDef NVIC_InitStruct;

  7.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC, ENABLE);

  8.     ADC_StructInit(&ADC_InitStruct);
  9.     ADC_InitStruct.ADC_Resolution       = ADC_Resolution_12b;
  10.     ADC_InitStruct.ADC_Prescaler        = ADC_Prescaler_16;
  11.     ADC_InitStruct.ADC_Mode             = ADC_Mode_Continue;
  12.     ADC_InitStruct.ADC_DataAlign        = ADC_DataAlign_Right;
  13.     ADC_Init(ADC1, &ADC_InitStruct);

  14.     ADC_DMACmd(ADC1, ENABLE);

  15.     ADC_SampleTimeConfig(ADC1, ADC_Channel_3, ADC_SampleTime_240_5);
  16.                 ADC_SampleTimeConfig(ADC1, ADC_Channel_10, ADC_SampleTime_240_5);
  17.                 ADC_SampleTimeConfig(ADC1, ADC_Channel_VoltReference, ADC_SampleTime_240_5);
  18.         
  19.     ADC_AnyChannelNumCfg(ADC1, 2);
  20.     ADC_AnyChannelSelect(ADC1, ADC_AnyChannel_0, ADC_Channel_3);
  21.                 ADC_AnyChannelSelect(ADC1, ADC_AnyChannel_1, ADC_Channel_10);
  22.                 ADC_AnyChannelSelect(ADC1, ADC_AnyChannel_2, ADC_Channel_VoltReference);
  23.     ADC_AnyChannelCmd(ADC1, ENABLE);

  24.     RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
  25.                 RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB, ENABLE);
  26.    
  27.                 //ADC1_VIN[3]
  28.                 GPIO_StructInit(&GPIO_InitStruct);
  29.     GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_3;
  30.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
  31.     GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AIN;
  32.     GPIO_Init(GPIOA, &GPIO_InitStruct);

  33.                 //ADC1_VIN[10]
  34.                 GPIO_StructInit(&GPIO_InitStruct);
  35.     GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_3;
  36.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
  37.     GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AIN;
  38.     GPIO_Init(GPIOB, &GPIO_InitStruct);
  39.                
  40.     ADC_Cmd(ADC1, ENABLE);

  41.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE);

  42.     DMA_DeInit(DMA_Channel1);

  43.     DMA_StructInit(&DMA_InitStruct);
  44.     DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->ADDATA);
  45.     DMA_InitStruct.DMA_MemoryBaseAddr     = (uint32_t)ADC_Buffer;
  46.     DMA_InitStruct.DMA_DIR                = DMA_DIR_PeripheralSRC;
  47.     DMA_InitStruct.DMA_BufferSize         = 30;
  48.     DMA_InitStruct.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
  49.     DMA_InitStruct.DMA_MemoryInc          = DMA_MemoryInc_Enable;
  50.     DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  51.     DMA_InitStruct.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
  52.     DMA_InitStruct.DMA_Mode               = DMA_Mode_Circular;
  53.     DMA_InitStruct.DMA_Priority           = DMA_Priority_High;
  54.     DMA_InitStruct.DMA_M2M                = DMA_M2M_Disable;
  55.     DMA_InitStruct.DMA_Auto_Reload        = DMA_Auto_Reload_Disable;
  56.     DMA_Init(DMA_Channel1, &DMA_InitStruct);

  57.     DMA_ClearFlag(DMA_FLAG_TC1);
  58.     DMA_ITConfig(DMA_Channel1, DMA_IT_TC, ENABLE);

  59.     NVIC_InitStruct.NVIC_IRQChannel = DMA_Channel1_IRQn;
  60.     NVIC_InitStruct.NVIC_IRQChannelPriority = 0x01;
  61.     NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  62.     NVIC_Init(&NVIC_InitStruct);

  63.     DMA_Cmd(DMA_Channel1, ENABLE);
  64. }

其中,

   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、中断处理
  1. void DMA_Channel1_IRQHandler(void)
  2. {
  3.     if (RESET != DMA_GetITStatus(DMA_IT_TC1))
  4.     {
  5.         ADC_DMA_InterruptFlag = 1;

  6.         DMA_ClearITPendingBit(DMA_IT_TC1);
  7.     }
  8. }
在采集中断发生后,修改采集标识。

3、实验程序

  1. void ADC_AnyChannel_ContinuousScan_DMA_Interrupt_Sample(void)
  2. {
  3.     uint8_t  i   = 0;
  4.     uint32_t Sum1 = 0;
  5.                 uint32_t Sum2 = 0;
  6.                 uint32_t Sum3 = 0;
  7.                 char buf[16]={0};
  8.                
  9.     float    Voltage1,Voltage2, Voltage3;

  10.     printf("\r\nTest %s", __FUNCTION__);

  11.                 SPI_Configure();
  12.                 ili9341_Init();
  13.                 GUI_Clear(COLOR_Blue);
  14.                 GUI_Write16CnChar(10,16,"灵动微F0121开发板",COLOR_White,COLOR_Blue);
  15.                 GUI_WriteASCII8x16(10,40,"Hello 21ic",COLOR_White,COLOR_Blue);
  16.                 GUI_WriteASCII8x16(10,56,"Hello MM32F0121",COLOR_White,COLOR_Blue);
  17.         
  18.                
  19.                 Gui_DrawRect(0,80,240,50,COLOR_Red);
  20.                 Gui_DrawRect(0,130,240,50,COLOR_Green);
  21.                 Gui_DrawRect(0,180,240,50,COLOR_Purple);
  22.                 Gui_DrawRect(0,230,240,90,COLOR_Black);
  23.     ADC_Configure();

  24.     ADC_SoftwareStartConvCmd(ADC1, ENABLE);

  25.     while (1)
  26.     {
  27.         if (0 != ADC_DMA_InterruptFlag)
  28.         {
  29.             ADC_DMA_InterruptFlag = 0;

  30.             Sum1 = 0;
  31.                                                 Sum2 = 0;
  32.                                                 Sum3 = 0;
  33.             for (i = 0; i < 30; i++)
  34.             {
  35.                                                         if(i%3==0){
  36.                                                                 Sum1 += ADC_Buffer[i];
  37.                                                         }else if(i%3==1){
  38.                                                                 Sum2 += ADC_Buffer[i];
  39.                                                         }else{
  40.                                                                 Sum3 += ADC_Buffer[i];
  41.                                                         }
  42.             }

  43.             Voltage1 = (float)Sum1 / (float)10.0 * (float)3.3 / (float)4096.0;
  44.                                                 Voltage2 = (float)Sum2 / (float)10.0 * (float)3.3 / (float)4096.0;
  45.                                                 Voltage3 = (float)Sum3 / (float)10.0 * (float)3.3 / (float)4096.0;
  46.                                                 
  47.             printf("\r\nPOT Voltage1 = %0.2f,Voltage2 = %0.2f,refVoltage = %0.2f", Voltage1,Voltage2,Voltage3);
  48.                                                 sprintf(buf,"%0.2f",Voltage1);
  49.                                                 GUI_Write16CnChar(10,100,"Vol1:",COLOR_White,COLOR_Red);
  50.                                                 GUI_WriteASCII_BIG(60,80,buf,COLOR_White,COLOR_Red);
  51.                                                 GUI_Write16CnChar(170,100,"V",COLOR_White,COLOR_Red);
  52.                                                 sprintf(buf,"%0.2f",Voltage2);
  53.                                                 GUI_Write16CnChar(10,150,"Vol2:",COLOR_White,COLOR_Green);
  54.                                                 GUI_WriteASCII_BIG(60,130,buf,COLOR_White,COLOR_Green);
  55.                                                 GUI_Write16CnChar(170,150,"V",COLOR_White,COLOR_Green);
  56.                                                 sprintf(buf,"%0.2f",Voltage3);
  57.                                                 GUI_Write16CnChar(10,200,"Ref:",COLOR_White,COLOR_Purple);
  58.                                                 GUI_WriteASCII_BIG(60,180,buf,COLOR_White,COLOR_Purple);
  59.                                                 GUI_Write16CnChar(170,200,"V",COLOR_White,COLOR_Purple);
  60.                                                 
  61.         }
  62.     }
  63. }
DMA搬运的数据中,按顺序分别为vol1(PA3),vol2(PB3),ref。
每个通道取10次数据平均做为结果。

2.jpg

tutieshi_640x357_5s (3).gif



AdaMaYun 发表于 2025-7-31 17:58 | 显示全部楼层
ADC采样实验
您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

146

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部

84

主题

146

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部