STM32使用HAL库实现ADC单通道转换
STM32的ADC转换还是很强大的,它具有多个通道选择,这里我就不细说,不了解的可以自行百度,这里只是选取单通道,实现ADC转换。在文章开始之前,我说一下数据左对齐跟右对齐的差别,以前一直糊里糊涂的,记录下来以免以后自己忘记。12位二进制最大值为 0x0FFF 左对齐操作后的结果是 0xFFF0,右对齐后还是0x0FFF。反过来看 ,若寄存器里左对齐的数据值X (相当于实际数据*16,所以左对齐转换的值要/16才是实际的值),则X>>4才是实际的数据。而右对齐,则是数据保持不变,采集到多少就多少。至于是按左对齐保存到寄存器还是按照右对齐,就看你的配置里如何选了。
好了,下面就开始说明怎么用STM32CUBEMX实现ADC单通道转换吧。
利用中断模式
1、配置ADC引脚

2、开定时跟串口,定时器用来定时打开ADC转换,这样可以达到1S内控制ADC转换次数的目的,不过有个限制,这里样子控制ADC转换次数的话,如果采样次数多,配置ADC采样速度时一定要够 快,正常配置ADC的采样频率可以通过改变其采样速度来设置的,这里我是为了方便处理,就直接用定时器去开启了;而串口则是打印转换后的电压用的。

3、配置时钟

