zmain_vdd_check();//确认VDD是否达到运行处理器的要求,如果没有达到就会闪烁LED<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
//【ZMain.c】line210左右
//重复检测VDD的状态,直到成功检测的次数达到规定过的要求为止。估计是等电源稳定吧,呵呵
static ZSEG void zmain_vdd_check( void )
{
uint8 vdd_passed_count = 0;
bool toggle = 0;
while ( vdd_passed_count < MAX_VDD_SAMPLES )
//#define MAX_VDD_SAMPLES 3; 【ZMain.c】
//循环检测3次
{
if ( HalAdcCheckVdd (ZMAIN_VDD_LIMIT) )
//【ZMain.c】
// #define ZMAIN_VDD_LIMIT HAL_ADC_VDD_LIMIT_4
//【hal_adc.h】
// #define HAL_ADC_VDD_LIMIT_4 0x04
{
vdd_passed_count++; // Keep track # times Vdd passes in a row
MicroWait (10000); // 延时10毫秒
//微秒级延时函数【OnBoard.h】
//#define MicroWait(t) Onboard_wait(t)
//void Onboard_wait( uint16 timeout )
{
while (timeout--)
{
asm("NOP");
asm("NOP");
asm("NOP");
}
}
}
else
{
vdd_passed_count = 0; // Reset passed counter
MicroWait (50000); // Wait 50ms
MicroWait (50000); // Wait another 50ms to try again
}
// HalAdcCheckVdd ()【hal_adc.c】函数用来检查VDD是否大于或等于最小的要求
bool HalAdcCheckVdd (uint8 limit)
{
uint16 value;
//如果芯片修订版本号小于REV_D(0x03)就直接完成电压检测并返回TRUE。CHVER是修订版本号寄存器,此寄存器是只读的。
if (CHVER < REV_D)
//检查芯片版本【hal_mcu.h】
//#define REV_A 0x00
//#define REV_D 0x03
{
return TRUE;
}
//清除ADC中断标志
ADCIF = 0;
//设置新的转换状态
//【hal_adc.c】
//使用内部1.25参考电压
// #define HAL_ADC_REF_125V 0x00
// #define HAL_ADC_DEC_064 0x00 /* Decimate by 64 : 8-bit resolution */8位精度
// #define HAL_ADC_CHN_VDD3 0x<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />0f /* VDD/3 */以AVDD_SOC/3为输入,检测电压
ADCCON3 = (HAL_ADC_REF_125V | HAL_ADC_DEC_064 | HAL_ADC_CHN_VDD3);
//等待转换完成
while ( !ADCIF );
//取得转换值
value = ADCL;
value |= ((uint16) ADCH) << 8;
//检测
return ( value >= HalAdcVddLimit[limit] );
}
// HalAdcVddLimit为一个数组
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 */
};
//关于电池电压的测量与计算在文档:Using the ADC to Measure Supply Voltage.pdf中有详细的示例和说明,现在摘录其中一段解说一下:
// Max ADC input voltage = reference voltage =>
// (VDD/3) max = 1.25 V => max VDD = 3.75 V
// 12 bits resolution means that max ADC value = 0x07FF = 2047 (dec)
// (the ADC value is 2’s complement)
// Battery voltage, VDD = adc value * (3.75 / 2047)
//其中有两点很重要:1、最大的ADC输入值=参考电压;2、ADC的值以2的补码形式储存,也就是说12位的精度因为有1位是符号位所以相对于精度为11,即2^11=2048。因为以VDD/3为输入电压,以内部1.25为参考电压,所以VDD/3最大值=1.25,得出最大的VDD=3.75;以12位精度计算,电压值划分为2.47等分,所以测出来的电压值为adc value*(3.75/2047)
//注意这里并没有操作ADCCON1来启动ADC转换。让我们来看看原因:
//数据手册133页ADCCON3中ECH的说明:
// Extra channel select. Selects the channel number of the extra
conversion that is carried out after a conversion sequence has
ended. This bit field must be written for an extra conversion to be
performed. If the ADC is not running, writing to these bits will
trigger an immediate single conversion from the selected extra
channel. The bits are automatically cleared when the extra
conversion has finished.
//这3位是用来选择转换序列完成以后额外的一次转换。其中有一句:If the ADC is not running, writing to these bits will trigger an immediate single conversion from the selected extra channel.(若ADC没有运行,对这几位的写入操作将会立即开始一个对指定通道的转换),这就是关键了,即使ADC没有运行,我们只要往这3位中写入我们希望转换的通道,那么ADC会马上开始运行,当然执行完毕后这几位会被清除。
//切换LED1和LED2
if (vdd_passed_count == 0)
{
if ((toggle = !(toggle)))
HAL_TOGGLE_LED1();
//【hal_board_cfg.h】
//#define HAL_TOGGLE_LED1() st( if (LED1_SBIT) { LED1_SBIT = 0; } else { LED1_SBIT = 1;} )
//这句很明显了,就是切换LED1的状态。这里一直没有改变toggle的值,为什么还要对它做一个判断呢?搞不明白
else
HAL_TOGGLE_LED2();
}
}
//关闭LED
//【hal_board_cfg.h】
//#define HAL_TURN_OFF_LED1() st( LED1_SBIT = LED1_POLARITY (0); )
//#define HAL_TURN_OFF_LED2() st( LED2_SBIT = LED2_POLARITY (0); )
//#define LED1_POLARITY ACTIVE_HIGH
//#define LED2_POLARITY ACTIVE_LOW
//#define ACTIVE_LOW !
//#define ACTIVE_HIGH !! /* double negation forces result to be '1' */
//这里的宏定义真的是太繁琐了,真不晓得TI这样弄有多大的意义,转了两个弯才看明白原来LED1是高电平点亮
HAL_TURN_OFF_LED1();
HAL_TURN_OFF_LED2();
}
文章评论(0条评论)
登录后参与讨论