STM32 SP706S 外部看門狗的應用示例

看門狗是防止程序跑飛的一種兜底方案,STM32有自己片內的獨立看門狗和串口看門狗,但是很意外的發現我測試片內的看門狗不好用,關閉了一扇門的同時,我又發現了一扇窗,板子上有SP706S外部看門狗芯片,那麼STM32 SP706S的測試就應運而生。

STM32和SP706S的電路部分說明示意圖

關於SP706S的文檔描述

對於SP706S來說,WDI是輸入,那麼對於STM32來說,對應連接的STM32引腳PA0就是輸出(推輓輸出)。

圖中紅框描述的意思是如果WDI這個引腳持續高電平或持續低電平到1.6秒的時間,內部看門狗定時器就會WDO(上劃線)持續低電平。從上面的示意圖可以看出WDO(上劃線)和MR(上劃線)連接在一起;RESET(上劃線)又和STM32的NRST連接在一起,也就是說 RESET(上劃線)決定了STM32的復位效果。

總結一下,從STM32這個角度出發,如果初始化了PA0爲推輓輸出,即使能了外部看門狗,PA0需要再1.6s內變化一次高低電平實現喂狗,否則STM32程序就會被複位。

按照上述思路,編寫測試工程代碼來進行驗證。

根據板子現有的資源2個LED燈,一個撥碼開關。要實現測試效果的描述:

程序開始,初始化LED和撥碼開關的GPIO,延時2秒鐘,這時候LED燈有2秒是滅的狀態。再使能看門狗,即設置PA0的GPIO爲推輓輸出。程序進入循環,循環中判斷撥碼開關的狀態,如果是1就喂狗,否則就不喂狗。緊接着LED1和LED2亮滅,延時了400毫秒。

測試過程,程序編譯下載,最初撥碼開關是0的狀態,即不喂狗,程序執行的現象是LED有2秒滅,然後亮滅閃爍4次左右,就又滅了2秒,再次執行這個過程。即SP706S外部看門狗起作用了,STM32程序重啓了。再將撥碼開關調爲1的狀態,程序不斷亮滅,沒有2秒左右的滅的現象,說明程序喂狗成功。

測試的主函數代碼

#ifndef __STM32F10X_H
#define __STM32F10X_H
#include "stm32f10x.h"
#endif

#ifndef __Z_UTIL_TIME_H
#define __Z_UTIL_TIME_H
#include "z_util_time.h"
#endif

#ifndef __Z_HARDWARE_LED_H
#define __Z_HARDWARE_LED_H
#include "z_hardware_led.h"
#endif

#ifndef __Z_HARDWARE_SWITCHKEYS_H
#define __Z_HARDWARE_SWITCHKEYS_H
#include "z_hardware_switchkeys.h"
#endif

#ifndef __Z_HARDWARE_SP706S_H
#define __Z_HARDWARE_SP706S_H
#include "z_hardware_sp706s.h"
#endif

void func_led_onoff_cross(void);

int main()
{	
	init_led();
	init_switchkeys();
	
	delay_ms(2000);
	
	func_init_sp706s();
	
	for(;;)
	{
		if(func_get_switchkey1() == 1)
		{
			func_feed_dog();
		}
		
		func_led_onoff_cross();
	}
	
}

void func_led_onoff_cross()
{
	func_led1_on();
	func_led2_off();
	delay_ms(200);
	func_led2_on();
	func_led1_off();
	delay_ms(200);
}

z_hardware_sp706s.c

#ifndef __Z_HARDWARE_SP706S_H
#define __Z_HARDWARE_SP706S_H
#include "z_hardware_sp706s.h"
#endif

void func_init_sp706s(void)
{
	GPIO_InitTypeDef GPIO_InitStructure_A;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
	GPIO_InitStructure_A.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure_A.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure_A.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure_A);
}

void func_feed_dog(void)
{
	if(GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_0);
	}
  else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_0);
	}		
}

z_hardware_sp706s.h

#ifndef __STM32F10X_H
#define __STM32F10X_H
#include "stm32f10x.h"
#endif

void func_init_sp706s(void);
void func_feed_dog(void);

以上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章