原创 STM32 动态改变ADC采样通道

2020-12-25 14:56 6431 34 8 分类: MCU/ 嵌入式 文集: STM32 软件
使用DMA 进行AD采样很方便,但需要事先设置好通道。如果有过程中希望修改通道,可以先做一个DeInit 然后设置不同的Rank

// Adc 通道配置 选择 vdc vbat preu pred
  • void ADC1_misc_Init(void)
  • {
  • ADC_ChannelConfTypeDef sConfig;
  • HAL_ADC_DeInit(&hadc1);
  • /**Common config
  • */
  • hadc1.Instance = ADC1;
  • hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  • hadc1.Init.ContinuousConvMode = ENABLE;
  • hadc1.Init.DiscontinuousConvMode = DISABLE;
  • hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  • hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  • hadc1.Init.NbrOfConversion = 4;
  • if (HAL_ADC_Init(&hadc1) != HAL_OK)
  • {
  • _Error_Handler(__FILE__, __LINE__);
  • }
  • /**Configure Regular Channel
  • */
  • sConfig.Channel = ADC_CHANNEL_12; // bdc
  • sConfig.Rank = ADC_REGULAR_RANK_1;
  • sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  • if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  • {
  • _Error_Handler(__FILE__, __LINE__);
  • }
  • /**Configure Regular Channel
  • */
  • sConfig.Channel = ADC_CHANNEL_13; // vbat
  • sConfig.Rank = ADC_REGULAR_RANK_2;
  • if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  • {
  • _Error_Handler(__FILE__, __LINE__);
  • }
  • /**Configure Regular Channel
  • */
  • sConfig.Channel = ADC_CHANNEL_1; // preu
  • sConfig.Rank = ADC_REGULAR_RANK_3;
  • if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  • {
  • _Error_Handler(__FILE__, __LINE__);
  • }
  • /**Configure Regular Channel
  • */
  • sConfig.Channel = ADC_CHANNEL_7; // pred
  • sConfig.Rank = ADC_REGULAR_RANK_4;
  • if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  • {
  • _Error_Handler(__FILE__, __LINE__);
  • }
  • }
  • // adc1 通道配置 bub pos
  • void ADC1_ir_Init(void)
  • {
  • ADC_ChannelConfTypeDef sConfig;
  • HAL_ADC_DeInit(&hadc1);
  • /**Common config
  • */
  • hadc1.Instance = ADC1;
  • hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  • hadc1.Init.ContinuousConvMode = ENABLE;
  • hadc1.Init.DiscontinuousConvMode = DISABLE;
  • hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  • hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  • hadc1.Init.NbrOfConversion = 2;
  • if (HAL_ADC_Init(&hadc1) != HAL_OK)
  • {
  • _Error_Handler(__FILE__, __LINE__);
  • }
  • /**Configure Regular Channel
  • */
  • sConfig.Channel = ADC_CHANNEL_5; // position
  • sConfig.Rank = ADC_REGULAR_RANK_1;
  • sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  • if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  • {
  • _Error_Handler(__FILE__, __LINE__);
  • }
  • /**Configure Regular Channel
  • */
  • sConfig.Channel = ADC_CHANNEL_6; // bubble
  • sConfig.Rank = ADC_REGULAR_RANK_2;
  • if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  • {
  • _Error_Handler(__FILE__, __LINE__);
  • }
  • }
  • 复制代码

    在启动转换时,依据设置的通道数,选择不同的DMA空间
    void StartADC1Misc(void){
  • HAL_ADC_Start_DMA(&hadc1, ADC1Buf.ValMem,ADCCNT*4);
  • }
  • void StartADC1IR(void){
  • HAL_ADC_Start_DMA(&hadc1, IRBuf.ValMem,ADCCNT*2);
  • }
  • 复制代码

    获取采样值的时候,找到对应的缓冲区
    uint32_t AdcGetValue(uint8_t ch){
  • uint32_t temp,i;
  • temp = 0;
  • for(i = ADCCNT/2-5;i< ADCCNT/2+5;i++){
  • temp = temp+ (ADC1Buf.Val[i][ch]&0xFFF);
  • }
  • temp /= 10;
  • return temp;
  • }
  • uint32_t AdcGetIRValue(uint8_t ch){
  • uint32_t temp,i;
  • temp = 0;
  • for(i = ADCCNT/2-5;i< ADCCNT/2+5;i++){
  • temp = temp+ (IRBuf.Val[i][ch]&0xFFF);
  • }
  • temp /= 10;
  • return temp;
  • }
  • 复制代码

    作者: southcreek, 来源:面包板社区

    链接: https://mbb.eet-china.com/blog/uid-me-408807.html

    版权声明:本文为博主原创,未经本人允许,禁止转载!

    PARTNER CONTENT

    文章评论2条评论)

    登录后参与讨论

    southcreek 2021-1-17 07:38

    冰点1128: 嗯,我一般都是一次采样N个通道,然后到DMA的地址查看.曾经有一段时间看AD的资料,才知道它有注入组,规则组.
    这两个组是有不同的功能,参见正点原子的说明.说的很详 ...
    这个还真没注意到,分注入组和规则组。

    冰点1128 2021-1-4 17:53

    嗯,我一般都是一次采样N个通道,然后到DMA的地址查看.曾经有一段时间看AD的资料,才知道它有注入组,规则组.
    这两个组是有不同的功能,参见正点原子的说明.说的很详细.
    相关推荐阅读
    southcreek 2025-04-03 09:49
    电路设计中的口线复用例子
    实例1:设置GPIO为输入或输出完成读取状态和驱动LED功能。下面这个电路使用3个gpio 用于读取拔码开关的设置和驱动3个LED流水灯显示。拔码开关在开机时需要读取一次。使用过程中不需要使用。如果单...
    southcreek 2025-02-20 13:35
    供电开关电路不良引起的MCU程序跑飞及解决办法
    这是一个3.3V 的供电开关,给WIFI模块供电。目的是能控制WIFI模块通电或断电。VCC_3V3 是电源,当WLENN为低时,Q1打开输出VCCW 给WIFI模块供电。实际使用时,当控制WLENN...
    southcreek 2025-01-22 06:34
    设置可执行程序图标
    在本文的示例中,图标文件名称为“logo.ico”,该文件位于项目主目录下。2.2 设置标题栏图标通过下列函数设置标题栏图标:setWindowIcon(QIcon("://logo.ico"));1...
    southcreek 2024-12-04 16:32
    PWM输出隔离DAC设计
    这个设计的目标是产生一个隔离的DAC输出。12V供电,产生0~5V的输出。达到10000约13.3位的分辨率。要求DAC输出在改变设置后1S内能稳定。需要能长时间保持稳定和低噪声。能达到要求的DAC只...
    southcreek 2024-12-04 15:23
    一个基于HAL库的串口控制框架
    将串口接收配置为 DMA方式,DMA 使用 DMA_CIRCULAR 模式工作。串口接收的数据实际上构成循环队列。 定义一个结构Comm_typedef 结构体中包含指向接收到的第一字节位置chrc...
    southcreek 2024-07-08 11:38
    接地不良导致的故障分析
    这个电路的控制板需要连接显示板和识别板。5V 供电和串行控制连到显示板,显示板再连接到识别板。识别板上电位器使用一个LDO供电,将输入的5V转成3.3V。当电位器滑动时,输出电压在0~3.3V之间。...
    我要评论
    2
    34
    关闭 站长推荐上一条 /4 下一条