概述
14.1 认识WB32的ADC
WB32有1个ADC,精度为12位,这个ADC有16个外部通道,分别对应着16个不同的IO口,具体可见WB32数据手册中管脚功能描述表。
ADC的输入电压范围为0-3.3V,若输入的电压过高或过低,可以设计一个外部调理电路,把需要转换的输入电压降低或升高到0-3.3V,这样WB32的ADC就可以测量了。
确定好输入电压后,即可通过输入通道检测输入电压了,但我们还需注意这16个外部通道在转换时还分为规则通道和注入通道;
规则通道为我们常用的通道,而注入通道是一种在规则通道转换时强行插入进行转换的通道,也就是说当规则通道转换过程中有注入通道插队,那么就先转换完注入通道,再继续转换规则通道;这和我们的中断有相似之处;
注入通道只会在有规则通道的时候才会存在。
此外,想要用好ADC还需要了解转换顺序、触发源、转换时间、中断(三种情况:转换完成中断、模拟看门狗中断、DMA请求)和电压转换等,老样子,在例程中带大家一起学习。
14.2 ADC中断转换实验
本节使用固件库ADC中ADC_Interrupt工程,讲解如何配置ADC独立模式单通道采集,单通道采集适用AD转换完成中断,在中断服务函数中读取数据(单通道也可通过DMA的方式来读取,本例主要为展示此方法,在日常使用中可多用DMA来完成ADC采集,使用DMA传输数值的方式不会影响MCU正在运行的程序)。
14.2.1 预处理文件、宏定义文件与函数声明
#include "wb32f10x.h"
#include <stdio.h> //若使用Printf或Scanf函数,必须包含此头文件
#include "bsp_uart1.h" //使用UART1,必须包含其对应头文件
ADC_InitTypeDef ADC_InitStructure; //将ADC_InitTypeDef宏定义为ADC_InitStructure
void NVIC_Configuration(void); //中断设置函数,由用户自定义
本节使用到WB32的ADC,就必须配置ADC初始化结构体成员,宏定义名称大家已经见到很多了,请务必习惯这种写法。
14.2.2 ADC结构体配置及其相关配置
这里笔者将有关ADC输出的所有代码全部在这里进行注释。
/* 初始化UART1 */
uart1_init(72000000, 115200);
/* 使能ADC, GPIOA 时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BMX1 |RCC_APB1Periph_ADC |RCC_APB1Periph_GPIOA, ENABLE);
/* 设置PA3 (ADC Channel3) 为模拟模式 */
GPIO_Init(GPIOA, GPIO_Pin_3, GPIO_MODE_ANA);
/* 中断配置函数,由用户自定义 ------------------------------------------------------*/
NVIC_Configuration();
/* ADC 模拟模式相关配置函数,了解有如下配置即可---------------------------------------*/
PWR_UnlockANA();
ANCTL_SARADCCmd(ENABLE);
PWR_LockANA();
/* ADC结构体成员配置 */
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //ADC扫描模式选择,单通道为DISABLE,多通道为ENABLE
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //ADC单次转换或者连续转换选择,这里DISABLE配置为单次转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //ADC转换触发信号选择,一般设置None为软件自动触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //转换结果对齐模式,一般选择右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //AD转换通道树木,根据实际设置,本次为单通道,即为1
ADC_Init(&ADC_InitStructure); //初始化ADC初始化结构体成员
/* ADC规则通道设置。这里配置为通道三、第一个转换,此采样时间为7.5个时钟周期 */
ADC_RegularChannelConfig(ADC_Channel_3, 1, ADC_SampleTime_7Cycles5);
/* ADC转换结束产生中断,在中断服务函数中读取转换值 */
ADC_ITConfig(ADC_IT_EOC, ENABLE);
/* 使能ADC外部触发转换 */
ADC_ExternalTrigConvCmd(ENABLE);
/* 使能ADC */
ADC_Cmd(ENABLE);
/* 开始ADC校准 */
ADC_StartCalibration();
/* 检查校准是否完成 */
while(ADC_GetCalibrationStatus());
/* 使能ADC复位校准寄存器 */
ADC_ResetCalibration();
/* 检查ADC校准寄存器是否复位完成 */
while(ADC_GetResetCalibrationStatus());
/* 没有使用外部触发,故使用软件触发ADC转换 */
ADC_SoftwareStartConvCmd(ENABLE);
在学习时大家看到这么多的代码是很头疼的,但实际上在WB32标准库下,这些代码都是有迹可循的,需要大家不断的学习和总结。
14.2.3 ADC中断服务函数
在上部分的程序中,我们看到了一条代码ADC_ITConfig(ADC_IT_EOC, ENABLE);
这条代码的注释已经标明了其功能,即ADC转换完成后,硬件会将ADC_IT_EOC这个中断标志位自动置1,告诉WB32可以执行对应的中断服务函数了:
void ADC_IRQHandler(void)
{
if(ADC_GetITStatus(ADC_IT_EOC) != RESET) //判断ADC是否转换完成
{
ADC_ClearITPendingBit(ADC_IT_EOC); //转换完成后清除该中断位
printf("rADC Channel 3: %-5d", ADC_GetADValue(ADC->DR)); //通过ADC_GetADValue这个函数将得到的数值打印出来
}
}
14.2.3 中断初始化结构体成员配置
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置并使能ADC中断 */
NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
此结构体大家务必熟悉,这个结构体在使用到中断时必须配置。
14.3 实验结果
代码编译烧录到WB32中,连接好串口,打开串口调试助手。
首先在PA3浮空时按下复位按键,接着将PA3接入GND时按下复位按键,最后将PA3接入3.3V时按下复位按键;这三次的得到的数值如图显示:
我们可以看到PA3浮空时ADC读到的数值为52,PA3接入GND时ADC读到的数值为52,PA3接入3.3V时ADC读到的数值为4093。
解释一下,因为ADC是12位的,那么12位满量程对应的就是3.3V,12位满量程对应的数字值为2^12(即4096),数值0对应的就是0V。
注意:
1)我们读出的数值并没有很完美的达到0与4096,这是由于误差和芯片的固有设计决定的,可以忽略。
2)在引脚浮空时,根据硬件设计的不同有可能读出不同的值,属于正常情况。
14.4 补充实验与结果
本例程读出的数据不太直观,为此我们新建一个变量用来存放ADC读取的值,并将此值通过运算转换为电压进行显示:
仅需修改ADC中断服务函数部分:
void ADC_IRQHandler(void)
{
float ADC_V_Value = 0;
if(ADC_GetITStatus(ADC_IT_EOC) != RESET)
{
ADC_ClearITPendingBit(ADC_IT_EOC);
ADC_V_Value = ADC_GetADValue(ADC->DR);
printf("rADC Channel 3: %5.0f rn", ADC_V_Value);
printf("rADC Channel 3 Voltage: %1.1f Vrn",(3.3 * ADC_V_Value) / 4096);
}
}
实验结果如下:
还是按照先测浮空,接着测GND,最后测3.3V的顺序;
可以看到,除了测得的浮空值略有不同(不影响结果),PA3测得的GND的电压值与3.3V的电压值都是十分准确的。
注意:此例程可以测试0-3.3V内的电压值,若超过3.3V,例如需测量的范围为0-10V,则需要通过外部调理电路将其降压为0-3.3V。
最后
以上就是听话樱桃为你收集整理的【WB32库开发】第14章 (上) ADC电压采集——单通道采集14.1 认识WB32的ADC14.2 ADC中断转换实验14.2.1 预处理文件、宏定义文件与函数声明14.2.2 ADC结构体配置及其相关配置14.2.3 ADC中断服务函数14.2.3 中断初始化结构体成员配置14.3 实验结果14.4 补充实验与结果的全部内容,希望文章能够帮你解决【WB32库开发】第14章 (上) ADC电压采集——单通道采集14.1 认识WB32的ADC14.2 ADC中断转换实验14.2.1 预处理文件、宏定义文件与函数声明14.2.2 ADC结构体配置及其相关配置14.2.3 ADC中断服务函数14.2.3 中断初始化结构体成员配置14.3 实验结果14.4 补充实验与结果所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复