4、配置ADC设置
`
5、开启中断模式

6、串口配置默认即可

7、定时器配置,定时器配置的是进入定时器中断的频率,定时时间可以根据这个频率换算出来,这里定时器的频率 = 72M / 72 /1000 =1000Hz,所以定时时间为 T = 1S/f = 1S/1000 = 1ms,所以我这里配置定时为1ms。

8、基本配置我们完成了,现在我们生成工程用KEIL5打开

9、打开工程,我们现在进入代码部分
这里我们只需要重写定时器中断回调函数跟,ADC转换回调中断函数即可。在main文件里添加这下面这两个函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) //定时器中断回调
{
HAL_ADC_Start_IT(&hadc1); //定时器中断里面开启ADC中断转换,1ms开启一次采集
} void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) //ADC转换完成回调
{
HAL_ADC_Stop_IT(&hadc1); //关闭ADC
HAL_TIM_Base_Stop_IT(&htim3); //关闭定时器
AD_Value=HAL_ADC_GetValue(&hadc1); //获取ADC转换的值
Value_1=(float)(AD_Value*3.3/); //ADC换算,这里参考电压3.3V,12位的ADC满量程为2^12=4096,转换出来的单位是V
printf("%.4f\r\n",Value_2[j-]); //串口打印信息
HAL_TIM_Base_Start_IT(&htim3); //开启定时器
}
到这里就完成单通道ADC中断转换的所有步骤啦,通过串口助手实测转换结果误差为0.0008v。
至于串口查看信息打印输出重定向可以看我这篇文章:https://www.cnblogs.com/xingboy/p/9522940.html
不使用中断模式
不使用中断模式的情况下跟使用中断的类似的,首先配置的过程中不需要开启中断,至于定时器开不开看个人需要,想利用定时器定时采集的可以开,不想的不用开,其他的配置一样。生成代码后,在main文件的main函数中的while循环里添加下面代码:
/* USER CODE BEGIN 3 */
for(char n=;n<;n++)
{ //取22个值做滤波用
HAL_ADC_Start(&hadc2);
HAL_ADC_PollForConversion(&hadc2, ); //等待转换完成,第二个参数表示超时时间,单位ms
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc2), HAL_ADC_STATE_REG_EOC))
{
Value[n]=HAL_ADC_GetValue(&hadc2);
AD_Value += Value[n];
}
}
max=Value[];
min=Value[];
for(char n=;n<;n++)//取最大值、最小值
{
max=(Value[n]<max)?max:Value[n];
min=(min<Value[n])?min:Value[n];
}
printf("PC0 ADC : %.4f \r\n",(float)((AD_Value -max-min)/)*(3.1/));
AD_tr=(float)((AD_Value -max-min)/)*(3.1/); //这里我做了个去掉最大最小值后,取均值的软件滤波
AD_Value=;
这里面的一些变量就你们自己去定义了,我就不列出来了,实测误差在0.001v以内。
补充注意事项:
1、ADC初始化后要进行校准,使用下面函数校准,可以放在ADC初始化函数后面校准
HAL_ADCEx_Calibration_Start(&hadc2); //AD校准
2、传入ADC的电压不可以超过3.3V,就是不可以超过你的参考电压,不然结果不准,还有可能烧坏ADC引脚
使用DMA模式【转:http://www.stm32cube.com/article/37】
再次写写stm32cubemx中AD采集的问题,这次不用while里面的查询,也不用中断采样了,直接用DMA
先说下用DMA的好处:无论是中断采样还是查询采样,都需要在主程序中占用好多时间出来,嗯,你可以这样理解
那种采样都需要调用HAL_ADC_GetValue()这个函数,,,就是要取得转换后的值,中断还好点,要是查询的话,有可能会丢失数据啊. 用dma就可以避免了
DMA用的事总线时间,无线cpu干预,额,这种说法貌似有点问题.管它呢
在AD转换结束的时候自动连接你准备存取的变量的地址,数据一步到位.额,省了多少事..
使用stm32cubemx对AD的配置

然后对她的DMA配置,并开启DMA的中断

然后生成代码吧
打开main.c文件,在这个地方添加代码
/[i] USER CODE BEGIN [/i]/
__IO uint16_t uhADCxConvertedValue = ;
/[i] USER CODE END [/i]/
在main()函数里添加
/[i] USER CODE BEGIN [/i]/
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&uhADCxConvertedValue, ); /[i] USER CODE END [/i]/
意思是开启dma传输,传送一个字的数据到uhADCxConvertedValue这个变量里面
然后再文件的末尾处添加
/[i] USER CODE BEGIN [/i]/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
/[i] Turn LED1 on: Transfer process is correct [/i]/
// BSP_LED_On(LED1);
HAL_GPIO_WritePin (GPIOF,GPIO_PIN_6,GPIO_PIN_SET );
}
/[i] USER CODE END [/i]/
意思是AD转换完成调用这个函数,函数里使能led
也许,你会问,为毛是HAL_ADC_ConvCpltCallback()这个函数啊,这个函数不是当开启AD的中断的时候才调用的吗?
嗯,对,这个函数是这样的,但是你仔细去分析下开启AD的DMA中断函数里面,就会发现这个函数也在啊
如下图.进入HAL_ADC_Start_DMA函数里面,看到

在进入到图中的ADC_DMAConvCplt函数里面看到

OK,疑问解决,
以后用到AD就可以直接调用这个CALL了,不要纠结了.
STM32使用HAL库实现ADC单通道转换的更多相关文章
- STM32 之 HAL库(固件库) _
1 STM32的三种开发方式 通常新手在入门STM32的时候,首先都要先选择一种要用的开发方式,不同的开发方式会导致你编程的架构是完全不一样的.一般大多数都会选用标准库和HAL库,而极少部分人会通过直 ...
- STM32 之 HAL库(固件库)
1 STM32的三种开发方式 通常新手在入门STM32的时候,首先都要先选择一种要用的开发方式,不同的开发方式会导致你编程的架构是完全不一样的.一般大多数都会选用标准库和HAL库,而极少部分人会通过直 ...
- (4)STM32使用HAL库实现串口通讯——理论讲解
一.查询模式 1. 二.中断模式 1.中断接收. 1.1先看中断接收的流程(以 USART2 为例) 在启动文件中找到中断向量 USART2_IRQHandler 找到USART2_IRQHandle ...
- (2)STM32使用HAL库操作外部中断——理论讲解
1.中断触发过程 对主程序压栈--把中断服务函数的地址写入到程序计数器(PC)--执行中断服务函数 2.中断向量表 中断服务函数的地址在STM32的手册上的中断向量表中(如下是一部分): 如上表所示, ...
- STM32 关于HAL库硬件SPI要注意的问题总结
利用STM32CUbeMx编写程序,大大方便了开发,最近做的项目利用到了 STM32CUbeMx的硬件SP,这里对SPI的使用做一个总结. HAL库里的硬件SPI主要有以下几个库函数: /* hspi ...
- STM32之HAL库、标准外设库、LL库(STM32 Embedded Software)-(转载)
STM32 Embedded Software 工作以来一直使用ST的STM32系列芯片,ST为开发者提供了非常方便的开发库.到目前为止,有标准外设库(STD库).HAL库.LL库 三种.前两者都是 ...
- STM32基于HAL库通过DMA读写SDIO
通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...
- (1)STM32使用HAL库操作GPIO
一 初始化GPIO 使用HAL库的优点在于不用手动添加初始化的代码了,CubeMX会根据软件设置自动生成. 自动生成的HAL库GPIO初始化代码: static void MX_GPIO_Init( ...
- 如何使用keil5将stm32的hal库编译成lib文件——F1版本
hal库中keil5中编译的速度是比较慢的,相同情况下,每次都要编译的时候,比标准库是要慢很多的,因此就hal库编译成lib文件是一种加快编译速度的方法,当然也有其自身的缺点.一.步骤1.使用cube ...
随机推荐
- 流媒体播放器VLC SDL
http://www.cnblogs.com/lihuixian001/archive/2013/03/15/2957103.html https://wiki.videolan.org/Win32C ...
- git-osc自己定义控件之:CircleImageView
git-osc自己定义控件之:CircleImageView 一.CircleImageView的使用 在项目中能够发现,用户的头像都是圆形的.感觉非常好奇,昨天最终发现了,原来是自定了一个Image ...
- 数据挖掘算法学习(一)K-Means算法
博主近期实习開始接触数据挖掘,将学习笔记分享给大家.眼下用的软件是weka.下篇文章会着重解说. 转载请附上链接http://blog.csdn.net/iemyxie/article/details ...
- 程序猿爱情表白专用html5动画网页的代码
程序猿爱情表白专用html5动画网页的代码 下载地址:源代码 程序员表白专用的html5动画特效网页,真的挺羡慕创作者的水平,有这水平能够把爱表白给想表白的人,不要以为那些鲜花是用 的图片.你会发如今 ...
- JavaScript 获取小数任一小数点后的位数的小数
用Javascript取float型小数点后两位,例22.127456取成22.13,怎样做? 1.这样的方法最不推荐: function get(){ var s = 22.127456 + &qu ...
- Server Tomcat v8.0 Server at localhost was unable to start within 45 seconds. If the server requires
Server Tomcat v8.0 Server at localhost was unable to start within 45 seconds. If the server requires ...
- 【MySQL】MySQL删除匿名用户,保证登录安全
博客地址已迁往 www.virtclouds.com 原文地址 http://www.virtclouds.com/538.html 很多MySQL程序都会带有匿名登录的功能. 在刚刚安装完MySQL ...
- Oracle回滚段的概念,用法和规划及问题的解决
回滚段概述 回滚段用于存放数据修改之前的值(包括数据修改之前的位置和值).回滚段的头部包含正在使用的该回滚段事务的信息.一个事务只能使用一个回滚段来存放它的回滚信息,而一个回滚段可以存放多个事务的回 ...
- weblogic状态监控脚本
echo "======================================welcome============================================ ...
- Spark任务调度
不多说,直接上干货! Spark任务调度 DAGScheduler 构建Stage—碰到shuffle就split 记录哪个RDD 或者Stage 输出被物化 重新提交shuffle 输出丢失的sta ...