STM32+HAL库ADC采样(采用内部基准电压)

本文介绍了STM32L476微控制器中如何利用内部基准电压VDDA和VREFINT_CAL进行实时测量,包括ADC的配置、单通道和多通道DMA方式的应用,以及在使用DMA时的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        当我们采用内部基准电压时,首先应了解下内部基准电压的用法,根据STM32L476参考手册我们得知:

解析:

VDDA:实际电压参考值,由上式计算得出,用来计算我们需要的采样电压值,下边会用到;

VREFINT_CAL:内部电压参考校准值,每个芯片都不一样,例如我的STM32L476则存在0x1FFF75AA-----0x1FFF75AB中,我们可以读出来:

#define VREFINT_CAL						(uint16_t)(*(__I uint16_t *)(0x1FFF75AA))

在数据手册中我们可以查到校准值的存储位置,如下图:

VERFINT_DATA:ADC转换后的实际VREFINT输出值,我们可以通过ADC的通道17读出来,该值在1.2V左右:

到这里我们就可以得到实时的参考电压值VDDA,既然确定了VDDA的值,我们便可以通过下式来计算我们实际测量的电压值:

### 使用STM32 HAL实现ADC多通道电压采集 为了通过STM32 HAL实现多个ADC通道的同时采样,配置过程涉及初始化ADC模块、设置所需的参数以及利用DMA传输数据。下面提供了一个完整的示例来展示如何执行这些操作。 #### 初始化ADC并启用DMA模式 在`MX_ADC1_Init()`函数内定义好ADC的相关属性之后,在主函数中进一步设定DMA请求映射到特定的中断事件,并指定要读取的数据缓冲区地址和长度: ```c /* 定义全局变量用于存储ADC结果 */ #define BUFFER_SIZE 8 // 假设有两个通道,则需两倍空间保存每轮的结果 uint16_t AdcConvertedValues[BUFFER_SIZE]; // 配置ADC通道列表 static void MX_ADC1_Init(void){ ... hadc1.Init.ScanConvMode = ENABLE; hadc1.ChannelConf[0].Channel = ADC_CHANNEL_4; // Channel 4 hadc1.ChannelConf[0].Rank = 1; hadc1.ChannelConf[0].SamplingTime = ADC_SAMPLETIME_7CYCLES_5; hadc1.ChannelConf[1].Channel = ADC_CHANNEL_5; // Channel 5 hadc1.ChannelConf[1].Rank = 2; hadc1.ChannelConf[1].SamplingTime = ADC_SAMPLETIME_7CYCLES_5; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } } ``` 上述代码片段展示了如何为ADC配置扫描模式(允许连续处理多个输入),并将两个不同的模拟信号源连接至相应的硬件引脚上[^1]。 #### 启动ADC转换并与DMA关联 一旦完成了必要的初始化工作,就可以调用`HAL_ADC_Start_DMA()`方法开始实际的数据收集流程了。此命令会触发一次性的批量读数动作,并自动把获得的信息传送到预先分配好的内存区域里去: ```c if (HAL_ADC_Start_DMA(&hadc1, (uint32_t*)AdcConvertedValues, BUFFER_SIZE / sizeof(uint16_t)) != HAL_OK) { Error_Handler(); } while (1) { // 主循环体可放置其他任务逻辑... } ``` 这里需要注意的是,当采用DMA方式进行大批量快速传输时,必须确保所选定时器间隔足够长以便让整个序列顺利完成;否则可能导致未完成的任务堆积甚至系统崩溃等问题发生。 #### 处理接收到的数据 最后一步是在适当的地方加入回调机制,用来响应已完成的DMA事务。这可以通过覆盖默认行为或者注册自定义处理器的方式来达成目的。每当一批新的测量值被成功接收后,就会触发对应的事件句柄来进行后续分析或可视化呈现等工作: ```c void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc) { // 当一半数量的样本已被传送完毕时调用该函数 } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { // 所有预定数目内的样本均已经过DMA搬运过来以后才会到达此处 for(int i=0;i<BUFFER_SIZE/sizeof(uint16_t);i++){ float voltage = ((float)(AdcConvertedValues[i]) * 3.3f)/4096.0f; printf("Channel %d Voltage Value:%.4fV\r\n", i+1,voltage); } } ``` 以上就是基于STM32 HAL构建一个多路同步采样的简单实例说明[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值