[STM32U3] 【每周分享】【STM32U385RG 测评】+ADC采集、输出

[复制链接]
 楼主| LiuDW091 发表于 2025-7-18 13:29 | 显示全部楼层 |阅读模式
本帖最后由 LiuDW091 于 2025-7-18 13:41 编辑

#每日话题# #申请原创# #有奖活动# #申请开发板#[url=home.php?mod=space&uid=760190]@21小跑堂 @21小跑堂

书接上回,这会来玩一玩ADC采集,中间遇到的问题、以及解决方面一并呈上。
一、首先通原理图、数据手册,找到自己需要的ADC端口,以及连接到的外部管脚
我这边选了ADC2的通道2,即ADC2_IN 2,对应的通道PC3
693776879dcf0848ee.png    570536879dd0e57abc.png    310756879dd29b15e1.png
二、IDE软件开始配置
debug配置、RCC配置就不在累赘了,如果不会,可以看我前面的测评内容
ADC2配置如下:
24586879b88495d1f.png    152196879b8b2a92e0.png
1、ADCs_Common_Settings (ADC模式设置)
     Mode     ADC_Mode_Independent   设置为独立模式
     独立模式模式下,每个ADC接口独立工作。
2、ADC_Settings  ADC参数设置
Resolution(分辨率)
ADC精度选择,目前选12位,这与最后你计算ADC实际电压值有关。

Gain Compensation  补偿,补偿

Scan Conversion Mode( 扫描模式 )  DISABLE
目前只用了一个通道的话,DISABLE就可以了(也只能DISABLE),如果使用了多个通道的话,会自动设置为ENABLE,即开启扫描模式。

End Of Conversion Selection(结束转换的选择)
有End of single conversion(EOC) 与 End of sequence of conversion(EOS)两种选择。
这两个事件会触发中断与DMA。
选择EOS,代表等所有通道转换完毕后,产生中断后将全部数据取出来,或者使用DMA将全部数据取出来

Low Power Auto Wait  (低功耗自动等待)
目前没用,禁止就行

Continuous Conversion Mode(连续转换模式)    DISABLE就行
ENABLE,即连续转换。连续转换直到所有的数据转换完成后才停止转换。
DISABLE,即单次转换。只转换一次数据就停止,要再次触发转换才可以进行转换

Discontinuous Conversion Mode(间断模式)    DISABLE

Overrun behaviour (溢出处理行为)
默认就好

Conversion Data Managerment Mode(转换数据管理模式)
默认就好

3、ADC Regular ConversionMode
Enable Regular Conversions (启用常规转换模式)    ENABLE
使能它才能采集各个通道上的模拟量

Enable Regular Oversamping(使能规则过采样)默认禁止

Oversamping Ratio(过采样率) 默认

Number OF Conversion(转换通道数)    1
用到几个通道就设置为几

External Trigger Conversion Soure(触发转换的外部来源)软件触发就好
①Regular Conversion launched by software (软件触发)
②Timer 1 Capture Compare 1 event (定时器1捕获比较事件1)
③Timer 1 Capture Compare 2 event(定时器1捕获比较事件2)
等等等等


External Trigger Conversion Edge(触发转换的外部沿)
如果选择定时器,就需要选择此项,是上升沿还是下降沿以及上升下降沿


Left Bit Shift(左移位数)不需要


4、ADC Injected Conversion Mode ( ADC注入转换模式)先不管

5、Analog Watchdog  先不管

DMA配置如下:
73556879c3c878dfc.png

NVIC配置如下:
669416879c412a0419.png 850276879c4270645a.png
配置好后,进行代码生成
三、代码调试
1、usart.c中增加如下代码
#include <stdio.h>
/* USER CODE BEGIN 1 */
#ifdef _GNUC_
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE

{

HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xFFFF);//阻塞方式打印

return ch;

}
/* USER CODE END 1 */


2、main.c中增加如下代码
#include <string.h>
#include <stdio.h>




  HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);    //AD校准





          HAL_ADC_Start(&hadc2);     //启动ADC转换
           HAL_ADC_PollForConversion(&hadc2, 50);   //等待转换完成,50为最大等待时间,单位为ms


           if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc2), HAL_ADC_STATE_REG_EOC))
           {
            ADC_Value = HAL_ADC_GetValue(&hadc2);   //获取AD值
            printf("21ic论坛ADC测试\r\n");
            printf("ADC2 Reading(码值) : %d \r\n",ADC_Value);
            printf("ADC2 Voltage(电压值) : %.1fv \r\n",ADC_Value*3.3f/4096);//除以4096是因为我们分辨率选的是12位,2的12次方即4096

          }
          HAL_Delay(1000);






四、踩坑
原来用过STM32F系列的,ADC校准是如下函数
HAL_ADCEx_Calibration_Start(&hadc2);    //AD校准
写入此代码,编译报错,../Core/Src/main.c:99:3: error: too few arguments to function 'HAL_ADCEx_Calibration_Start'
   99 |   HAL_ADCEx_Calibration_Start(&hadc2);    //AD校准


这就是经验主义害人

528626879d731bca72.png 403866879d75e31487.png
发现还需要添加个参数,于是度娘查询,代码如下,编译正常。


       HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);    //AD校准


将程序下载进入demo板,测量电压


串口数据如下:
342406879d92302ba3.png

返回查询代码,发现此处有点小问题,百度后得知是浮点数的问题。
572866879d94bba67e.png
解决措施如下:
936246879d9ee76521.png    545186879da1c0a75a.png
代码正常:
354206879da40137f6.png
重新下载即可

五、运行效果
388916879da9b2eda2.png
视频如下:



代码: 代码Core.rar (22.69 KB, 下载次数: 0)
致此,ADC实验结束。
这只是简单的ADC实现,如果觉得精度不够,还有在程序里面添加滤波算法。大家有兴趣可以自行添加。



LOVEEVER 发表于 2025-7-29 23:28 | 显示全部楼层
ADC采集、输出
 楼主| LiuDW091 发表于 2025-7-30 08:36 | 显示全部楼层
和下土 发表于 2025-7-31 21:38 | 显示全部楼层
学习学习
 楼主| LiuDW091 发表于 2025-8-7 22:00 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

178

帖子

0

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