ADC+DMA采集配置能量机关

简介: ADC+DMA采集配置能量机关

ADC+DMA采集。RNG硬件随机数发生器。ADC的Vrefint Channel内部参照电压。FreeRTOS的Delay_us函数。这是能量机关其他部分的配置。

ADC+DMA采集

转换时间

ADC的工作流程为采样 - 比较 - 转换。采样是指对某一时刻的模拟电压进行采集,比较是指将采样的电压在比较电路中进行比较,转换是指将比较电路中结果转换成数字量

  • ADC时钟

​ ADC输入时钟ADC_CLK,由PCLK2经过分频产生,最大值是36MHz。

  • 采样周期

​ ADC需要若干个ADC_CLK周期完成对输入的电压进行采样。周期就是1/ADC_CLK。ADC最小需要3个周期,因为大幅击打不会有很高的频率,所以设置为480 Cycles也可以。

  • 总转换时间

​ ADC的总转换时间 = (设置的采样周期数 + 12个周期)x ADC_CLK。加12个周期是因为转换精度设置为12Bits

ADC Parameter Settings

  • DMA Settings开启ADC。

    • 配置下DMA模式为Circular,既循环更新数据。默认的Normal模式触发后只执行 一次。
    • 设置方向Direction为从外设到内存。
    • 配置自增地址为Memory方式,因为我程序里定义uint16_t 的数组来存储多路ADC数据,占两个字节所以选择half word
  • Scan Conversion Mode 设置为 ENABLE

    多通道AD转换配置为使用扫描

  • Continuous Conversion Mode 设置为 ENABLE

    使能自动连续转换。DISABLE为单次转换,转换一次后停止需要代码手动控制才重新启动转换。

  • Discontinuous Conversion Mode 默认为 DISABLE

    关闭非连续转换模式,默认为DISABLE即可

  • DMA Continuous Requests 设置为 ENABLE

    每次转换完成后产生EOC的同时,也产生DMA请求

    指定DMA以连续模式执行。(必须开启DMA才有效,且设置为ENABLE时必须配置DMA为circular模式)

  • End of Conversion Selection

    每个通道转换结束后发送 EOC 标志/所有通道转换结束后发送EOC标志

  • Number Of Conversion 设置为 6

    配置几路通道采集及采集顺序。大幅一共5个扇叶加上一个 Vrefint Channel。下面的 RANK1-6 即可配置采集顺序和采样周期。

Vrefint Channel 内部参照电压

VREFINT是STM32的内部参照电压。一般来说STM32的ADC采用Vcc作为Vref,但为了防止Vcc存在波动较大导致Vref不稳定,进而导致采样值的比较结果不准确,STM32可以通过内部已有的参照电压VREFINT来进行校准,接着以VREFINT为参照来比较ADC的采样值,从而获得比较高的精度。VREFINT的电压为1.2V。Vrefint Channel在STM32内部完成没有对应引脚,只能出现在主ADC1中使用。

volatile fp32 voltage_vrefint_proportion = 8.0586080586080586080586080586081e-4f; // 初始化

adc_calibration = adc_original * (1.20f / voltage_vrefint_proportion);

程序

uint16_t ADC_ConvertedValue[6] = {0};
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&ADC_ConvertedValue, 6);

即可开启DMA传输。

ADC的DMA中断函数为DMA2_Stream0_IRQHandler。可以直接在DMA中断函数内加入判断是否大幅被击打的程序部分。

最终实现的方法可以用很多种,比如用外部触发信号像是定时器之类,这里就是展示了其中一种的配置思路和方法。

不使用DMA的ADC单次采集

/**
  * @brief            获取ADC采样值
  * @retval            none
  * @example        adcx_get_chx_value(&hadc1, ADC_CHANNEL_1);
  */
