[应用相关] ADC(16bit分辨率)+DMA采样三路模拟量(并行)

[复制链接]
1023|12
 楼主| 木木guainv 发表于 2021-9-4 15:21 | 显示全部楼层 |阅读模式
一、前言
在实际项目上,ADC采样必须与DMA组合使用,实现并行采样。这里的“并行采样”并不是多个通道同时采样,而是ADC控制器一边采样,CPU一边干其他非常重要的活。当CPU在需要ADC采样的数据时,通过cache获取内存里模拟量的值即可。

这个笔记实现ADC3+DMA采样三路模拟量,分别是ADC_IN9, Vrefint Channel(MCU内部), Temperature Sensor Channel(MCU内部).

系统框图如下(从右到左):

ADC3采样各个通道的模拟量,每当采样完成时,让DMA将采样的数据存放到内存RAM_D3里(声明一个全局数组ADC3_Data[3])。
每隔300ms,CPU通过cache获取全局变量ADC_Data[0] ~ ADC_Data[2]一共3个模拟量。

9245261331e7980196.png

 楼主| 木木guainv 发表于 2021-9-4 15:22 | 显示全部楼层
二、CubeMX
2.1、RCC,SYS,Clock Configuration
这三项的设置不赘述

2.2、CORTEX_M7(cache与MPU)
DMA不能访问DTCM内存,所以要开辟RAM_D3内存,让DMA有地方放数据。基于这个目的,需要开启Cortex_M7的cache与MPU功能。
6806361331ea410cec.png

 楼主| 木木guainv 发表于 2021-9-4 15:23 | 显示全部楼层
2.3、ADC3 Mode and Configuration

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg


 楼主| 木木guainv 发表于 2021-9-4 15:24 | 显示全部楼层
2.4、DMA Settings

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg


 楼主| 木木guainv 发表于 2021-9-4 15:24 | 显示全部楼层
2.5、Parameter Settings


watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg


 楼主| 木木guainv 发表于 2021-9-4 15:26 | 显示全部楼层
2.6、GPIO settings

只有ADC3_IN9是外部通道,所以只有一个GPIO口。
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg
最后生成代码:
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg


 楼主| 木木guainv 发表于 2021-9-4 15:27 | 显示全部楼层
三、Keil

3、1、Target

让Keil只管理DTCM内存,不要管理其他内存。
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg


 楼主| 木木guainv 发表于 2021-9-4 15:29 | 显示全部楼层
2.2、Linker
从ST官方手册RM0433可以查到,STM32H743的Flash首地址是0x08000000,DTCM(紧密耦合内存)的首地址是0x20000000。
5708761332020d20a1.png
.sct文件,最开始跟Target配置的ROM与RAM一一对应的。接下来,我们需要增加.sct的内存。
21845613320256fa87.png
在.sct文件添加其他内存的描述。

235266133202b6de30.png

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00200000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00200000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00020000  {  ; RW data
   .ANY (+RW +ZI)
  }

  RW_IRAM4 0x38000000 0x00010000  {  ; RW data - 64KB SRAM4(0x38000000)
   *(.RAM_D3)
  }

}
接着,一定要Rebuild整个工程,不然会报错。。
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg

 楼主| 木木guainv 发表于 2021-9-4 15:29 | 显示全部楼层
四、代码
4.1、adc.c

在函数MX_ADC3_Init():
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg


 楼主| 木木guainv 发表于 2021-9-4 15:30 | 显示全部楼层
4.2、main.c

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg


 楼主| 木木guainv 发表于 2021-9-4 15:31 | 显示全部楼层
五、硬件接线
只有ADC3_IN9是外部通道,为了方便测试,ADC3_IN9连接3.3V。

六、DEBUG
6.1、Debug(printf)Viewer
从printf的信息看到,Vrefint的值是正确的。ADC3_IN9与DC3.3V连接,所以它的值非常接近3.3V。


watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg

 楼主| 木木guainv 发表于 2021-9-4 15:31 | 显示全部楼层
6.2、观察全局变量

实时观察全局变量。
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbGxhY2U4OQ==,size_16,color_FFFFFF,t_70.jpg


 楼主| 木木guainv 发表于 2021-9-4 15:32 | 显示全部楼层
七、细节补充
7.1、在HAL_ADCEx_Calibration_Start()之前添加HAL_Delay
有一些网友说,在某些板子上电时,电容正在充电,最好在HAL_ADCEx_Calibration_Start()之前延时一会会,等待电容充满电,板子的3.3V电源网络稳定后再执行HAL_ADCEx_Calibration_Start()。

30412613320f9c3acb.png

您需要登录后才可以回帖 登录 | 注册

本版积分规则

192

主题

4366

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部