基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集

前言

在使用到RTT的ADC设备框架进行AD的多通道采集时,发现数据会跳变,觉得可能是没有加DMA的缘故,但RTT好像没有对应的DMA接口函数(或者我没找到),故尝试不使用RTT的ADC设备框架,直接使用HAL库对ADC进行DMA的配置


一、创建工程

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第1张图片

二、打开CubeMX进行配置

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第2张图片

三、使用外部高速时钟

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第3张图片

四、配置调试下载接口

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第4张图片

五、打开异步串口一,因为创建工程的时候默认使用了串口一,所以这里进行配置

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第5张图片

六、配置ADC,开启ADC转换通道

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第6张图片

七、打开ADC的DMA模式

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第7张图片

八、选择ADC1

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第8张图片

九、选择DMA的模式,DMA的模式有两种:Normal(普通)和Circular(循环)。

在Normal模式下,DMA传输将在传输完指定的数据量后停止。这意味着当DMA传输完成后,它需要重新配置和启动以进行下一次传输。Normal模式适用于需要一次性传输固定数量数据的情况。

相比之下,Circular模式下的DMA传输会循环执行,不会停止。当传输完成后,DMA会立即重新开始传输,无需重新配置和启动。这种模式适用于需要连续传输数据的情况,例如音频流或连续的数据采样。
基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第9张图片

十、配置时钟,直接拉满

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第10张图片

十一、生成代码

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第11张图片

十二、将如下CubeMX生成的代码均进行一一复制

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第12张图片
基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第13张图片
基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第14张图片

十三、将上面复制的代码均一一粘贴到board.c的末尾

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第15张图片

十四、在board.c文件的前面,加上这两句

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第16张图片

十五、将CubeMX生成的这段代码进行注释

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第17张图片

十六、编译一下,无报错

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第18张图片

十七、把board.c文件中的这两个函数前面的static关键字去掉

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第19张图片

十八、在board.c的ADC1初始化中,将每个Rank添加对应的通道,这里CubeMX默认生成的只有通道0,如果你不自己添加,待会你读出来的值全是一样的,因为所有Rank都对应到通道0去了

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第20张图片

十九、在主函数中写入如下代码

/*
 * Copyright (c) 2006-2024, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-01-26     RT-Thread    first version
 */

#include 

#include 
#include 
#include 

extern ADC_HandleTypeDef hadc1;
rt_uint16_t adc_val[4]={0};            //adc采样值

int main(void)
{
    MX_DMA_Init();
    MX_ADC1_Init();


    HAL_NVIC_DisableIRQ(DMA1_Channel1_IRQn); //禁用DMA通道1中断


     while (1)
    {

         HAL_ADC_Start_DMA(&hadc1, (rt_uint32_t*) &adc_val, 4);  //启动ADC1的DMA转换,将转换结果存贮到AD_Value的数组里

         //打印输出
         rt_kprintf("%d,%d,%d,%d\n", adc_val[0], adc_val[1], adc_val[2], adc_val[3]);




        rt_thread_mdelay(50);

    }


}

二十、编译一下,无报错

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第21张图片

二十一、我采集的是遥控器遥感的数据,经测试,数据正确。

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第22张图片

二十二、值得一提的是,这里的禁用DMA通道1的中断,看起来好像不太对,按理说应该开启DMA中断才对呀,数据转换完成触发中断进行处理,我是这么想的,不过经过实测,如果把这句代码注释掉,程序就会卡死,也就说如果不禁用这个中断,程序就会卡死,我暂时也不知道为什么,在此记录一下

基于RT-Thread(RTT)的HAL库+ADC+DMA多通道采集_第23张图片

你可能感兴趣的:(RTT,stm32,c语言,RTT,学习,RTOS)