uint16_t adcx_get_chx_value(ADC_HandleTypeDef *ADCx, uint32_t ch)
{
    static ADC_ChannelConfTypeDef sConfig = {0};
    sConfig.Channel = ch;                            // ADC转换通道
    sConfig.Rank = 1;                                // ADC序列排序 即转换顺序
    sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;    // ADC采样时间

    HAL_ADC_ConfigChannel(ADCx, &sConfig);            // 设置ADC通道的各个属性值
//    if (HAL_ADC_ConfigChannel(ADCx, &sConfig) != HAL_OK) {
//        Error_Handler();                            // Debug时使用
//    }
    
    HAL_ADC_Start(ADCx);                            // 开启ADC采样

    HAL_ADC_PollForConversion(ADCx, 1);                // 等待ADC转换结束

    if (HAL_IS_BIT_SET(HAL_ADC_GetState(ADCx), HAL_ADC_STATE_REG_EOC)) {    // 判断转换完成标志位是否设置
        return (uint16_t)(HAL_ADC_GetValue(ADCx));    // 获取ADC值
    } else {
        return 1;                                    // 发现数值为1代表错误
    }
}

RNG硬件随机数发生器

STM32F4自带了RBG硬件随机数发生器,RNG处理器是一个以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个 32 位的随机数。

在CubeMX的Security使能RNG之后,还需要配置下时钟树的RNG专用时钟 (PLL48CLK) 。

生成的 MX_RNG_Init(); 已经完成了所需的初始化。初始化的过程很简单,首先使能挂载到AHB2总线的随机数发生器时钟,然后使能随机数发生器即可完成初始化。

uint32_t HAL_RNG_GetRandomNumber(RNG_HandleTypeDef *hrng);  

该函数用于读取随机数值。

每次读取之前,须先判断RNG_SR这个RNG 状态寄存器的DRDY最低位,如果该位为1则则说明RNG_DR这个数据寄存器的数据是有效的,可以读取得到随机数值,读取后该位自动清零;如果不为 1则需要等待。该函数已包含判断DRDY位并返回读取到的随机数值。

#include "stm32f4xx_hal_rng.h"
/**
  * @brief          生成0-5随机数 用于确定大幅的亮灯顺序
  */
void RandGet(void)
{
    uint8_t i = 0, j = 0, tmp = 0;
    for(i = 0; i < 5; i ++) {
        while (1) {
            tmp = HAL_RNG_GetRandomNumber(&hrng) % 5;
            for(j = 0; j < i; j ++) {
                if(tmp == Rand[j]) {
                    break;
                }
            }
            if(j == i) {
                Rand[i] = tmp;
                break;
            }
        }
    }
}

// 如果是F1的板子没有RNG,可以换成伪随机数,用当前时间作为种子生成随机数
#include <stdlib.h>
// 时间作为种子
srand((unsigned int)HAL_GetTick());
tmp = rand() % 5;
HAL_Delay(1);

Delay_us

用FreeRTOS时,TimeBaseSource为SysTick以外的其他定时器,对应的us延时也需要改动。

/**
  * @brief            us延时
  * @param[in]        us
  */
#define TimebaseSource_is_SysTick 1
#if    (!TimebaseSource_is_SysTick)
    extern TIM_HandleTypeDef htim9;        // 当使用FreeRTOS, TimebaseSource为其他定时器时
    #define Timebase_htim htim9
    #define Delay_GetCurrentValueReg()    __HAL_TIM_GetCounter(&Timebase_htim)
    #define Delay_GetReloadReg()        __HAL_TIM_GetAutoreload(&Timebase_htim)
#else
    #define Delay_GetCurrentValueReg()    (SysTick->VAL)
    #define Delay_GetReloadReg()        (SysTick->LOAD)
#endif

static uint32_t fac_us = 0;
static uint32_t fac_ms = 0;

void Delay_us_init(void)
{
    #if    (!TimebaseSource_is_SysTick)
        fac_ms = 1000000;                // 作为时基的计数器时钟频率在HAL_InitTick()中被设为了1MHz
        fac_us = fac_ms / 1000;
    #else
        fac_ms = SystemCoreClock / 1000;
        fac_us = fac_ms / 1000;
    #endif
}

