STM32G4 ADC模块注入模式使用方法

目录

概述

1 注入模式介绍

1.1 触发注入模式

1.2 自注入模式

1.3 转换时序图

1.4 注入源列表

2 STM32 Cube 配置项目

2.1 ADC模块参数配置

2.2 触发源参数配置

3 功能实现 

3.1 软件架构

3.2 ADC相关代码

3.2.1 ADC模块初始化

3.2.2 读取ADC数据

 3.3 源代码文件

4 测试

4.1 测试程序定义

4.2 功能测试

4.2.1 采样频率测试

4.2.2 DAC输出波形

4.2.3 ADC采样波形

4.2.4 波形比较


概述

本文主要介绍使用STM32G4 ADC模块注入模式实现ADC转换功能,文中介绍ADC注入模式转换的实现原理,波形特征,还介绍使用STM32 Cube配置项目,并编写代码验证该功能。

1 注入模式介绍

1.1 触发注入模式

要使用触发注入,必须清除ADC_CFGR寄存器中的JAUTO位。


1. 通过外部触发器或通过设置ADC_CR寄存器中的ADSTART位启动一组常规通道的转换。

2. 如果外部注入触发器发生,或者如果ADC_CR寄存器中的JADSTART位是设置在转换一组常规通道时,当前转换复位并启动注入通道序列开关(所有注入通道转换一次)。

3. 从上次中断的正则转换中恢复正则组信道的正则转换。

4. 如果在注入转换期间发生常规事件,则不会中断注入转换,而是在注入序列的末尾执行常规序列。下图显示了相应的时序图。

注意点:

当使用触发注入时,必须确保触发事件之间的间隔长于注入序列。例如,如果序列长度为30个ADC时钟周期(即两次转换,采样时间为2.5个时钟周期),则触发器之间的最小间隔必须为31个ADC时钟周期。

1.2 自注入模式

如果设置了ADC_CFGR寄存器中的JAUTO位,则注入组中的通道在常规通道组之后自动转换。这可以用来转换在ADC_SQRy和ADC_JSQR寄存器中编程的最多20个转换序列。

在这种模式下,必须将ADC_CR寄存器中的ADSTART位设置为启动常规转换,然后是注入转换(JADSTART必须保持清除)。设置ADSTP位会终止常规转换和注入转换(不能使用JADSTP位)。在此模式下,必须禁用注入通道上的外部触发

注意点:

1)不可能同时使用自动注入和不连续模式。

2)当DMA在JAUTO模式下用于导出常规音序器的数据时,需要将其编程为循环模式(在DMA_CCRx寄存器中设置CIRC位)。如果CIRC位复位(单发模式),则在DMA传输时停止JAUTO序列完整的事件。

1.3 转换时序图

1.4 注入源列表

2 STM32 Cube 配置项目

2.1 ADC模块参数配置

1) MCU配置模拟量端口

2)ADC模块上的配置

 3)常规参数配置

4) 注入模式参数配置

2.2 触发源参数配置

 本文选择TIME0作为触发定时器,其具体配置如下:

1)定时器通道选择

2)基本参数配置

4) 参数定义

3 功能实现 

3.1 软件架构

完成以上参数配置后,就可以生成代码,其程序框架结构如下:

3.2 ADC相关代码

3.2.1 ADC模块初始化

代码32行:启动定时器

代码33行:启动ADC注入中断

代码35行:指针指向ADC数据buff

3.2.2 读取ADC数据

代码46行:读取通道1数据

代码47行:读取通道2数据

 3.3 源代码文件

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * File Name        :  adc_drv.c
 * Description      :  adc driver 
 ******************************************************************************
 * @attention
 *
* COPYRIGHT:    Copyright (c) 2024  tangmingfei2013@126.com

* CREATED BY:   mingfei.tang
* DATE:         JUL 05th, 2024

 ******************************************************************************
 */
/* USER CODE END Header */
#include "adc_drv.h"
#include "adc.h"
#include "tim.h"
#include "userDebug.h"
#include "mainTask.h"
#include "waveLib.h"
#include "stTemper.h"


float adc1_value_list[ADC_TOTAL_CH];
static float *pADC_ValList;
static bool bl_ready = false;

void adc_drv_init( void )
{
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);
    HAL_ADCEx_InjectedStart_IT(&hadc1);
    
    pADC_ValList = adc1_value_list;
}


__attribute__((section("ccmram")))
void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    static uint32_t count,last_val;
    
    if(hadc==&hadc1)
    {
        adc1_value_list[0] = HAL_ADCEx_InjectedGetValue(&hadc1,ADC_INJECTED_RANK_1);
        adc1_value_list[1] = HAL_ADCEx_InjectedGetValue(&hadc1,ADC_INJECTED_RANK_2);
        //adc1_value_list[2] = HAL_ADCEx_InjectedGetValue(&hadc1,ADC_INJECTED_RANK_3);
        
        count++;
        if( get_1ms_status() )
        {
            clear_1ms_status();
            last_val = count;
            count = 0;
        }
        adc1_value_list[POS_FREQ] = last_val*1000;
        bl_ready = true;
    }
}

void Debug_adcLog( void )
{
    float value;
    
    value = 200+ sin_wave();
    // dac_triangle_wave();
    DAC_SetConvert(value);
    if( bl_ready )
    {
        bl_ready = false;

        adc1_value_list[2] = value;
        // asin wave 
        adc1_value_list[3] = asin_wave();
     
        Debug_PrintfJustFloat( pADC_ValList, ADC_TOTAL_CH );
    }
}




/* End of this file */

4 测试

4.1 测试程序定义

1)使用STM32G4的DAC产生一路正弦波

2)使用STM32G4的ADC模块采样该正弦波

 源代码实现:

1)正弦波函数:

2)log输出函数

 源代码函数:

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * File Name        :  waveLib.c
 * Description      :  main task 
 ******************************************************************************
 * @attention
 *
* COPYRIGHT:    Copyright (c) 2024  tangmingfei2013@126.com

* CREATED BY:   mingfei.tang
* DATE:         JUL 05th, 2024

 ******************************************************************************
 */
/* USER CODE END Header */
#include "waveLib.h"
#include "dac.h"
#include <stdio.h> 
#include <string.h>
#include <stdbool.h>
#include <math.h>

#define PI    3.14159


void DAC_SetConvert( uint32_t value)
{
   HAL_DAC_SetValue( &hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R,value );
}

void dac_triangle_wave( void )
{
    static  uint32_t count = 0;
    
    DAC_SetConvert(count);
    count++;
    if( count > 4095 )
    {
        count = 0;
    }
}




float asin_wave( void )
{
    static double t = -1;
    float value, angle;
    
    if( t >= 1 )
    {
      t = -1;
    }
    
    value = asin( t ); 
    angle = (180*value)/3.1415926;
    t += 0.001;
    
    return  angle;
}

float sin_wave( void )
{
    float value, angle;
    static double t = -1;
    
    angle = 2*PI*t;
    value = 100*sin( angle ); 
    
    t += 0.001;
    if( t >= 1 )
    {
      t = -1;
    }
    
    return  value;
}





/* End of this file */

4.2 功能测试

4.2.1 采样频率测试

配置的采样频率

测试到采样频率

4.2.2 DAC输出波形

4.2.3 ADC采样波形

 

4.2.4 波形比较

 

作者:mftang

物联沃分享整理
物联沃-IOTWORD物联网 » STM32G4 ADC模块注入模式使用方法

发表回复