前言

最近在学习小壁虎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 采集电压相关推荐

  1. 基于STM32F407使用ADC采集电压实验

    核心板:STM32F407 实验目的:使用ADC采集电压值将其打印在串口助手上 目录 ADC简介 STM32F407 ADC通道对应的引脚 STM32F407中的数据寄存器 ADC 规则数据寄存器 ( ...

  2. Arduino Uno 使用 ADC采集电压在LCD上显示

    Arduino Uno 使用 ADC采集电压显示在LCD上 前言 所需组件 电路图及说明 Arduino使用ADC 代码 前言 在本教程中,我们将在 ARDUINO UNO 中介绍 ADC(模数转换) ...

  3. 蓝桥杯嵌入式模板的构建——STM32G431RB(LCD和ADC采集电压)

    基于LED和按键的模板来写的 下载工程的链接 蓝桥杯嵌入式模板的构建--STM32G431RB(LED和按键的配置)-其它文档类资源-CSDN下载这个模板亲测有效只写了按键三和按键4对LED进行点灯和 ...

  4. STM32 - ADC采集电压 中断处理

    一.参考电压 VDD接入电压为3.3V ADC供电要求:2.4V到3.6V 注意:STM32的100脚以上(含100脚)有参考电压引脚.在没有参考电压引脚的单片机上,可以把基准电压芯片接入VDDA,但 ...

  5. GD32 ADC采集电压

    文章目录 ADC TIM DMA 其他一些初始化 main 总结 使用芯片为GD32F307 ADC 连续转换模式,可以运行在规则组通道上,一旦相应软件触发或者外部触发产生,ADC就会采样和转换规定的 ...

  6. STM32实现双通道ADC采集电压电流值

    本次的实验是通过配置DMA来获取ADC采集到的数据的. 软件实现如下: adc.c文件 #include "adc.h"#define ADC1_DR_Address ((u32) ...

  7. 单片机 ADC采集电压

    单片机:N76E003 /********************************************* 函数名:Adc_Configuration 功 能:ADC初始化配置 形 参: 返 ...

  8. F28335的ADC采集电压不对(采集的电压值乱飘)

    昨天在调试F28335的ADC采集部分,因为有开发板,所以我就直接把光盘自带的程序给跑了一下,结果发现采集的值和我输入的值不对,我的输入是直接把一个直流电源的正极接到一个采集通道的端口上,直流电源的地 ...

  9. 小壁虎EFM32如何写Flash实现存储

    概念 ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写.ROM在系统停止供电的时候仍然可以保持数据,而RAM通 ...

最新文章

  1. 使用 PHP 构建的 Web 应用如何避免 XSS 攻击
  2. IE6 浮动层背景不显示
  3. CSS公共清除浏览器默认样式
  4. (原创)speex与wav格式音频文件的互相转换(二)
  5. 静物摄影用光技巧_室内人像摄影想要拍好,这3种用光技巧你了解吗?
  6. SpringCloud 从菜鸟到大牛之三 服务拆分 理论
  7. Shell脚本编程基础笔记一
  8. mysql慢查询原因_mysql 慢查询的原因分析点滴
  9. Selenium XPath示例
  10. IOUtils工具类的依赖maven
  11. 互联网大佬“舌战”996:马云、刘强东、周鸿祎、张朝阳、李国庆,你站谁?
  12. Java TIF、JPG、PNG等图片转换
  13. urllib库如何设置代理如何传递并保存cookie【python爬虫入门进阶】(02-3)
  14. android vendor接口,HIDL众多service在那启动的--/vendor/etc/init/android.hardware.*@2.0-service.rc...
  15. 凤凰系统运行linux,在Deepin操作系统中安装凤凰系统(Phoenix OS)的方法
  16. 腾讯优图一年记:贾佳亚的专访笔记
  17. VirtualBox Guest Additions
  18. vba字典重复key_字典去除重复项问题
  19. 分布式与集群的区别?
  20. word输入后面的字没了

热门文章

  1. 【CC++】数组作为函数的参数
  2. Android Q MTK平台开关机铃声
  3. OBD 诊断与 UDS 诊断有什么区别?
  4. ABB机器人拆装说明书_ABB 机器人拆装维护案例.pptx
  5. 直线特征提取算法:IEPF(iterative end point fit)
  6. 牛客网 SQL31 提取博客URL中的用户名
  7. Linux下使用VisualVm通过JMX连接远程机器
  8. mysql高级-4-深入InnoDB
  9. video DownLoad Mothed
  10. 当不知轴承型号时如何寻找轴承故障频率_变频电机常见故障及解决方案大全