剛開始接觸RF通信,借助成都億佰特的demo很快完成了數(shù)據(jù)互傳,但是功耗一直降不下去,ST和SiliconLabs官方的datasheet里分別說STM8L101在halt模式功耗為1uA(開AWU的情況下)、SI4463在standby模式為50nA,但是即使把STM8和SI4463以外的芯片都拆了,整板的實際測試值也比1uA大兩個數(shù)量級。
一、關(guān)于低功耗
首先,把SI4463拿掉,只剩STM8L,在main函數(shù)直接進(jìn)入halt模式,得到工作電流為0.4uA,達(dá)到標(biāo)稱值。
然后,將si4463接上,在main函數(shù)直接進(jìn)入halt模式,工作電流飆升至167uA。為什么呢?
在ST官網(wǎng)找到了《AN3147:Power management in STM8L and STM8AL》,在“第五章 :Power management tips”中找到了問題的關(guān)鍵點——進(jìn)入HALT之前必須將GPIO設(shè)為固定的電平狀態(tài),否則有漏電流存在。于是根據(jù)電路設(shè)計原理圖,除了與SI4463連接的SPI_CSN設(shè)為輸出高、SDN設(shè)為輸出低,其余全設(shè)為輸入上拉。電流降到了25uA,仍遠(yuǎn)遠(yuǎn)大于標(biāo)稱值。
圖1 整板電路圖
最后問題定位在SI4463的GIO設(shè)置上,億佰特的SI4463模塊采用的是TX和RX分離的模擬電路設(shè)計(圖2),GIO2和GIO3控制選通開關(guān),它們根據(jù)TX和RX的狀態(tài)輸出0和1,比如芯片處于TX狀態(tài)時GIO2輸出1、GIO3輸出0,此時天線與TX形成通路,調(diào)制信號從TX口經(jīng)過電感電路被發(fā)送出去。在使si4463進(jìn)入低功耗之前,必須將GIO2、GIO3拉低。
圖2 si4463參考電路設(shè)計
[cpp] view plain copySI446X_GPIO_CONFIG(3, 3, 2, 2, 3, 0, 0x60);
SI446X_CHANGE_STATE(1);
最后功率降到了1uA以下,與標(biāo)稱值相符。
二、關(guān)于AWU設(shè)置
AWU(Auto Wakeup Unit)的時鐘源是獨立的LSI(Low Speed Internal Clock),官方datasheet顯示LSI的一致性比較差,從25KHz到75KHz不等(確實很差),所以配置AWU之前要先知道每一片芯片的LSI是多少,才能達(dá)到喚醒時間的預(yù)期值。首先,用TIM2測量LSI的頻率,官方驅(qū)動庫就有函數(shù)實現(xiàn),函數(shù)原型如下
uint32_t TIM2_ComputeLsiClockFreq(uint32_t TIM2_TimerClockFreq);
官網(wǎng)驅(qū)動庫也有AWU的配置函數(shù) void AWU_LSICalibrationConfig(uint32_t LSIFreqHz), 這個函數(shù)給出的結(jié)果很糟糕,喚醒時間根本不對。于是自己根據(jù)datasheet寫了個函數(shù)
[cpp] view plain copy#define AWU_MAX_INTERNVAL_COEFFICIENT ((uint32_t)3932160)
#define AWU_APR_MAX_VALUE ((uint8_t)64)
#define AWU_TBR_MAX_VALUE ((uint8_t)0x0f)
#define AWU_APR_MIN_VALUE ((uint8_t)2)
#define AWU_TBR_MIN_VALUE ((uint8_t)0x01)
#define AWU_HIGH_RESOLUTION_THRESHOLD ((uint32_t)6889)
[cpp] view plain copy
[cpp] view plain copy/**
* @brief Update APR register with the measured LSI frequency.
Accuracy is much better than AWU_LSICalibrationConfig()。
* @param LSIFreqHz -- the LSI frequency, in Hertz.
internval -- AWU wake up interval, in milliseconds
* @note AWU must be disabled to avoid unwanted interrupts.
* @retval None
*/
ErrorStatus AWU_ConfigLSI(uint32_t LSIFreqHz, uint32_t internval)
{
uint32_t tmp = 0, z = 0;
uint8_t y = 0, x = 0;
uint8_t flag = 0;
/* Check parameter */
assert_param(IS_LSI_FREQUENCY(LSIFreqHz));
z = LSIFreqHz * internval;
if(internval》AWU_HIGH_RESOLUTION_THRESHOLD)
{
tmp = z / 10240000;
if( tmp》=AWU_APR_MIN_VALUE && tmp 《= AWU_APR_MAX_VALUE)
{
AWU-》TBR |= 0x0e;
AWU-》APR = (tmp)-2;
return SUCCESS;
}
tmp = z / 61440000;
if( tmp》=AWU_APR_MIN_VALUE && tmp 《= AWU_APR_MAX_VALUE)
{
AWU-》TBR |= 0x0f;
AWU-》APR = (tmp)-2;
return SUCCESS;
}
}
/* 2^x*y = LSIFreqHz * internval */
for(y=64;y》1;y=y》》1)
{
tmp = z/((uint32_t)y*1000) ;
if(tmp》=1 && tmp《=4096) /*value is between 2^0 and 2^12*/
{
flag = 1;
break;
}
}
/*計算TBR,再根據(jù)TBR推導(dǎo)出APR*/
if(flag!=0)
{
for(x=0;x《13;x++)
{
if( (tmp》》x)==0 )
{
break;
}
}
tmp = (uint32_t)1《《x;
y = z/((uint32_t)tmp*1000);
if(y《2)
{
return ERROR;
}
AWU-》TBR = x+1;
AWU-》APR = y-2;
return SUCCESS;
}
else
{
return ERROR;
}
}
參數(shù)internval是期望的喚醒時間,單位是ms,數(shù)值范圍是1到60000。
設(shè)置好TBR和APR之后,只要使用AWU_Cmd(ENABLE)即可啟動AWU,它只會在STM8處于halt模式下才開始計時,當(dāng)計時達(dá)到設(shè)置的interval時產(chǎn)生中斷,將STM8從halt模式喚醒。
/***** 補丁1:AWU設(shè)置函數(shù)存在BUG,修正了一下,現(xiàn)在可以放心使用了 20161205 *******/
評論
查看更多