小壁虎EFM32之ADC 采集电压
前言
最近在学习小壁虎EFM32芯片的使用,需要用ADC采集电压,学习之中,遇到一些小问题和需要注意的地方,现将其记录下来,避免以后自己再次踩坑和往后可以学而时习之;好了,进入正题。
代码
主函数:
int main (void)
{ CHIP_Init();CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);/* * 开启LE时钟,只要使用到低频外设,都需要开启该时钟 */CMU_ClockEnable(cmuClock_CORELE, true); CMU_ClockEnable(cmuClock_GPIO, true);adcInit(); /* ADC初始化 */
// EMU_EnterEM1(); /* 进入EM1等待ADC转换结束 */ while(1){Voltage_Value = GetulVoltage_Value(); //获取电池电压}
}
ADC初始化函数:
void adcInit (void)
{CMU_ClockEnable(cmuClock_ADC0, true); /* 使能ADC模块时钟 */ADC_Init_TypeDef tAdcInit = {.ovsRateSel = adcOvsRateSel2, /* ADC过采样配置 */.lpfMode = adcLPFilterBypass, /* 旁路输入滤波RC电路 */.warmUpMode = adcWarmupNormal, /* 正常预热模式 */.timebase = ADC_TimebaseCalc(0), /* 基时间配置 */.prescale = ADC_PrescaleCalc(7000000, 0), /* ADC时钟分频配置 */.tailgate = false /* 不使能Tailgate */};ADC_InitSingle_TypeDef tSingleInit = {.prsSel = adcPRSSELCh0, /* 选择PRS通道0 */.acqTime = adcAcqTime16, /* 配置采集时间为16周期 */.reference = adcRef2V5, /* 使用VDD参考电压 */.resolution = adcRes12Bit, /* 使用12位分辨率 */.input = adcSingleInpCh5, /* 选择ADC通道 */.diff = false, /* 不采用差分采集模式 */.prsEnable = false, /* 禁能PRS输入 */.leftAdjust = false, /* 使用右对准 */.rep = false /* 不使用连续转换 */};ADC_Init(ADC0, &tAdcInit);ADC_InitSingle(ADC0, &tSingleInit); /* 初始化ADC单次转换 *//** 使能单次采集完成中断*/ADC_IntEnable(ADC0, ADC_IF_SINGLE);NVIC_EnableIRQ(ADC0_IRQn);
}
需要注意地方和修改的地方:
1、参考基准电压:
.reference = adcRef2V5, / 使用VDD参考电压 /
需要更改参考电压,如果你使用蓄电池供电,一般不采用VDD作为参考电压,因为随着电池的使用,电压会降低,导致采集到的电压数据不准确;采用内部的电压作为基准电压最为稳妥,我选用了内部电压2.5V,EFM32也提供了几种参考电压供你选择,如下:
typedef enum
{ /** Internal 1.25V reference. */adcRef1V25 = _ADC_SINGLECTRL_REF_1V25,/** Internal 2.5V reference. */adcRef2V5 = _ADC_SINGLECTRL_REF_2V5,/** Buffered VDD. */adcRefVDD = _ADC_SINGLECTRL_REF_VDD,/** Internal differential 5V reference. */adcRef5VDIFF = _ADC_SINGLECTRL_REF_5VDIFF,/** Single ended ext. ref. from pin 6. */adcRefExtSingle = _ADC_SINGLECTRL_REF_EXTSINGLE,/** Differential ext. ref. from pin 6 and 7. */adcRef2xExtDiff = _ADC_SINGLECTRL_REF_2XEXTDIFF,/** Unbuffered 2xVDD. */adcRef2xVDD = _ADC_SINGLECTRL_REF_2XVDD
} ADC_Ref_TypeDef;
2、ADC通道
.input = adcSingleInpCh5, / 选择ADC通道 /
根据你所选用GPIO口,确定通道,可参考芯片规格书PIN脚部分说明。
typedef enum
{/* Differential mode disabled */adcSingleInpCh0 = _ADC_SINGLECTRL_INPUTSEL_CH0, /**< Channel 0. */adcSingleInpCh1 = _ADC_SINGLECTRL_INPUTSEL_CH1, /**< Channel 1. */adcSingleInpCh2 = _ADC_SINGLECTRL_INPUTSEL_CH2, /**< Channel 2. */adcSingleInpCh3 = _ADC_SINGLECTRL_INPUTSEL_CH3, /**< Channel 3. */adcSingleInpCh4 = _ADC_SINGLECTRL_INPUTSEL_CH4, /**< Channel 4. */adcSingleInpCh5 = _ADC_SINGLECTRL_INPUTSEL_CH5, /**< Channel 5. */adcSingleInpCh6 = _ADC_SINGLECTRL_INPUTSEL_CH6, /**< Channel 6. */adcSingleInpCh7 = _ADC_SINGLECTRL_INPUTSEL_CH7, /**< Channel 7. */adcSingleInpTemp = _ADC_SINGLECTRL_INPUTSEL_TEMP, /**< Temperature reference. */adcSingleInpVDDDiv3 = _ADC_SINGLECTRL_INPUTSEL_VDDDIV3, /**< VDD divided by 3. */adcSingleInpVDD = _ADC_SINGLECTRL_INPUTSEL_VDD, /**< VDD. */adcSingleInpVSS = _ADC_SINGLECTRL_INPUTSEL_VSS, /**< VSS. */adcSingleInpVrefDiv2 = _ADC_SINGLECTRL_INPUTSEL_VREFDIV2, /**< Vref divided by 2. */adcSingleInpDACOut0 = _ADC_SINGLECTRL_INPUTSEL_DAC0OUT0, /**< DAC output 0. */adcSingleInpDACOut1 = _ADC_SINGLECTRL_INPUTSEL_DAC0OUT1, /**< DAC output 1. *//* TBD: Use define when available */adcSingleInpATEST = 15, /**< ATEST. *//* Differential mode enabled */adcSingleInpCh0Ch1 = _ADC_SINGLECTRL_INPUTSEL_CH0CH1, /**< Positive Ch0, negative Ch1. */adcSingleInpCh2Ch3 = _ADC_SINGLECTRL_INPUTSEL_CH2CH3, /**< Positive Ch2, negative Ch3. */adcSingleInpCh4Ch5 = _ADC_SINGLECTRL_INPUTSEL_CH4CH5, /**< Positive Ch4, negative Ch5. */adcSingleInpCh6Ch7 = _ADC_SINGLECTRL_INPUTSEL_CH6CH7, /**< Positive Ch6, negative Ch7. *//* TBD: Use define when available */adcSingleInpDiff0 = 4 /**< Differential 0. */
} ADC_SingleInput_TypeDef;
3、ADC采集电压
uint16_t GetulVoltage_Value(void)
{ADC_Start(ADC0, adcStartSingle); /* 启动单次转换 */EMU_EnterEM1(); /* 进入EM1等待ADC转换结束 */ ulVoltage = ADC_DataSingleGet(ADC0) * 22300 / 4095; /* 计算采集到的电压值 */return (ulVoltage);
}
需要注意的地方:
1、ulVoltage = ADC_DataSingleGet(ADC0) * 22300 / 4095;
“22300”怎样得到的?
采集电压图
电路图使用了串联分压,电压计算公式:R2/(R1+R2)*参考电压
R2:3.3M
R1:390K
参考电压:2.5V
完成以上的操作就可以正常的读取到电池电压了。
总结
本次记录和分享到此结束,其实ADC采集电压是平时最常用的一种模拟量转换,没有难度,初学者注意细节便能熟练灵活的使用到自己代码和电路之中。
完整函数:
#include "efm32.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_adc.h"
#include "em_lcd.h"
#include "em_chip.h"
#include "em_gpio.h"
#include "system.h"
#include "segmentlcd.h"extern void adcInit(void);
uint16_t ulVoltage;
uint16_t Voltage_Value = 0;uint16_t GetulVoltage_Value(void)
{ADC_Start(ADC0, adcStartSingle); /* 启动单次转换 */EMU_EnterEM1(); /* 进入EM1等待ADC转换结束 */ ulVoltage = ADC_DataSingleGet(ADC0) * 22300 / 4095; /* 计算采集到的电压值 */return (ulVoltage);
}
int main (void)
{ CHIP_Init();CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO);/* * 开启LE时钟,只要使用到低频外设,都需要开启该时钟 */CMU_ClockEnable(cmuClock_CORELE, true); CMU_ClockEnable(cmuClock_GPIO, true);adcInit(); /* ADC初始化 */
// EMU_EnterEM1(); /* 进入EM1等待ADC转换结束 */ while(1){Voltage_Value = GetulVoltage_Value(); //获取电池电压}
}
void adcInit (void)
{CMU_ClockEnable(cmuClock_ADC0, true); /* 使能ADC模块时钟 */ADC_Init_TypeDef tAdcInit = {.ovsRateSel = adcOvsRateSel2, /* ADC过采样配置 */.lpfMode = adcLPFilterBypass, /* 旁路输入滤波RC电路 */.warmUpMode = adcWarmupNormal, /* 正常预热模式 */.timebase = ADC_TimebaseCalc(0), /* 基时间配置 */.prescale = ADC_PrescaleCalc(7000000, 0), /* ADC时钟分频配置 */.tailgate = false /* 不使能Tailgate */};ADC_InitSingle_TypeDef tSingleInit = {.prsSel = adcPRSSELCh0, /* 选择PRS通道0 */.acqTime = adcAcqTime16, /* 配置采集时间为16周期 */.reference = adcRef2V5, /* 使用VDD参考电压 */.resolution = adcRes12Bit, /* 使用12位分辨率 */.input = adcSingleInpCh5, /* 选择ADC通道 */.diff = false, /* 不采用差分采集模式 */.prsEnable = false, /* 禁能PRS输入 */.leftAdjust = false, /* 使用右对准 */.rep = false /* 不使用连续转换 */};ADC_Init(ADC0, &tAdcInit);ADC_InitSingle(ADC0, &tSingleInit); /* 初始化ADC单次转换 *//** 使能单次采集完成中断*/ADC_IntEnable(ADC0, ADC_IF_SINGLE);NVIC_EnableIRQ(ADC0_IRQn);
}
void ADC0_IRQHandler (void)
{ADC_IntClear(ADC0, ADC_IF_SINGLE); /* 清ADC中断标志位 */
}
小壁虎EFM32之ADC 采集电压相关推荐
- 基于STM32F407使用ADC采集电压实验
核心板:STM32F407 实验目的:使用ADC采集电压值将其打印在串口助手上 目录 ADC简介 STM32F407 ADC通道对应的引脚 STM32F407中的数据寄存器 ADC 规则数据寄存器 ( ...
- Arduino Uno 使用 ADC采集电压在LCD上显示
Arduino Uno 使用 ADC采集电压显示在LCD上 前言 所需组件 电路图及说明 Arduino使用ADC 代码 前言 在本教程中,我们将在 ARDUINO UNO 中介绍 ADC(模数转换) ...
- 蓝桥杯嵌入式模板的构建——STM32G431RB(LCD和ADC采集电压)
基于LED和按键的模板来写的 下载工程的链接 蓝桥杯嵌入式模板的构建--STM32G431RB(LED和按键的配置)-其它文档类资源-CSDN下载这个模板亲测有效只写了按键三和按键4对LED进行点灯和 ...
- STM32 - ADC采集电压 中断处理
一.参考电压 VDD接入电压为3.3V ADC供电要求:2.4V到3.6V 注意:STM32的100脚以上(含100脚)有参考电压引脚.在没有参考电压引脚的单片机上,可以把基准电压芯片接入VDDA,但 ...
- GD32 ADC采集电压
文章目录 ADC TIM DMA 其他一些初始化 main 总结 使用芯片为GD32F307 ADC 连续转换模式,可以运行在规则组通道上,一旦相应软件触发或者外部触发产生,ADC就会采样和转换规定的 ...
- STM32实现双通道ADC采集电压电流值
本次的实验是通过配置DMA来获取ADC采集到的数据的. 软件实现如下: adc.c文件 #include "adc.h"#define ADC1_DR_Address ((u32) ...
- 单片机 ADC采集电压
单片机:N76E003 /********************************************* 函数名:Adc_Configuration 功 能:ADC初始化配置 形 参: 返 ...
- F28335的ADC采集电压不对(采集的电压值乱飘)
昨天在调试F28335的ADC采集部分,因为有开发板,所以我就直接把光盘自带的程序给跑了一下,结果发现采集的值和我输入的值不对,我的输入是直接把一个直流电源的正极接到一个采集通道的端口上,直流电源的地 ...
- 小壁虎EFM32如何写Flash实现存储
概念 ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写.ROM在系统停止供电的时候仍然可以保持数据,而RAM通 ...
最新文章
- 使用 PHP 构建的 Web 应用如何避免 XSS 攻击
- IE6 浮动层背景不显示
- CSS公共清除浏览器默认样式
- (原创)speex与wav格式音频文件的互相转换(二)
- 静物摄影用光技巧_室内人像摄影想要拍好,这3种用光技巧你了解吗?
- SpringCloud 从菜鸟到大牛之三 服务拆分 理论
- Shell脚本编程基础笔记一
- mysql慢查询原因_mysql 慢查询的原因分析点滴
- Selenium XPath示例
- IOUtils工具类的依赖maven
- 互联网大佬“舌战”996:马云、刘强东、周鸿祎、张朝阳、李国庆,你站谁?
- Java TIF、JPG、PNG等图片转换
- urllib库如何设置代理如何传递并保存cookie【python爬虫入门进阶】(02-3)
- android vendor接口,HIDL众多service在那启动的--/vendor/etc/init/android.hardware.*@2.0-service.rc...
- 凤凰系统运行linux,在Deepin操作系统中安装凤凰系统(Phoenix OS)的方法
- 腾讯优图一年记:贾佳亚的专访笔记
- VirtualBox Guest Additions
- vba字典重复key_字典去除重复项问题
- 分布式与集群的区别?
- word输入后面的字没了