看到这里,相信大家已经尝试过网上各类ADC_DMA传输的文章,且大多都并不能实现,因为在RT-Thread中并没有找到关于ADC的DMA接口,在官方例程中有关DMA的传输也只有一个串口接收的介绍,找遍全网怕也没能找到真正有用的消息。
在我成功实现ADC_DMA之前,也是和大家一样,到处寻找相关消息以及求助ChatGPT,可想而知,把希望寄托于别人倒不如自己去摸索,这样自己更能知道缺什么做什么。。。
不多说了,请往下看
一、ADC_DMA
以下是我求助ChatGPT的示例代码:
#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>
#define ADC_SAMPLE_COUNT 100
static rt_adc_device_t adc_device;
static rt_uint16_t adc_buffer[ADC_SAMPLE_COUNT];
static void adc_dma_callback(rt_device_t dev, rt_size_t size)
{
rt_adc_start(adc_device, ADC_MODE_DMA);
}
static void adc_dma_thread_entry(void *parameter)
{
rt_err_t result;
/* 初始化ADC设备 */
adc_device = (rt_adc_device_t)rt_device_find("adc");
if (adc_device == RT_NULL)
{
rt_kprintf("ADC device not found!\n");
return;
}
/* 配置ADC设备参数 */
struct rt_adc_msg msg;
msg.channel = ADC_CHANNEL_0;
msg.resolution = ADC_RESOLUTION_12BIT;
msg.buf = adc_buffer;
msg.count = ADC_SAMPLE_COUNT;
msg.callback = adc_dma_callback;
msg.user_data = RT_NULL;
/* 启动ADC设备 */
result = rt_adc_control(adc_device, RT_ADC_CMD_START, &msg);
if (result != RT_EOK)
{
rt_kprintf("Failed to start ADC device! Error code: %d\n", result);
return;
}
while (1)
{
/* 在这里可以对采集到的数据进行处理 */
rt_thread_mdelay(1000);
}
}
int adc_dma_sample(void)
{
rt_thread_t thread;
thread = rt_thread_create("adc_dma",
adc_dma_thread_entry,
RT_NULL,
1024,
RT_THREAD_PRIORITY_MAX - 1,
20);
if (thread != RT_NULL)
rt_thread_startup(thread);
return 0;
}
ChatGPT: 这个示例代码中,首先我们需要使用 rt_device_find 函数来查找ADC设备。然后,我们使用 rt_adc_control 函数来配置ADC设备的参数,包括选择通道、分辨率、缓冲区和采样数量等。在参数配置完成后,我们使用 rt_adc_control 函数的 RT_ADC_CMD_START 命令来启动ADC设备,并指定了一个回调函数 adc_dma_callback,该回调函数在DMA传输完成后被调用。
在 adc_dma_thread_entry 函数中,我们使用 rt_adc_control 函数的 RT_ADC_CMD_START 命令来启动ADC设备,并在回调函数中再次调用 rt_adc_start 函数来触发下一次DMA传输。
在 adc_dma_thread_entry 函数的主循环中,可以对采集到的数据进行处理,例如打印到终端或进行其他计算。
最后,在 adc_dma_sample 函数中,我们创建一个线程来执行 adc_dma_thread_entry 函数,并将线程设置为最高优先级。
请注意,以上示例代码仅供参考,具体的实现可能会因硬件平台或RT-Thread版本的不同而有所差异。在使用时,请根据实际情况进行适当的修改和调试。
可发现,ChatGPT的代码有模有样的,但实际移植过来会出现各种指令或函数报错,因为它所提供的代码并不适用于你的当前环境,多说不说,但它是可以给你提供一个不错的路线。
在经过本人的多次尝试,我是用裸机的开发形式成功实现DMA传输,所以这里并没有依托于RT-Thread平台提供的软件库,运用平台提供的库函数肯定是可以实现的,经本人多次尝试还是未能成功实现,所以这里仅介绍依托于HAL库的开发形式。
- 第一步,进STM32 CubeMX 初始化设备
- 第二步,四步完成ADC_DMA初始化,MX_DMA_Init()、MX_ADC1_Init()为cubemx初始化自动生成
MX_DMA_Init();
MX_ADC1_Init();
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&adc_data1_origin,(uint32_t)6);
HAL_ADC_Start(&hadc1);
- 第三步,直接打印,像什么找设备、打开设备的都不用管
while (1)
{
rt_thread_mdelay(1000);
rt_kprintf("\n\nadc0:%d\n",adc_data1_origin[0]);
rt_kprintf("adc1:%d\n",adc_data1_origin[1]);
rt_kprintf("adc2:%d\n",adc_data1_origin[2]);
rt_kprintf("adc3:%d\n",adc_data1_origin[3]);
rt_kprintf("adc4:%d\n",adc_data1_origin[4]);
rt_kprintf("adc5:%d\n\n",adc_data1_origin[5]);
}
至此,我都不敢相信 这就完事了
获取源码或学术交流联系下方即可👇👇👇