📄 f36x_watchdog.c
字号:
//-----------------------------------------------------------------------------
// F36x_Watchdog.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// The Watchdog Timer (WDT) is a hardware timer enabled on every reset that
// will timeout after a programmable interval. When the WDT times out, it
// will force a device reset. To prevent the reset, the WDT must be restarted
// by application software before it overflows. If the system experiences a
// software or hardware malfunction preventing the software from restarting
// the WDT, the WDT will overflow and cause a reset, returning the MCU to a
// known state.
//
// This example demonstrates how to initialize and reset the Watchdog Timer
// (using a timer) and check for a Watchdog Timer reset.
//
// How to Test:
// 1) Compile and download code to a 'F360 device.
// 2) Run the code:
// - The test will blink the LED at a rate of 10Hz until the switch SW1
// (P3.0) is pressed.
// - Once the the switch is pressed it will cause the WDT to trip and
// cause a reset.
// - Upon reset the code checks for a WDT reset and blinks the LED five
// times faster than before.
//
// FID: 36X000041
// Target: C8051F36x
// Tool chain: Keil C51 8.0 / Keil EVAL C51
// Command Line: None
//
// Release 1.0
// -Initial Revision (SM / TP)
// -13 OCT 2006
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <C8051F360.h> // SFR declarations
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F36x
//-----------------------------------------------------------------------------
sfr16 TMR2RL = 0xCA; // Timer2 reload value
sfr16 TMR2 = 0xCC; // Timer2 counter
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 24500000 / 8 // SYSCLK frequency in Hz
sbit LED = P3^2; // LED='1' means ON
sbit SW1 = P3^0; // SW1='0' means switch pressed
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void Oscillator_Init (void);
void Port_Init (void);
void Watchdog_Init (void);
void Timer0_Init (void);
void Timer2_Init (unsigned int counts);
void Timer0_ISR (void);
void Timer2_ISR (void);
//-----------------------------------------------------------------------------
// main() Routine
//-----------------------------------------------------------------------------
//
// The MAIN routine performs all the intialization, and then loops until the
// switch is pressed. When SW1 (P3.0) is pressed the code checks the RSTSRC
// register to make sure if the last reset is because of WDT.
//-----------------------------------------------------------------------------
void main (void)
{
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)
Oscillator_Init(); // Initialize system clock to 24.5/8 MHz
Watchdog_Init(); // Intialize the Watchdog Timer
Port_Init(); // Initialize crossbar and GPIO
Timer0_Init(); // Initialize Timer0 to "kick" the WDT
EA = 1; // Enable global interrupts
if ((RSTSRC & 0x02) == 0x00) // First check the PORSF bit. If PORSF
{ // is set, all other RSTSRC flags are
// invalid
if (RSTSRC == 0x08) // Check if the last reset was due to a
{ // WDT.
PCA0MD &= ~0x40; // Disable the WDT until the next reset
// Make LED blink at 50Hz
Timer2_Init (SYSCLK / 12 / 50);
while (SW1 != 0); // Wait until SW1 is pressed to reset
// the WDT
while (SW1 == 0); // Wait until the switch is released
// before continuing
RSTSRC = 0x10; // Force a SW reset to reset the WDT
}
else
{
// Init Timer2 to generate interrupts at a 10Hz rate.
Timer2_Init (SYSCLK / 12 / 10);
}
}
SFRPAGE = LEGACY_PAGE;
while (1)
{
if (SW1 == 0) // If the switch (SW) is pressed, stop
{ // resetting the WDT, causing a reset
TR0 = 0;
while(1);
}
}
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Oscillator_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine initializes the system clock to use the internal 24.5MHz / 8
// oscillator as its clock source. Also enables missing clock detector reset.
//
//-----------------------------------------------------------------------------
void Oscillator_Init (void)
{
unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE
SFRPAGE = CONFIG_PAGE; // Switch to the necessary SFRPAGE
OSCICN = 0x80; // Configure internal oscillator for
// its lowest frequency
RSTSRC = 0x04; // Enable missing clock detector
SFRPAGE = SFRPAGE_save; // Restore the SFRPAGE
}
//-----------------------------------------------------------------------------
// Watchdog_Init
//-----------------------------------------------------------------------------
// Return Value : None
// Parameters : None
//
// This routine initializes the Watchdog timer (WDT) to use the SYSCLK / 12
// as its clock source. It also sets the offset value by writing to PCA0CPL5.
//-----------------------------------------------------------------------------
void Watchdog_Init()
{
unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE
SFRPAGE = CONFIG_PAGE; // Switch to the necessary SFRPAGE
// Step 1: Disable the WDT by writing a
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -