HAL库配置ADC_2_多通道


一、轮询模式多通道采集

💦CubeMX配置如下,注意
在这里插入图片描述
注意:转换要填写第一个序列,否则转换的数据不准确

  while (1)
  {
      adc_temp1=Get_Adc_Average(ADC_CHANNEL_0,20,1);     
      voltage_temp1=(float)adc_temp1*(3.3/4096);     
      adc_temp2=Get_Adc_Average(ADC_CHANNEL_1,20,1);//rank不管那个通道,都要填序列1     
      voltage_temp2=(float)adc_temp2*(3.3/4096);
      printf("V:%f,%f\n",voltage_temp1,voltage_temp2);
      HAL_Delay(1);
  }
}

uint16_t Get_Adc(uint32_t ch,uint8_t rank)   
{
    ADC_ChannelConfTypeDef ADC1_ChanConf;    
    ADC1_ChanConf.Channel=ch;                                   //通道
    ADC1_ChanConf.Rank=rank;                                       //第1个序列,序列1
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;        //采样时间
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&hadc1,&ADC1_ChanConf);        //通道配置	
    HAL_ADC_Start(&hadc1);                               //开启ADC	
    HAL_ADC_PollForConversion(&hadc1,10);                //轮询转换 
	return (uint16_t)HAL_ADC_GetValue(&hadc1);	        //返回最近一次ADC1规则组的转换结果
}
//获取指定通道的转换值,取times次,然后平均 
//times:获取次数
//返回值:通道ch的times次转换结果平均值
uint16_t Get_Adc_Average(uint32_t ch,uint8_t times,uint8_t rank)
{
	uint32_t temp_val=0;
	uint8_t t;
	for(t=0;t<times;t++)
	{
		temp_val+=Get_Adc(ch,rank);
		//HAL_Delay(5);
	}
	return temp_val/times;
}

测试发现,扫描,连续,间接模式,开启和关闭对转换结果没有影响。

二、DMA多通道采集

1.CubeMX软件配置

在这里插入图片描述

💦将扫描模式打开,多通道,必须开启扫描模式
💦将连续转换打开,DMA使能。

2.代码示例_F407

代码如下(示例):

  uint16_t adc_dma_temp[2]={0};
  uint8_t adc_dma_cnt=0;
  uint32_t adc_dma_sum1=0,adc_dma_sum2=0;
  float voltage_temp1=0,voltage_temp2=0;
  uint8_t adc_dma_state=0;
  uint16_t data1,data2;
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    if(hadc==&hadc1)
    {        
          adc_dma_sum1+=adc_dma_temp[0];
          adc_dma_sum2+=adc_dma_temp[1];
          adc_dma_cnt++;
          if(adc_dma_cnt>=20)
          {
              data1=(uint16_t)(adc_dma_sum1/adc_dma_cnt);
              data2=(uint16_t)(adc_dma_sum2/adc_dma_cnt);
              voltage_temp1=(float)data1*(3.3/4096);
              voltage_temp2=(float)data2*(3.3/4096);
              printf("V:%f,%f\n",voltage_temp1,voltage_temp2);
              adc_dma_cnt=0;
              adc_dma_sum1=0;
              adc_dma_sum2=0;
  
          }
    }
}

💦因为是连续转换模式,所以在函数初始化时,开启一次转换即可。

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  extern uint16_t adc_dma_temp[2];
  extern  uint16_t data1,data2;
   HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&adc_dma_temp, 2);//开启转换
  while (1)
  {

     for(uint8_t i=20;i>=1;i--)
     {
         data_buff[i]=data_buff[i-1];
     }
     data_buff[0]=data1;
      HAL_Delay(1000);
  }
}

💦结果如下:通道1,采集正弦信号,通道2采集3.3V电压,通道2误差较大,原因未知。
在这里插入图片描述

三补充

💦如果不使用连续转换模式,就需要在while循环中开启转换,转换效率不如连续转换高。
💦DMA的circular模式理解:当转换完成后自动搬运。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值