Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
ADC
DMA
stm32f407-atk
10
STM32F407ZGT6 ADC+DMA 多路输出结果有误
发布于 2021-11-28 03:00:25 浏览:1730
订阅该版
在网上借鉴了ADC+DMA的写法改写了rtthread的adc框架,可以正常的获取单个通道的值,但是当读取多通道时发现其他的值只与第一个通道值有关,且有一定的差值。 [借鉴的地址](https://blog.csdn.net/qq_30659437/article/details/107282070) ```c #ifdef BSP_USING_ADC_DMA #define BSP_DMA_BUF_COUNT 1 #define BSP_ADC_TOTAL_CHANNELS 3 #define BSP_ADC_CHN_DEF {5,6,7} #define BSP_ADC_SAMPLE_CYC_DEF ADC_SAMPLETIME_56CYCLES #endif #define ADC1_CONFIG \ { \ .Instance = ADC1, \ .Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4, \ .Init.Resolution = ADC_RESOLUTION_12B, \ .Init.DataAlign = ADC_DATAALIGN_RIGHT, \ .Init.ScanConvMode = ENABLE, \ .Init.EOCSelection = ADC_EOC_SINGLE_CONV, \ .Init.ContinuousConvMode = ENABLE, \ .Init.NbrOfConversion = BSP_ADC_TOTAL_CHANNELS, \ .Init.DiscontinuousConvMode = DISABLE, \ .Init.NbrOfDiscConversion = 0, \ .Init.ExternalTrigConv = ADC_SOFTWARE_START, \ .Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE, \ .Init.DMAContinuousRequests = ENABLE, \ } #define ADC1_DMA_CONFIG \ { \ .Instance = DMA2_Stream0, \ .Init.Direction = DMA_PERIPH_TO_MEMORY, \ .Init.PeriphInc = DMA_PINC_DISABLE, \ .Init.MemInc = DMA_MINC_ENABLE, \ .Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD, \ .Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD, \ .Init.Mode = DMA_CIRCULAR, \ .Init.Priority = DMA_PRIORITY_HIGH, \ .Init.FIFOMode = DMA_FIFOMODE_DISABLE, \ .Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL, \ .Init.MemBurst = DMA_MBURST_SINGLE, \ .Init.PeriphBurst = DMA_PBURST_SINGLE, \ .Init.Channel = DMA_CHANNEL_0, \ } ``` ADC和DMA的配置 ``` void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if (hadc->Instance == ADC1) { /* Peripheral clock enable */ __HAL_RCC_ADC1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); #ifdef BSP_USING_ADC_DMA __HAL_RCC_DMA2_CLK_ENABLE(); HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); #endif } } ``` GPIO初始化 ```c static int stm32_adc_init(void) { int result = RT_EOK; /* save adc name */ char name_buf[5] = {'a', 'd', 'c', '0', 0}; int i = 0; for (i = 0; i < sizeof(adc_config) / sizeof(adc_config[0]); i++) { /* ADC init */ name_buf[3] = '0'; stm32_adc_obj[i].ADC_Handler = adc_config[i]; #if defined(ADC1) if (stm32_adc_obj[i].ADC_Handler.Instance == ADC1) { name_buf[3] = '1'; } #endif #if defined(ADC2) if (stm32_adc_obj[i].ADC_Handler.Instance == ADC2) { name_buf[3] = '2'; } #endif #if defined(ADC3) if (stm32_adc_obj[i].ADC_Handler.Instance == ADC3) { name_buf[3] = '3'; } #endif if (HAL_ADC_Init(&stm32_adc_obj[i].ADC_Handler) != HAL_OK) { LOG_E("%s init failed", name_buf); result = -RT_ERROR; } else { #ifdef BSP_USING_ADC_DMA int j; ADC_ChannelConfTypeDef sConfig = {0}; rt_uint32_t chn[BSP_ADC_TOTAL_CHANNELS] = BSP_ADC_CHN_DEF; sConfig.SamplingTime = BSP_ADC_SAMPLE_CYC_DEF; for (j = 0; j < BSP_ADC_TOTAL_CHANNELS; j++) { sConfig.Channel = stm32_adc_get_channel(chn[j]); sConfig.Rank = j + 1; if (HAL_ADC_ConfigChannel(&stm32_adc_obj[j].ADC_Handler, &sConfig) != HAL_OK) { rt_kprintf("channel error\n"); return 1; } } #endif /* register ADC device */ if (rt_hw_adc_register(&stm32_adc_obj[i].stm32_adc_device, name_buf, &stm_adc_ops, &stm32_adc_obj[i].ADC_Handler) == RT_EOK) { LOG_D("%s init success", name_buf); } else { LOG_E("%s register failed", name_buf); result = -RT_ERROR; } } } return result; } INIT_BOARD_EXPORT(stm32_adc_init); #endif /* BSP_USING_ADC */ ``` ```c static rt_err_t stm32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled) { ADC_HandleTypeDef *stm32_adc_handler; DMA_HandleTypeDef dma_init_handler = {0}; RT_ASSERT(device != RT_NULL); stm32_adc_handler = device->parent.user_data; if (enabled) { #ifdef BSP_USING_ADC_DMA if (device->dma_buf != RT_NULL) { if (stm32_adc_handler->Instance == ADC1) { dma_init_handler = dma_config[0]; HAL_DMA_Init(&dma_init_handler); __HAL_LINKDMA(stm32_adc_handler, DMA_Handle, dma_init_handler); HAL_DMA_Start(&dma_init_handler, ((rt_uint32_t)ADC1 + 0x4c), (rt_uint32_t)device->dma_buf, BSP_ADC_TOTAL_CHANNELS * BSP_DMA_BUF_COUNT); } HAL_ADC_Start_DMA(stm32_adc_handler, (rt_uint32_t *)device->dma_buf, BSP_ADC_TOTAL_CHANNELS * BSP_DMA_BUF_COUNT); } #else __HAL_ADC_ENABLE(stm32_adc_handler); #endif } else { __HAL_ADC_DISABLE(stm32_adc_handler); } return RT_EOK; } ``` 改写的驱动部分 ```c rt_device_t adc1_dev; rt_uint16_t joystick_value[3][1]; static int rt_adc1_init(void) { adc1_dev = rt_device_find("adc1"); if (adc1_dev == RT_NULL) { rt_kprintf("adc sample run failed! can't find %s device!\n", "adc1"); } rt_device_control(adc1_dev, RT_ADC_CMD_SET_DMA_BUF, joystick_value); rt_device_control(adc1_dev, RT_ADC_CMD_ENABLE, RT_NULL); return RT_EOK; } INIT_APP_EXPORT(rt_adc1_init); ``` 启动的部分 ![QQ截图20211128025852.png](https://oss-club.rt-thread.org/uploads/20211128/62dd0ea9e52daa8e234e9ca9a7d57ad2.png) ![QQ截图20211128025906.png](https://oss-club.rt-thread.org/uploads/20211128/a340bcf5ee29e120ca542c9daaa45155.png) ![QQ截图20211128025916.png](https://oss-club.rt-thread.org/uploads/20211128/c5635d46bed02f996697e7c058d6ec41.png) 仅仅改变PA5的输入电平,三个输出都会变,且值都不相同,而改变PA6,7则完全没影响
查看更多
5
个回答
默认排序
按发布时间排序
红枫
认证专家
2023-04-03
这家伙很懒,什么也没写!
通道切换时上一个通道的电平可能会影响下一个通道,如果想消除这种影响,可以采样两次转换取第2次转换结果的方式。原理看ADC采样保持
张世争
2021-11-29
学以致用
ADC 的 channel,应该配置到DMA那边吧
fubaojun2006
2021-12-02
哇(挖)~~坑~~~啊!
你的帖子,发布于 2021-11-28 03:00:25 我摸了摸我的头发。 看了你两篇关于ADC DMA的帖子了,也看了你参考的源连接。 我决定 还是按裸机方式 初始化ADC ,然后初始化DMA 。用一个任务去处理DMA搬运过来的数据。 这样感觉还简单点---来自一个没有学设备管理框架的渣渣
safly
2022-03-25
这家伙很懒,什么也没写!
兄弟,你这个驱动没有问题,只有一行代码有个笔误。 将 `if (HAL_ADC_ConfigChannel(&stm32_adc_obj[j].ADC_Handler, &sConfig) != HAL_OK)` 改成 `if (HAL_ADC_ConfigChannel(&stm32_adc_obj[i].ADC_Handler, &sConfig) != HAL_OK)` 即可,通道配置的时候,不能改变stm32_adc_obj的下标。
CrazyH
2023-04-19
这家伙很懒,什么也没写!
rtt的adc架构 学习就行
撰写答案
登录
注册新账号
关注者
1
被浏览
1.7k
关于作者
Tourist
这家伙很懒,什么也没写!
提问
4
回答
3
被采纳
0
关注TA
发私信
相关问题
1
请大神帮忙看下风格 还是哪里有问题 照着串口驱动写的ADC驱动
2
ADC config
3
rt_thread_delay()和ADC采样之间的冲突
4
请教在官方BSP中的STM32F40X程序中加入ADC,串口没输出。
5
给RT-Thread添加ADC驱动框架
6
求助:ADC采样被干扰
7
【内核和外设学习营】十里 ADC光敏电阻电压采集实验
8
<内核学习营>+坦然+探索者stm32f407板子的ADC测试光传感器实验
9
【内核学习营】+青春+ADC读取光敏传感器实验
10
《内核学习营》+水一方+项目中应用的ADC实现电压采集
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
7
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部