STM32 ADC详细篇(基于HAL库)
一、基础认识
ADC就是模数转换,即将模拟量转换为数字量

l 分辨率,读出的数据的长度,如8位就是最大值为255的意思,即范围[0,255],12位就是最大值为4096,即范围[0,4096]
l 通道,ADC输入引脚,通常一个ADC控制器控制多个通道,如果需要多通道的话,就得进行每个通道扫描了。
l ADC DMA功能,DMA是内存到内存或内存到存储的直接映射,数据不用经过单片机处理器而直接由硬件进行数据的传递。方便直接将读取的ADC值放到内存变量中。
ADC芯片通常有正参考电压和负参考电压,通常正参考电压连接到VCC,负参考电压连接到GND
在STM32中ADC还可以用于采集芯片的温度、RTC供电电压
一般来说,采样时间越长,结果越准确,采样时间要更具ADC的时钟周期和ADC通道设置的采样周期计算,如STM32F103C8T6配置的ADC时钟周期为12MHZ,采样周期配置的是239.5 Cycles。
ADC的转换方式:
l 单次转换,一次只转换一个通道
l 连续转换,转换完成一个通道后立即自动执行下一个通道的转换
l 扫描模式,开启一次后,自动的连续读取多个通道
ADC的三种工作方式:
l 阻塞模式(查询模式)
l 中断模式
l DMA模式
二、cubemx基础配置
使用外部晶振

使用SWD调试

时钟配置

ADC时钟12MHZ,采样周期

二、 单个通道,查询阻塞模式
缺点:占用CPU的使用率
流程:
- 启动ADC
- 等待EOC标志位
- 读取寄存器数据
选择引脚,选择未ADC1的通道0和设置为模拟通道

需要配置的功能,看门狗应该是可以设置上限下限的值,以产生中断报警。


独立模式,不可选

Data Alignment : 对齐模式,可选左对齐和右对齐
Conversion Mode:扫描转换模式是否开启
Continuous Conversion Mode:连续转换模式是否开启
Discontinuous Conversion Mode:不连续转换模式 是否开启

Enable Regular Conversions:是否使能转换
Number Of Conversion:转换的通道数
External Trigger Conversion Source:触发开始转换事件选择:
可选由软件或定时器触发采集

Rank 编号1,如果有多个通道的话就有多个Rank,每个Rank有如下参数配置:
Channel:所选择的通道
Sampling Time:采用周期,一个周期的时间要看ADC的时钟,如当前时钟图里设置的是12MHZ。这个时间设置越长采样越准确,但也相对要占用更长的采样时间。但不管再长,这采集都是微秒级别的。
转换函数
uint16_t ADC_Value=0;
uint16_t dong_get_adc(){
//开启ADC1
HAL_ADC_Start(&hadc1);
//等待ADC转换完成,超时为100ms
HAL_ADC_PollForConversion(&hadc1,100);
//判断ADC是否转换成功
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC)){
//读取值
return HAL_ADC_GetValue(&hadc1);
}
return 0;
}
调用
ADC_Value=dong_get_adc();
转换的值为0-4096,对应0-3.3V
四、 三通道,查询阻塞模式
选择引脚

独立模式

数据右读取,如果是多通道,则必须开启扫描模式(scan conversion mode)和不连续采集模式,最后一个1表示每个通道为一组

设置为3个通道
采用软件触发方式启动采集
3个通道各自的参数设置

转换函数
uint16_t ADC_Value[3]={0};
uint16_t dong_get_adc(){
//开启ADC1
HAL_ADC_Start(&hadc1);
//等待ADC转换完成,超时为100ms
HAL_ADC_PollForConversion(&hadc1,100);
//判断ADC是否转换成功
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC)){
//读取值
return HAL_ADC_GetValue(&hadc1);
}
return 0;
}
使用
for(uint8_t i=0;i<3;i++){
//分别存放通道1、2、3的ADC值
ADC_Value[i]=dong_get_adc();
}
五、 ADC中断方式多通道采集
这个可以正确读出数据,但是顺序是乱的,所以谨慎使用
第一步:启动ADC,使能中断
第二步:等待中断触发
第三步:在中断中读取寄存器数据
引脚设置

使能了连续转换

开启中断

把优先级设置低一点

两个函数
#define ADC_MAX_NUM 3*5 //3组ADC,每组最多存储5个值
uint16_t ADC_Values[ADC_MAX_NUM]={0};
uint16_t adc_value_flg=0; //启动函数,需要在main中调用一次
void dong_start_adc(){
//开启ADC1,使能中断
HAL_ADC_Start_IT(&hadc1);
} //ADC转换完成自动调用函数
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){ //获取值并存储
ADC_Values[adc_value_flg++]=HAL_ADC_GetValue(hadc); if(adc_value_flg==ADC_MAX_NUM)
{
adc_value_flg=0;//清零下标
} }
六、ADC DMA方式多通道采集
步骤:
l 启动ADC
l 配置DMA缓冲区
l 读取缓冲区数据
引脚选择