void Delay_us(uint16_t us)
{
    /*** 定时器功能实现 ***/
    uint32_t ticks = us * fac_us;
    uint32_t reload = Delay_GetReloadReg();
    uint32_t told = Delay_GetCurrentValueReg();
    uint32_t tnow = 0;
    uint32_t tcnt = 0;
    while (1) {
        tnow = Delay_GetCurrentValueReg();
        if (tnow != told) {
            if (tnow < told) {
                tcnt += told - tnow;
            } else {
                tcnt += reload - tnow + told;
            }
            told = tnow;
            if (tcnt >= ticks) {
                break;
            }
        }
    }

    /*** NOP空语句实现 ***/
//    uint32_t delay = us * fac_us / 4;
//    do {
//        __NOP();
//    }
//    while (delay --);
}
目录
相关文章
|
数据采集 C语言
单片机开发之ADC0808/9信号采集
本文主要介绍了单片机开发之ADC0808/9信号采集
677 0
单片机开发之ADC0808/9信号采集
|
7月前
|
传感器 编解码 IDE
STM32CubeMX ADC采集光照和电压
STM32CubeMX ADC采集光照和电压
370 3
MCU ADC如何测量超过VCC的电压?
MCU ADC如何测量超过VCC的电压?
STM32:USART串口外设(内含:1.USART简介+2.USART基本结构+3.数据帧+4.起始位侦测+5.数据采样+6.波特率发生器)
STM32:USART串口外设(内含:1.USART简介+2.USART基本结构+3.数据帧+4.起始位侦测+5.数据采样+6.波特率发生器)
430 0
STM32:USART串口外设(内含:1.USART简介+2.USART基本结构+3.数据帧+4.起始位侦测+5.数据采样+6.波特率发生器)
|
传感器 芯片
MCU实现对外部脉冲信号的计数功能
MCU实现对外部脉冲信号的计数功能
72 1
|
物联网
工程监测无线中继采集仪的寄存器(参数)汇总详解
无线中继采集发送仪有很多参数(寄存器),对于一些简单的应用,用户无需关心这些参数,使用默认参数值即可。仅列出较为常用的参数,当需要配置设备完成复杂、特殊的应用时,请查看“无线中继采集发送仪寄存器汇总说明” 。
工程监测无线中继采集仪的寄存器(参数)汇总详解
|
传感器 存储 数据采集
工程监测多通道振弦模拟信号采集仪VTN DAC 的使用
VTN208-432是多通道振弦、温度、模拟传感信号系列数据采集仪,可对32通道振弦频率、32通道热敏电阻或DS18B20温度传感器、32通道模拟量传感器(电流或电压)进行实时在线采集或全自动定时采集存储工作;预留一路可调电源输出为模拟传感器定时供电;程控多路DAC输出,可以用于将振弦频率信号实时转换为模拟信号输出。设备支持RS485数据接口(支持Modbus或自定义AABB简单通讯协议)可以直接接入测控系统(如PLC、无线数据传输设备等)。
工程监测多通道振弦模拟信号采集仪VTN DAC 的使用
|
传感器 存储
工程监测多通道振弦模拟信号采集仪VTN通道分配与激励设置
VTN208-432 是多通道振弦、温度、模拟传感信号采集仪,可对最多32通道振弦频率、32通道温度传感器(热敏电阻或 DS18B20)、32 通道模拟量传感器(电压或电流)进行实时或全自动定时采集存储。
工程监测多通道振弦模拟信号采集仪VTN通道分配与激励设置
|
传感器 存储 数据采集
工程监测多通道振弦模拟信号采集仪VTN的四种工作模式
VTN是多通道振弦、温度、模拟传感信号系列数据采集仪,可对32通道振弦频率、32通道热敏电阻或DS18B20温度传感器、32通道模拟量传感器(电流或电压)进行实时在线采集或全自动定时采集存储工作;预留一路可调电源输出为模拟传感器定时供电;程控多路DAC输出,可以用于将振弦频率信号实时转换为模拟信号输出。设备支持RS485数据接口(支持Modbus或自定义AABB简单通讯协议)可以直接接入测控系统(如PLC、无线数据传输设备等)。
工程监测多通道振弦模拟信号采集仪VTN的四种工作模式
|
传感器 数据处理
VM系列振弦采集读数模块的电压激励
什么是振弦传感器采集读数模块:指针对振弦传感器的特性而设计的传感器激励、读数模块。具有集成度高、功能模块化、数字接口的一系列特性,能完成振弦 传感器的激励、信号检测、数据处理、质量评估等专用针对性功能,进行传感器频率和温度物理量模数转换,进而通过数字接口实现数据交互。振弦传感器读数模块是振弦传感器与数字化、信息化之间的核心转换单元。
VM系列振弦采集读数模块的电压激励