ZigBee学习笔记_zmain_vdd_check()

把学习当做是一种乐趣,(学得懂的肯定是很乐, 学不懂的话可就不是乐趣是煎熬了,半懂不懂的就装懂吧)中午没睡,静等崩溃……

static void zmain_vdd_check( void )
{
  uint8 vdd_passed_count = 0;
  bool toggle = 0;

  // Repeat getting the sample until number of failures or successes hits MAX
  // then based on the count value, determine if the device is ready or not
  while ( vdd_passed_count < MAX_VDD_SAMPLES )
  {
    if ( HalAdcCheckVdd (ZMAIN_VDD_LIMIT) )
    {
      vdd_passed_count++;    // Keep track # times Vdd passes in a row
      MicroWait (10000);     // Wait 10ms to try again
    }
    else
    {
      vdd_passed_count = 0;  // Reset passed counter
      MicroWait (50000);     // Wait 50ms
      MicroWait (50000);     // Wait another 50ms to try again
    }

    /* toggle LED1 and LED2 */
    if (vdd_passed_count == 0)
    {
      if ((toggle = !(toggle)))
        HAL_TOGGLE_LED1();
      else
        HAL_TOGGLE_LED2();
    }
  }

  /* turn off LED1 */
  HAL_TURN_OFF_LED1();
  HAL_TURN_OFF_LED2();
}
这个函数是检测VDD是否能够运行器MCU,本质就是检测供电电压的大小,我想一般都能运行起吧,不得不说程序很严谨那。。。

查看宏定义可发现MAX_VDD_SAMPLES的值是3,ZMAIN_VDD_LIMIT的值是4,也就是说循环检测了3次,HalAdcCheckVdd()就是检测的实现,如果检测的电压达到要求就延时10ms继续下一次检测,否则的话重新去检测,重置检测计数器,并且LED灯闪烁。

下面看下具体实现

bool HalAdcCheckVdd (uint8 limit)
{
  uint16 value;

  /* Clear ADC interrupt flag */
  ADCIF = 0;

  /* Setup the new value for conversion */
  ADCCON3 = (HAL_ADC_REF_125V | HAL_ADC_DEC_064 | HAL_ADC_CHN_VDD3);

  /* Wait for the conversion to finish */
  while ( !ADCIF );

  /* Get the result */
  value = ADCL;
  value |= ((uint16) ADCH) << 8;

  /* Check the limit and return */
  return ( value >= HalAdcVddLimit[limit] );
}

在这个里面用到了ADCCOON3寄存器, ZigBee学习笔记_zmain_vdd_check()_第1张图片

这个寄存器是用来控制单个ADC转换的,这里的ADC输入是AVDD5/3,实现电池检测功能,

#define HAL_ADC_REF_125V    0x00    /* Internal 1.25V Reference */
#define HAL_ADC_DEC_064     0x00    /* Decimate by 64 : 8-bit resolution */
#define HAL_ADC_CHN_VDD3    0x0f    /* VDD/3 */
可以看到是采用内部1.25V作为参考电压、抽取率为64,输入通道为VDD/3,因为目前没有AD转换序列进行,因此对ADCCON3赋值完毕后即开始AD转换,单个ADC转换将触发ADC中断,而完成一个序列转换是触发一个DMA中断,转换完毕,我们即可以取值了,这里他是用结果跟一个数组里面的值进行比较,数组如下

static __code const uint16 HalAdcVddLimit[] =
{
  0x369C,       /*  VDD Limit - 1.6v  */
  0x3A06,       /*  VDD Limit - 1.7v  */
  0x3D70,       /*  VDD Limit - 1.8v  */
  0x40D9,       /*  VDD Limit - 1.9v  */
  0x4443,       /*  VDD Limit - 2.0v  */
  0x47AD,       /*  VDD Limit - 2.1v  */
  0x4B17,       /*  VDD Limit - 2.2v  */
  0x4E81,       /*  VDD Limit - 2.3v  */
  0x51EA,       /*  VDD Limit - 2.4v  */
};

这里是用转换结果与2.0V进行比较,2.0V是MCU可运行的最低电压,可看下图

ZigBee学习笔记_zmain_vdd_check()_第2张图片


当检测的电压大于等于2.0V时返回true,回到zmain_vdd_check()函数中,当检测结果返回false时,LED灯会闪烁,这个toggle变量不晓得是起什么作用,

#define HAL_TOGGLE_LED2()         st( if (LED2_SBIT) { LED2_SBIT = 0; } else { LED2_SBIT = 1;} )

可以看到只是状态取反而已,LED2的引脚是P1_1,但是在HAL_BOARD_INIT()函数中只是设置P1_0为输出口,并没有设置P1_1为输出口,我想他是写错了吧,最后两句是关闭LED灯,

#define HAL_TURN_OFF_LED1()       st( LED1_SBIT = LED1_POLARITY (0); )
#define LED1_POLARITY     ACTIVE_HIGH
#define ACTIVE_HIGH       !    /* double negation forces result to be '1' */

一个很简单的语句总是用很多层来实现,唉~


你可能感兴趣的:(ZigBee学习笔记_zmain_vdd_check())