基础配置
开启连续转换模式

关闭中断

DMA配置
mode:模式
Normal:正常模式,当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次
Circular: 循环模式,传输完成后又重新开始继续传输,不断循环永不停止
data width:数据宽度
byte:字节,通用8位,与u8相同
word:字长,与硬件的位数相同,STM32是32位,所以对应是u32
Half Word:半个字长,所以对应是u16
Memory打钩表示存储ADC值的内存地址(数组)会自增

代码也很简单,只要在main中调用一次启动函数即可
#define ADC_MAX_NUM 3*5 //3组ADC,每组最多存储5个值
uint16_t ADC_Values[ADC_MAX_NUM]={0};
//启动函数,需要在main中调用一次
void dong_start_adc(){
//启动DMA
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC_Values,ADC_MAX_NUM);
}
测试发现,数据还是很稳的

STM32 ADC详细篇(基于HAL库)的更多相关文章
- STM32 GPIO输入输出(基于HAL库)
一.基础认识 GPIO全名为General Purpose Input Output,即通用输入输出.有时候简称为"IO口".通用,说明它是常见的.输入输出,就是说既能当输入口使用 ...
- Keil MDK STM32系列(七) STM32F4基于HAL的PWM和定时器
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- 【GMT43智能液晶模块】基于HAL库的SDRAM和LCD驱动例程(MDK工程&CubeMX工程)
说明: 1.该工程基于HAL库实现动态存储器SDRAM驱动以及液晶控制器LCD驱动. 2.工程通过STM32CubeMX(Version 4.22.0)配置生成,可直接打开进行配置. 3.KEIL M ...
- STM32基于HAL库通过DMA读写SDIO
通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...
- STM32串口接收中断——基于HAL库
写在前面 最近需要使用一款STM32L4系列的芯片进行开发,需要学习使用HAL库.在进行串口中断使用的时候遇到了一些小麻烦,写下解决方案供大家参考. 1.UART相关的头文件引用错误 由于本人直接使用 ...
- 基于HAL库的STM32的DSP库详解(附FFT应用)
1 . 建立工程,生成代码时选择包含所有库. 2. 打开 option for target 选择 Target 标签,在code generatio中,将floating point hardw ...
- STM32标准外设库、 HAL库、LL库
工作以来一直使用ST的STM32系列芯片,ST为开发者提供了非常方便的开发库.到目前为止,有标准外设库(STD库).HAL库.LL库 三种.前两者都是常用的库,后面的LL库是ST最近才添加,目前支持的 ...
- Keil MDK STM32系列(八) STM32F4基于HAL的PWM和定时器输出音频
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- STM32F072从零配置工程-基于HAL库的串口UART中断配置
先上一个采用串口直接传输的Demo: 此处的思路是完全采用HAL库来实现的,核心是运用HAL_UART_Transmit_IT和HAL_UART_Receive_IT两个函数来实现的,可以作为一个De ...
随机推荐
- [Golang]-7 定时器和打点器
目录 定时器 打点器 After()方法 我们常常需要在未来某个时刻运行 Go 代码,或者在某段时间间隔内重复运行. Go 的内置 定时器 和 打点器 特性让这些很容易实现. 定时器 type Tim ...
- 创建AVL树,插入,删除,输出Kth Min
https://github.com/TouwaErioH/subjects/tree/master/C%2B%2B/PA2 没有考虑重复键,可以在结构体内加一个int times. 没有考虑删除不存 ...
- spring-cloud-netflix-eureka-client
服务注册中心eureka-server已经搭好,我们开始编写一个eureka-client,并提供一个hello服务 一.新建module,选择对应的springcloud模块,pom.xml如下: ...
- HDU 4628 Pieces(状压DP)题解
题意:n个字母,每次可以删掉一组非连续回文,问你最少删几次 思路:把所有回文找出来,然后状压DP 代码: #include<set> #include<map> #includ ...
- js camelCase formatter
js camelCase formatter 驼峰命名 转换器 'A'.charCodeAt(); // 65 'Z'.charCodeAt(); // 90 'a'.charCodeAt(); // ...
- OTA development
OTA development OTA update OTA Over the Air / 无线下载 https://en.wikipedia.org/wiki/Over-the-air_progra ...
- jest & code testing
jest jest & code testing https://jestjs.io/zh-Hans/ 24.9 https://jestjs.io/docs/zh-Hans/getting- ...
- Netty & websockets
Netty & websockets Netty is a non-blocking I/O client-server framework for the development of Ja ...
- TypeScript & global.d.ts
TypeScript & global.d.ts https://www.typescriptlang.org/docs/handbook/declaration-files/template ...
- taro swiper & scroll tabs
taro swiper & scroll tabs https://taro-docs.jd.com/taro/docs/components/viewContainer/swiper.htm ...