Silicon EFR32BG22(5)ADC读取电池电压功能

1 平台条件

1.软件: gecko_sdk_3.2.3
2:硬件:EFR32BG22C224F512GM32
3.IDE工具:SimpliStudio 5
4.官方提供的例程链接 访问链接

2 代码的添加

官方有自己的库,以及应用历程,可以添加以及计算

需要包含的.h文件

#include “em_device.h”
#include “em_cmu.h”

2.1 ADC的初始化

// Set CLK_ADC to 10kHz (this corresponds to a sample rate of 1ksps)
#define CLK_SRC_ADC_FREQ        5000000  // CLK_SRC_ADC; largest division is by 4
#define CLK_ADC_FREQ            10000    // CLK_ADC; IADC_SCHEDx PRESCALE has 10 valid bits

// When changing GPIO port/pins above, make sure to change xBUSALLOC macro's
// accordingly.
#define IADC_INPUT_BUS          CDBUSALLOC
#define IADC_INPUT_BUSALLOC     GPIO_CDBUSALLOC_CDEVEN0_ADC0

// Stores latest ADC sample and converts to volts
static volatile IADC_Result_t sample;
static volatile double singleResult;


static uint16_t batt_valu =0;
uint8_t batt_level =100;
void read_adc(void);
/**************************************************************************//**
 * @brief  IADC Initializer
 *****************************************************************************/
void initIADC (void)
{
  // Declare init structs
  IADC_Init_t init = IADC_INIT_DEFAULT;
  IADC_AllConfigs_t initAllConfigs = IADC_ALLCONFIGS_DEFAULT;
  IADC_InitSingle_t initSingle = IADC_INITSINGLE_DEFAULT;

  IADC_SingleInput_t initSingleInput = IADC_SINGLEINPUT_DEFAULT;

  // Enable IADC clock
  CMU_ClockEnable(cmuClock_IADC0, true);

  // Reset IADC to reset configuration in case it has been modified
  IADC_reset(IADC0);

  // Configure IADC clock source for use while in EM2
//  CMU_ClockSelectSet(cmuClock_IADCCLK, cmuSelect_FSRCO);//2022-3-3

  // Modify init structs and initialize
  init.warmup = _IADC_CTRL_WARMUPMODE_KEEPINSTANDBY;

  // Set the HFSCLK prescale value here
  init.srcClkPrescale = IADC_calcSrcClkPrescale(IADC0, CLK_SRC_ADC_FREQ, 0);

  // Configuration 0 is used by both scan and single conversions by default
  // Use unbuffered AVDD as reference
  initAllConfigs.configs[0].reference = iadcCfgReferenceInt1V2 ;
  initAllConfigs.configs[0].vRef   =1210;

  // Divides CLK_SRC_ADC to set the CLK_ADC frequency for desired sample rate
  initAllConfigs.configs[0].adcClkPrescale = IADC_calcAdcClkPrescale(IADC0,
                                                                    CLK_ADC_FREQ,
                                                                    0,
                                                                    iadcCfgModeNormal,
                                                                    init.srcClkPrescale);
  // Single initialization
  initSingle.dataValidLevel = _IADC_SINGLEFIFOCFG_DVL_VALID1;

  // Set conversions to run continuously
  initSingle.triggerAction = _IADC_TRIGGER_SCANTRIGACTION_ONCE;

  // Set alignment to right justified with 12 bits for data field
  initSingle.alignment = iadcAlignRight12;

  // Configure Input sources for single ended conversioniadcPosInputDvdd;选择读取源//
  initSingleInput.posInput = iadcPosInputAvdd;
  initSingleInput.negInput = iadcNegInputGnd;

  // Initialize IADC
  IADC_init(IADC0, &init, &initAllConfigs);

  // Initialize Scan
  IADC_initSingle(IADC0, &initSingle, &initSingleInput);

  // Allocate the analog bus for ADC0 inputs
  GPIO->IADC_INPUT_BUS |= IADC_INPUT_BUSALLOC;

  // Enable interrupts on data valid level
  IADC_enableInt(IADC0,IADC_IEN_SINGLEFIFODVL );//

  // Enable ADC interrupts
  NVIC_ClearPendingIRQ(IADC_IRQn);
  NVIC_EnableIRQ(IADC_IRQn);
}

2.2 ADC的disable

/****************************************************************
 *iadc_uinit
 */
void iadc_uinit(void)
{
  // Reset IADC to reset configuration in case it has been modified
  IADC_reset(IADC0);

  IADC_disableInt(IADC0,IADC_IEN_SINGLEFIFODVL);
  // Enable IADC clock
  CMU_ClockEnable(cmuClock_IADC0, false);
  NVIC_DisableIRQ(IADC_IRQn);

}

2.3 ADC读取函数

