看看窗口看門狗的框圖
從圖里看出產生復位信號有2個方式:
1 WDGCR寄存器的T6 由1變0,也就是從此寄存器的值從0x40變成0x3F會產生復位信號;
2 當寄存器WDGCR的值大於WDGWR的時候寫WDGCR寄存器會產生復位信號;
解釋:
WDGCR的最高位WDGA是開啟看門狗的(WDGA=1開啟),當然如果開啟了硬件看門狗這個位就沒用了。硬件看門狗在OPTION BYTES里設置。
WDGCR的低六位是計數用的從圖里可以得出這個計數器的時鍾是fCPU時鍾分頻得來的。這個分頻值固定是12288,根據這個可以計算看門狗的延時時間。
WDGWR是窗口寄存器,最高位保留,低六位保存的是窗口值,從圖里的邏輯圖發現comparator=1 when T6:0>W6:0,意思是當WDGCR計數值大於WDGCR
且此時Write WDGCR(這個意思是軟件刷新計數器的值)就會產生一個復位信號復位stm8s。當然我們不想這個事情發送。所以在寫程序的時候不能在計時器的值
大於窗口寄存器設定值的時候刷新計數器的值。所以在設定這個窗口寄存器數值的時候只能設定在0x7f~0xC0之間。
程序:
知道窗口電子狗怎么工作那么編程就好說了,三件事:
1 設定窗口寄存器值,開啟看門狗(WDGA=1),這是初始化看門狗
2 判斷看門狗計數值是否小於窗口值,是就喂狗
代碼如下:
用stm8s的官方庫。
WWDG_Init(0x7f, 0x50); //初始化
CounterValue = (u8)WWDG->CR & 0x7F;
if(CounterValue < WINDOW){
WWDG_SetCounter(COUNTERINIT); //喂狗
}
解釋一下WWDG_Init這個函數體的內容是:
void WWDG_Init(uint8_t Counter, uint8_t WindowValue)
{
/* Check the parameters */
assert_param(IS_WWDG_WINDOWLIMITVALUE_OK(WindowValue));
WWDG->WR = WWDG_WR_RESET_VALUE;
WWDG->CR = (uint8_t)((uint8_t)(WWDG_CR_WDGA | WWDG_CR_T6) | (uint8_t)Counter);
WWDG->WR = (uint8_t)((uint8_t)(~WWDG_CR_WDGA) & (uint8_t)(WWDG_CR_T6 | WindowValue));
}
WWDG_SetCounter的源碼是:
void WWDG_SetCounter(uint8_t Counter)
{
/* Check the parameters */
assert_param(IS_WWDG_COUNTERVALUE_OK(Counter));
/* Write to T[6:0] bits to configure the counter value, no need to do
a read-modify-write; writing a 0 to WDGA bit does nothing */
WWDG->CR = (uint8_t)(Counter & (uint8_t)BIT_MASK);
}
assert_param是參數檢查,其他沒啥好說的。搞清楚寄存器作用就行了。其他問題暫時想不起來。哦,對了延時時間看下圖:
這里說得比較清楚如果stm8用的是內部HSI 16M晶振切fCPU的分頻也是0那么窗口看門狗的時鍾頻率就是fCPU/12288,那么一個計時周期就是12288/fCPU就是0.768ms
如果設定的窗口值是0x50,那么從0x7F數下來一算就知道了。0.768*(0x7f-0x50)。要注意這里fCPU不一定是16m(CPUDIV分頻系數可以改變),如果要搞清楚stm8的時鍾頻率看下面這個圖。這里就不做詳細討論了,以后在說。