void read_adc(void)
{
  initIADC();
  // Start single
  IADC_command(IADC0, iadcCmdStartSingle);
}

2.4 ADC执行读取函数后,进行中断数据的处理

/**************************************************************************//**
 * @brief  ADC Handler
 *****************************************************************************/
void IADC_IRQHandler(void)
{
  float temp_batt=0.0;
  // Read data from the FIFO, 12-bit result
  sample = IADC_pullSingleFifoResult(IADC0);

  // For single-ended the result range is 0 to +Vref, i.e., 16 bits for the
  // conversion value.
  singleResult = (sample.data*1.21)/0x0FFF;

  uint16_t temp =singleResult*1000;
  batt_valu=temp*4;

  BLE_RTT("singleResult===%d.....valu=%d\r\n",sample.data,batt_valu);
  IADC_clearInt(IADC0, IADC_IF_SINGLEFIFODVL);

  iadc_uinit();
}

2.5 注意点

系列0和系列1的一些Silincon Labs的蓝牙、MCU芯片采取的是把内部LDO的参考源电压x2来提升测量范围,才能测量VDD,系列2的EFR32BG22系列蓝牙SOC简化了这个过程。EFR32BG22如果不采用外部的参考源,测量VDD时,会采用内部的1.21V作为参考源,VDD作为输入信号源。那么问题来了: VREF=1.21V,而VDD一般会大于1.22V,介于1.8V到3V之间,超过了量程,是否根本无法测量?
连接来源:访问地址

但是EFR32BG22有一个特点,当VDD作为ADC的输入源时,实际上有进行1/4分压,如下:
在这里插入图片描述

所以当输入源=VDD/4时,1.21V的VREF量程是足够的。
实现过程:
开始GPIO和IADC时钟
// Enable GPIO clock branch
CMU_ClockEnable(cmuClock_GPIO, true);
// Enable IADC clock
CMU_ClockEnable(cmuClock_IADC0, true);
参考源选择内部1.21V
initAllConfigs.configs[0].reference = iadcCfgReferenceInt1V2;
参考源选择,直接选择VDD,例如:这里VDD为电池供电3V,那么实际内部输入电压只有0.75V,小于参考源电压,可以测量出来VDD的电压:
initSingleInput.posInput = iadcPosInputDvdd;
initSingleInput.negInput = iadcNegInputGnd;
4. VDD电压计算
采集到的IDAC数据:sample = IADC_pullSingleFifoResult(IADC0).data;
计算输入电压:singleResult = (sample * 1.21) / 0xFFFF;
还原VDD实际电压:VDD = singleResult *4;

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
EFR32FG12低功耗无线片上系统 • 高性能 32 位 40 MHz ARM Cortex®-M4,带有 DSP 指令和浮 点单元,可实现高效的信号处理 • 最高 256 kB 闪存程序存储器 • 最高 32 kB RAM 数据存储器 • 2.4 GHz 和 1 GHz 以下无线电操作 • 发射功率: • 2.4 GHz 无线电:最高 19 dBm • 1 GHz 以下的无线电:最高 20 dBm • 低功耗 • 在 169 MHz、 38.4 kbps、GFSK 的条件下,RX 电流为 8.4 mA • 在 2.4 GHz、1 Mbps、GFSK 的条件下,RX 电流为 8.8 mA • 在 2.4 GHz、250 kbps、DSSS-OQPSK 的条件下,RX 电流为 10.2 mA • 在 2.4 GHz、0 dBm 输出功率的条件下,TX 电流为 8.5 mA • 在 868 MHz、14 dBm 输出功率的条件下,TX 电流为 35.3 mA • 在活动模式 (EM0) 下,运行功耗为 67 μA/MHz • 在 EM2 深度睡眠模式下,电流为 1.3 μA(保留 16 kB RAM,RTCC 从 LFRCO 中运行) • 无线模块唤醒,带有信号强度检测,前导模式检测,帧检测 和超时功能 • 高接收器性能 • 在 2.4 GHz、1 Mbit/s GFSK 的条件下,灵敏度为 -93.8 dBm • 在 2.4 GHz、250 kbps DSSS-OQPSK 的条件下,灵敏度为 -103.3 dBm • 在 915 MHz、600 bps、GFSK 的条件下,灵敏度为 -126.2 dBm • 在 868 MHz、2.4 kbps、GFSK 的条件下,灵敏度为 -120.6 dBm • 在 433 MHz、4.8 kbps、OOK 的条件下,灵敏度为 -109.9 dBm • 在 169 MHz、38.4 kbps、GFSK 的条件下,灵敏度为 -112.2 dBm • 支持的调制格式 • 2/4 (G)FSK,可配置完整波形 • BPSK / DBPSK TX • OOK / ASK • 已调制好波形的 OQPSK / (G)MSK • 可配置的 DSSS 和 FEC

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值