您好,歡迎進(jìn)入深圳市穎特新科技有限公司官方網(wǎng)站!
看門狗定時(shí)器的用途是在軟件出問題時(shí)執(zhí)行系統(tǒng)復(fù)位功能,這可以防止系統(tǒng)無限期地掛起。除此之外,看門狗定時(shí)器還支持將CPU 從掉電模式喚醒的功能。看門狗定時(shí)器包含一個(gè)18 位的自由運(yùn)行計(jì)數(shù)器,定時(shí)溢出間隔可編程。
特征
18-位自由運(yùn)行WDT 計(jì)數(shù)器用于看門狗定時(shí)器超時(shí)間隔。
可選擇的超時(shí)間隔 (2^4 ~ 2^18),超時(shí)間隔為104 ms ~ 26.316 s (如果WDT_CLK = 10 kHz)。
復(fù)位周期 = (1 / 10 kHz) * 63,如果WDT_CLK = 10 kHz
對應(yīng)的寄存器是這個(gè)
#define WDT_BASE (APB1PERIPH_BASE + 0x04000) ///< WDT register base address #define APB1PERIPH_BASE ((uint32_t)0x40000000) ///< APB1 base address #define CLK_APBCLK_WDT_EN_Pos (0) /*!< CLK_T::APBCLK: WDT_EN Position */ #define CLK_APBCLK_WDT_EN_Msk (0x1ul << CLK_APBCLK_WDT_EN_Pos) /*!< CLK_T::APBCLK: WDT_EN Mask
typedef struct { /** * PWRCTL * =================================================================================================== * Offset: 0x00 System Power Down Control Register * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[0] |HXT_EN |HXT Control * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |The bit default value is set by flash controller user configuration register config0 [26]. * | | |0 = Disabled. * | | |1 = Enabled. * | | |HXT is disabled by default. * |[1] |LXT_EN |LXT Control * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |0 = Disabled. * | | |1 = Enabled. * | | |LXT is disabled by default. * |[2] |HIRC_EN |HIRC Control * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |0 = Disabled. * | | |1 = Enabled. * | | |HIRC is enabled by default. * |[3] |LIRC_EN |LIRC Control * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |0 = Disabled. * | | |1 = Enabled. * | | |LIRC is enabled by default. * |[4] |WK_DLY |Wake-Up Delay Counter Enable * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |When chip wakes up from Power-down mode, the clock control will delay 4096 clock cycles to wait HXT stable or 16 clock cycles to wait HIRC stable. * | | |0 = Delay clock cycle Disabled. * | | |1 = Delay clock cycle Enabled. * |[5] |PD_WK_IE |Power-Down Mode Wake-Up Interrupt Enable * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |0 = Disabled. * | | |1 = Enabled. * | | |PD_WK_INT will be set if both PD_WK_IS and PD_WK_IE are high. * |[6] |PD_EN |Chip Power-Down Mode Enable Bit * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |When CPU sets this bit, the chip power down is enabled and chip will not enter Power-down mode until CPU sleep mode is also active * | | |When chip wakes up from Power-down mode, this bit will be auto cleared. * | | |When chip is in Power-down mode, the LDO, HXT and HIRC will be disabled, but LXT and LIRC are not controlled by Power-down mode. * | | |When power down, the PLL and system clock (CPU, HCLKx and PCLKx) are also disabled no matter the Clock Source selection. * | | |Peripheral clocks are not controlled by this bit, if peripheral Clock Source is from LXT or LIRC. * | | |In Power-down mode, flash macro power is ON. * | | |0 = Chip operated in Normal mode. * | | |1 = Chip power down Enabled. * |[8] |HXT_SELXT |HXT SELXT * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |0 = High frequency crystal loop back path Disabled. It is used for external oscillator. * | | |1 = High frequency crystal loop back path Enabled. It is used for external crystal. * |[9] |HXT_GAIN |HXT Gain Control Bit * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |Gain control is used to enlarge the gain of crystal to make sure crystal wok normally. * | | |If gain control is enabled, crystal will consume more power than gain control off. * | | |0 = Gain control Disabled. It means HXT gain is always high. * | | |For 16MHz to 24MHz crystal. * | | |1 = Gain control Enabled. HXT gain will be high lasting 2ms then low. This is for power saving. * | | |For 4MHz to 16MHz crystal. * |[10] |LXT_SCNT |LXT Stable Time Control * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |0 = Delay 4096 LXT before LXT output. * | | |1 = Delay 8192 LXT before LXT output. * |[12:11] |HXT_HF_ST |HXT Frequency Selection * | | |Set this bit to meet HXT frequency selection (Recommended) * | | |00 = HXT frequency is from 4 MHz to 12 MHz. * | | |01 = HXT frequency is from 12 MHz to 16 MHz. * | | |10 = HXT frequency is from 16 MHz to 24 MHz. * | | |11 = Reserved. */ __IO uint32_t PWRCTL; /** * AHBCLK * =================================================================================================== * Offset: 0x04 AHB Devices Clock Enable Control Register * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[0] |GPIO_EN |GPIO Controller Clock Enable * | | |0 = Disabled. * | | |1 = Enabled. * |[1] |DMA_EN |DMA Controller Clock Enable * | | |0 = Disabled. * | | |1 = Enabled. * |[2] |ISP_EN |Flash ISP Controller Clock Enable * | | |0 = Disabled. * | | |1 = Enabled. * |[3] |EBI_EN |EBI Controller Clock Enable * | | |0 = Disabled. * | | |1 = Enabled. * |[4] |SRAM_EN |SRAM Controller Clock Enable * | | |0 = Disabled. * | | |1 = Enabled. * |[5] |TICK_EN |System Tick Clock Enable * | | |0 = Disabled. * | | |1 = Enabled. */ __IO uint32_t AHBCLK; /** * APBCLK * =================================================================================================== * Offset: 0x08 APB Devices Clock Enable Control Register * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[0] |WDT_EN |Watchdog Timer Clock Enable Control * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |This bit is used to control the WDT APB clock only, The WDT engine Clock Source is from LIRC. * | | |0 = Disabled. * | | |1 = Enabled. * |[1] |RTC_EN |Real-Time-Clock Clock Enable Control * | | |This bit is used to control the RTC APB clock only, The RTC engine Clock Source is from LXT. * | | |0 = Disabled. * | | |1 = Enabled. * |[2] |TMR0_EN |Timer0 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[3] |TMR1_EN |Timer1 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[4] |TMR2_EN |Timer2 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[5] |TMR3_EN |Timer3 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[6] |FDIV_EN |Frequency Divider Output Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[7] |SC2_EN |SmartCard 2 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[8] |I2C0_EN |I2C0 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[9] |I2C1_EN |I2C1 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[12] |SPI0_EN |SPI0 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[13] |SPI1_EN |SPI1 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[14] |SPI2_EN |SPI2 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[16] |UART0_EN |UART0 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[17] |UART1_EN |UART1 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[20] |PWM0_CH01_EN|PWM0 Channel 0 And Channel 1Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[21] |PWM0_CH23_EN|PWM0 Channel 2 And Channel 3 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[22] |PWM1_CH01_EN|PWM1 Channel 0 And Channel 1 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[23] |PWM1_CH23_EN|PWM1 Channel 2 And Channel 3 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[25] |DAC_EN |12-Bit DAC Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[26] |LCD_EN |LCD Controller Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[27] |USBD_EN |USB FS Device Controller Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[28] |ADC_EN |Analog-Digital-Converter (ADC) Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[29] |I2S_EN |I2S Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[30] |SC0_EN |SmartCard 0 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. * |[31] |SC1_EN |SmartCard 1 Clock Enable Control * | | |0 = Disabled. * | | |1 = Enabled. */ __IO uint32_t APBCLK; /** * CLKSTATUS * =================================================================================================== * Offset: 0x0C Clock status monitor Register * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[0] |HXT_STB |HXT Clock Source Stable Flag * | | |0 = HXT clock is not stable or not enable. * | | |1 = HXT clock is stable. * |[1] |LXT_STB |LXT Clock Source Stable Flag * | | |0 = LXT clock is not stable or not enable. * | | |1 = LXT clock is stable. * |[2] |PLL_STB |PLL Clock Source Stable Flag * | | |0 = PLL clock is not stable or not enable. * | | |1 = PLL clock is stable. * |[3] |LIRC_STB |LIRC Clock Source Stable Flag * | | |0 = LIRC clock is not stable or not enable. * | | |1 = LIRC clock is stable. * |[4] |HIRC_STB |HIRC Clock Source Stable Flag * | | |0 = HIRC clock is not stable or not enable. * | | |1 = HIRC clock is stable. * |[7] |CLK_SW_FAIL|Clock Switch Fail Flag * | | |0 = Clock switch success. * | | |1 = Clock switch fail. * | | |This bit will be set when target switch Clock Source is not stable. This bit is write 1 clear */ __I uint32_t CLKSTATUS; /** * CLKSEL0 * =================================================================================================== * Offset: 0x10 Clock Source Select Control Register 0 * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[2:0] |HCLK_S |HCLK Clock Source Selection * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |Note: * | | |Before Clock Source switches, the related clock sources (pre-select and new-select) must be turn on * | | |The 3-bit default value is reloaded with the value of CFOSC (Config0[26:24]) in user configuration register in Flash controller by any reset. * | | |Therefore the default value is either 000b or 111b. * | | |000 = HXT * | | |001 = LXT * | | |010 = PLL Clock * | | |011 = LIRC * | | |111 = HIRC * | | |Others = Reserved */ __IO uint32_t CLKSEL0; /** * CLKSEL1 * =================================================================================================== * Offset: 0x14 Clock Source Select Control Register 1 * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[1:0] |UART_S |UART 0/1 Clock Source Selection (UART0 And UART1 Use The Same Clock Source Selection) * | | |00 = HXT * | | |01 = LXT * | | |10 = PLL Clock * | | |11 = HIRC * |[3:2] |ADC_S |ADC Clock Source Selection * | | |00 = HXT * | | |01 = LXT * | | |10 = PLL Clock * | | |11 = HIRC * |[5:4] |PWM0_CH01_S|PWM0 Channel 0 And Channel 1 Clock Source Selection * | | |PWM0 channel 0 and channel 1 use the same Engine clock source, both of them with the same prescaler * | | |00 = HXT * | | |01 = LXT * | | |10 = HCLK * | | |11 = HIRC * |[7:6] |PWM0_CH23_S|PWM0 Channel 2 And Channel 3 Clock Source Selection * | | |PWM0 channel 2 and channel 3 use the same Engine clock source, both of them with the same prescaler * | | |00 = HXT * | | |01 = LXT * | | |10 = HCLK * | | |11 = HIRC * |[10:8] |TMR0_S |Timer0 Clock Source Selection * | | |000 = HXT * | | |001 = LXT * | | |010 = LIRC * | | |011 = External Pin * | | |111 = HIRC * | | |Others = Reserved * |[14:12] |TMR1_S |Timer1 Clock Source Selection * | | |000 = HXT * | | |001 = LXT * | | |010 = LIRC * | | |011 = External Pin * | | |111 = HIRC * | | |Others = Reserved * |[18] |LCD_S |LCD Clock Source Selection * | | |0 = Clock Source from LXT. * | | |1 = Reserved. */ __IO uint32_t CLKSEL1; /** * CLKSEL2 * =================================================================================================== * Offset: 0x18 Clock Source Select Control Register 2 * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[3:2] |FRQDIV_S |Clock Divider Clock Source Selection * | | |00 = HXT * | | |01 = LXT * | | |10 = HCLK * | | |11 = HIRC * |[5:4] |PWM1_CH01_S|PWM1 Channel 0 And Channel 1 Clock Source Selection * | | |PWM1 channel 0 and channel 1 use the same Engine clock source, both of them with the same pre-scale * | | |00 = HXT * | | |01 = LXT * | | |10 = HCLK * | | |11 = HIRC * |[7:6] |PWM1_CH23_S|PWM1 Channel 2 And Channel 2 Clock Source Selection * | | |PWM1 channel 2 and channel 3 use the same Engine clock source, both of them with the same pre-scale * | | |00 = HXT * | | |01 = LXT * | | |10 = HCLK * | | |11 = HIRC * |[10:8] |TMR2_S |Timer2 Clock Source Selection * | | |000 = HXT * | | |001 = LXT * | | |010 = LIRC * | | |011 = External Pin * | | |111 = HIRC * | | |Others = Reserved * |[14:12] |TMR3_S |Timer3 Clock Source Selection * | | |000 = HXT * | | |001 = LXT * | | |010 = LIRC * | | |011 = External Pin * | | |111 = HIRC * | | |Others = Reserved * |[17:16] |I2S_S |I2S Clock Source Selection * | | |00 = HXT * | | |01 = PLL Clock * | | |10 = HIRC * | | |11 = HIRC * |[19:18] |SC_S |SC Clock Source Selection * | | |00 = HXT * | | |01 = PLL Clock * | | |10 = HIRC * | | |11 = HIRC * | | |Note: SC0,SC1 and SC2 use the same Clock Source selection but they have different clock divider number. * |[20] |SPI0_S |SPI0 Clock Source Selection * | | |0 = PLL. * | | |1 = HCLK. * |[21] |SPI1_S |SPI1 Clock Source Selection * | | |0 = PLL. * | | |1 = HCLK. * |[22] |SPI2_S |SPI2 Clock Source Selection * | | |0 = PLL. * | | |1 = HCLK. */ __IO uint32_t CLKSEL2; /** * CLKDIV0 * =================================================================================================== * Offset: 0x1C Clock Divider Number Register 0 * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[3:0] |HCLK_N |HCLK Clock Divide Number From HCLK Clock Source * | | |The HCLK clock frequency = (HCLK Clock Source frequency) / (HCLK_N + 1). * |[7:4] |USB_N |USB Clock Divide Number From PLL Clock * | | |The USB clock frequency = (PLL frequency ) / (USB_N + 1). * |[11:8] |UART_N |UART Clock Divide Number From UART Clock Source * | | |The UART clock frequency = (UART Clock Source frequency ) / (UART_N + 1). * |[15:12] |I2S_N |I2S Clock Divide Number From I2S Clock Source * | | |The I2S clock frequency = (I2S Clock Source frequency ) / (I2S_N + 1). * |[23:16] |ADC_N |ADC Clock Divide Number From ADC Clock Source * | | |The ADC clock frequency = (ADC Clock Source frequency ) / (ADC_N + 1). * |[31:28] |SC0_N |SC 0 Clock Divide Number From SC 0 Clock Source * | | |The SC 0 clock frequency = (SC0 Clock Source frequency ) / (SC0_N + 1). */ __IO uint32_t CLKDIV0; /** * CLKDIV1 * =================================================================================================== * Offset: 0x20 Clock Divider Number Register 1 * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[3:0] |SC1_N |SC 1 Clock Divide Number From SC 1 Clock Source * | | |The SC 1 clock frequency = (SC 1 Clock Source frequency ) / (SC1_N + 1). * |[7:4] |SC2_N |SC 2 Clock Divide Number From SC2 Clock Source * | | |The SC 2 clock frequency = (SC 2 Clock Source frequency ) / (SC2_N + 1). */ __IO uint32_t CLKDIV1; /** * PLLCTL * =================================================================================================== * Offset: 0x24 PLL Control Register * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[4:0] |FB_DV |PLL Feedback Divider Control Pins * | | |Refer to the formulas below the table. * | | |The range of FB_DV is from 0 to 63. * |[9:8] |IN_DV |PLL Input Divider Control Pins * | | |Refer to the formulas below the table. * |[12] |OUT_DV |PLL Output Divider Control Pins * | | |Refer to the formulas below the table. This bit MUST be 0 for PLL output low deviation. * |[16] |PD |Power-Down Mode * | | |If set the PD_EN bit "1" in PWR_CTL register, the PLL will enter Power-down mode too * | | |0 = PLL is in normal mode. * | | |1 = PLL is in power-down mode (default). * |[17] |PLL_SRC |PLL Source Clock Select * | | |0 = PLL source clock from HXT. * | | |1 = PLL source clock from HIRC. */ __IO uint32_t PLLCTL; /** * FRQDIV * =================================================================================================== * Offset: 0x28 Frequency Divider Control Register * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[3:0] |FSEL |Divider Output Frequency Selection Bits * | | |The formula of output frequency is * | | |Fout = Fin/2^(N+1),. * | | |Where Fin is the input clock frequency, Fout is the frequency of divider output clock and N is the 4-bit value of FSEL[3:0]. * |[4] |FDIV_EN |Frequency Divider Enable Bit * | | |0 = Frequency Divider Disabled. * | | |1 = Frequency Divider Enabled. */ __IO uint32_t FRQDIV; /** * MCLKO * =================================================================================================== * Offset: 0x2C Module Clock Output Register * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[5:0] |MCLK_SEL |Module Clock Output Source Selection (PC.0) * | | |000000 = ISP_CLK * | | |000001 = HIRC * | | |000010 = HXT * | | |000011 = LXT * | | |000100 = LIRC * | | |000101 = PLL output * | | |000110 = PLL input * | | |000111 = System Tick * | | |001000 = HCLK clock * | | |001010 = PCLK clock * | | |100000 = TMR0_CLK * | | |100001 = TMR1_CLK * | | |100010 = UART0_CLK * | | |100011 = USB_CLK * | | |100100 = ADC_CLK * | | |100101 = WDT_CLK * | | |100110 = PWM0_CH01_CLK * | | |100111 = PWM0_CH32_CLK * | | |101001 = LCD_CLK * | | |111000 = TMR2_CLK * | | |111001 = TMR3_CLK * | | |111010 = UART1_CLK * | | |111011 = PWM1_CH01_CLK * | | |111100 = PWM1_CH23_CLK * | | |111101 = I²S_CLK * | | |111110 = SC0_CLK * | | |111111 = SC1_CLK * |[7] |MCLK_EN |Module Clock Output Enable * | | |User can get the module clock output from PC.0 pin via choosing the clock source in the MCLK_SEL bit field and then setting MCLK_EN bit to 1. * | | |0 = Module clock output Disabled. * | | |1 = Module clock output Enabled. * | | |Note: If this bit is enabled, PC.0 will be configured to module clock output and the setting of PC0_MFP will be ineffective */ __IO uint32_t MCLKO; /** * WK_INTSTS * =================================================================================================== * Offset: 0x30 Wake-up interrupt status * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[0] |PD_WK_IS |Wake-Up Interrupt Status In Chip Power-Down Mode * | | |This bit indicates that some event resumes chip from Power-down mode * | | |The status is set if external interrupts, UART, GPIO, RTC, USB, SPI, Timer, WDT, and BOD wake-up occurred. * | | |Write 1 to clear this bit. */ __IO uint32_t WK_INTSTS; } CLK_T;
對照datasheet,只需要看APBCLK的部分就可以了。
功能描述
看門狗定時(shí)器的用途是在軟件出問題時(shí)執(zhí)行系統(tǒng)復(fù)位功能,這可以防止系統(tǒng)無限期地掛起。除此之外,看門狗定時(shí)器還支持將CPU 從掉電模式喚醒的功能,
此外當(dāng) CPU 進(jìn)入掉電模式時(shí),WDT 計(jì)數(shù)器會自動重置。
看門狗定時(shí)器包含一個(gè)18 位的自由運(yùn)行計(jì)數(shù)器,定時(shí)溢出間隔可編程。
接下來的表格給出了看門狗超時(shí)間隔選擇,
而接下來的圖片給出了看門狗中斷信號和復(fù)位信號的時(shí)序。
設(shè)置 WTE (WDT_CTL[3]) 使能看門狗定時(shí)器和WDT 計(jì)數(shù)器開始計(jì)數(shù)。
當(dāng)計(jì)數(shù)器達(dá)到選擇的超時(shí)間隔,看門狗定時(shí)器中斷標(biāo)志W(wǎng)DT_IS 將被立即被置位,并請求WDT 中斷 (如果看門狗定時(shí)器中斷使能位WDT_IE 置位),同時(shí)緊接著超時(shí)事件會有一個(gè)指定的延時(shí)可透過 WTRDSEL 設(shè)置,用戶必須在該指定延時(shí)過期前設(shè)置WTR (WDT_CTL[0]) (看門狗定時(shí)器復(fù)位) 為高來復(fù)位18 位 WDT 計(jì)數(shù)器,以防止芯片復(fù)位。
WTR 位在WDT 計(jì)數(shù)器復(fù)位后由硬件自動清零。
通過設(shè)置WTIS (WDT_CTL[6:4]),有8 種帶指定延時(shí)時(shí)間的超時(shí)間隔可供選擇(上面的表格)。
如果在指定延遲時(shí)間過期后,WDT 計(jì)數(shù)器沒有被清零,看門狗定時(shí)器將置位看門狗定時(shí)器復(fù)位標(biāo)志(WDT_RST_IS),并復(fù)位CPU。
這個(gè)復(fù)位將持續(xù)63 個(gè) WDT 時(shí)鐘 (TRST),然后芯片重啟,并從復(fù)位向量(0x0000_0000) 處重新開始執(zhí)行程序。
WDT_RST_IS 不會被看門狗復(fù)位清零。用戶可用軟件輪詢WDT_RST_IS 來識別復(fù)位源是否WDT。
明白了原理,再看一下它們的寄存器,然后找到對應(yīng)的寄存器,就可以進(jìn)行配置了
寄存器是什么?在我的理解就是地址,這個(gè)地址對應(yīng)著硬件的
下圖是寄存器的基地址和偏移地址:
對應(yīng)的宏定義為:
#define APB1PERIPH_BASE ((uint32_t)0x40000000) ///< APB1 base address #define WDT_BASE (APB1PERIPH_BASE + 0x04000) ///< WDT register base address #define WDT ((WDT_T *) WDT_BASE) ///< Pointer to WDT register structure
上文是WDT的基地址,也就是WDT_BA的部分,而下面是它的寄存器對應(yīng)地址
typedef struct { /** * CTL * =================================================================================================== * Offset: 0x00 Watchdog Timer Control Register * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[0] |WTR |Clear Watchdog Timer * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |Set this bit will clear the Watchdog timer. * | | |0 = No effect. * | | |1 = Reset the contents of the Watchdog timer. * | | |Note: This bit will be auto cleared after few clock cycles. * |[1] |WTRE |Watchdog Timer Reset Function Enable * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |Setting this bit will enable the Watchdog timer reset function. * | | |0 = Watchdog timer reset function Disabled. * | | |1 = Watchdog timer reset function Enabled. * |[2] |WTWKE |Watchdog Timer Wake-Up Function Enable * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |0 = Watchdog timer Wake-up CPU function Disabled. * | | |1 = Wake-up function Enabled so that Watchdog timer time-out can wake up CPU from power-down mode. * |[3] |WTE |Watchdog Timer Enable * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |0 = Watchdog timer Disabled (this action will reset the internal counter). * | | |1 = Watchdog timer Enabled. * |[6:4] |WTIS |Watchdog Timer Interval Selection * | | |This is a protected register. Please refer to open lock sequence to program it. * | | |These three bits select the time-out interval for the Watchdog timer. * | | |This count is free running counter. * | | |Please refer to the Table 5-16. * |[9:8] |WTRDSEL |Watchdog Timer Reset Delay Select * | | |When watchdog timeout happened, software has a time named watchdog reset delay period to clear watchdog timer to prevent watchdog reset happened. * | | |Software can select a suitable value of watchdog reset delay period for different watchdog timeout period. * | | |00 = Watchdog reset delay period is 1026 watchdog clock * | | |01 = Watchdog reset delay period is 130 watchdog clock * | | |10 = Watchdog reset delay period is 18 watchdog clock * | | |11 = Watchdog reset delay period is 3 watchdog clock * | | |This register will be reset if watchdog reset happened */ __IO uint32_t CTL; /** * IER * =================================================================================================== * Offset: 0x04 Watchdog Timer Interrupt Enable Register * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[0] |WDT_IE |Watchdog Timer Interrupt Enable * | | |0 = Watchdog timer interrupt Disabled. * | | |1 = Watchdog timer interrupt Enabled. */ __IO uint32_t IER; /** * ISR * =================================================================================================== * Offset: 0x08 Watchdog Timer Interrupt Status Register * --------------------------------------------------------------------------------------------------- * |Bits |Field |Descriptions * | :----: | :----: | :---- | * |[0] |IS |Watchdog Timer Interrupt Status * | | |If the Watchdog timer interrupt is enabled, then the hardware will set this bit to indicate that the Watchdog timer interrupt has occurred. * | | |If the Watchdog timer interrupt is not enabled, then this bit indicates that a time-out period has elapsed. * | | |0 = Watchdog timer interrupt did not occur. * | | |1 = Watchdog timer interrupt occurs. * | | |Note: This bit is read only, but can be cleared by writing "1" to it. * |[1] |RST_IS |Watchdog Timer Reset Status * | | |When the Watchdog timer initiates a reset, the hardware will set this bit. * | | |This flag can be read by software to determine the source of reset. * | | |Software is responsible to clear it manually by writing "1" to it. * | | |If WTRE is disabled, then the Watchdog timer has no effect on this bit. * | | |0 = Watchdog timer reset did not occur. * | | |1 = Watchdog timer reset occurs. * | | |Note: This bit is read only, but can be cleared by writing "1" to it. * |[2] |WAKE_IS |Watchdog Timer Wake-Up Status * | | |If Watchdog timer causes system to wake up from power-down mode, this bit will be set to high. * | | |It must be cleared by software with a write "1" to this bit. * | | |0 = Watchdog timer does not cause system wake-up. * | | |1 = Wake system up from power-down mode by Watchdog time-out. * | | |Note1: When system in power-down mode and watchdog time-out, hardware will set WDT_WAKE_IS and WDT_IS. * | | |Note2: After one engine clock, this bit can be cleared by writing "1" to it */ __IO uint32_t ISR; } WDT_T;
#define WDT_CTL_WTR_Msk (0x1ul << WDT_CTL_WTR_Pos) /*!< WDT_T::CTL: WTR Mask */ #define WDT_CTL_WTRE_Pos (1) /*!< WDT_T::CTL: WTRE Position */ #define WDT_CTL_WTRE_Msk (0x1ul << WDT_CTL_WTRE_Pos) /*!< WDT_T::CTL: WTRE Mask */ #define WDT_CTL_WTWKE_Pos (2) /*!< WDT_T::CTL: WTWKE Position */ #define WDT_CTL_WTWKE_Msk (0x1ul << WDT_CTL_WTWKE_Pos) /*!< WDT_T::CTL: WTWKE Mask */ #define WDT_CTL_WTE_Pos (3) /*!< WDT_T::CTL: WTE Position */ #define WDT_CTL_WTE_Msk (0x1ul << WDT_CTL_WTE_Pos) /*!< WDT_T::CTL: WTE Mask */ #define WDT_CTL_WTIS_Pos (4) /*!< WDT_T::CTL: WTIS Position */ #define WDT_CTL_WTIS_Msk (0x7ul << WDT_CTL_WTIS_Pos) /*!< WDT_T::CTL: WTIS Mask */ #define WDT_CTL_WTRDSEL_Pos (8) /*!< WDT_T::CTL: WTRDSEL Position */ #define WDT_CTL_WTRDSEL_Msk (0x3ul << WDT_CTL_WTRDSEL_Pos) /*!< WDT_T::CTL: WTRDSEL Mask */ //以上部分是否感到眼熟?跟WDT_CTL的地址是一一對應(yīng)的,后面也是一樣,也就是說0bit是WTR,1是WTRE.WTIS是第四位,但是它本身占三位, //所以下一個(gè)寄存器就會移三位,又保留了一位,所以左移第八位。后面都是一樣的
#define WDT_IER_IE_Pos (0) /*!< WDT_T::IER: IE Position */ #define WDT_IER_IE_Msk (0x1ul << WDT_IER_IE_Pos) /*!< WDT_T::IER: IE Mask */ #define WDT_ISR_IS_Pos (0) /*!< WDT_T::ISR: IS Position */ #define WDT_ISR_IS_Msk (0x1ul << WDT_ISR_IS_Pos) /*!< WDT_T::ISR: IS Mask */ #define WDT_ISR_RST_IS_Pos (1) /*!< WDT_T::ISR: RST_IS Position */ #define WDT_ISR_RST_IS_Msk (0x1ul << WDT_ISR_RST_IS_Pos) /*!< WDT_T::ISR: RST_IS Mask */ #define WDT_ISR_WAKE_IS_Pos (2) /*!< WDT_T::ISR: WAKE_IS Position */ # define WDT_ISR_WAKE_IS_Msk (0x1ul << WDT_ISR_WAKE_IS_Pos) /*!< WDT_T::ISR: WAKE_IS Mask */ /**@}*/ /* WDT_CONST */ /**@}*/ /* end of WDT register group */ 上面是它的最底層部分,您看懂了么?其實(shí)就是強(qiáng)制地址轉(zhuǎn)換,分配地址,然后根據(jù)地址進(jìn)行。配置寄存器就是給他們一個(gè)輸入,或者輸出。不過雖然本質(zhì)就是這樣,但操作并不簡單, 因?yàn)樗麄兊募拇嫫骱芏?,而且大多要涉及外圍電路和外部器件,任何一個(gè)環(huán)節(jié)出錯(cuò),都不可能達(dá)到效果,雖然麻煩,但大部分都是有規(guī)律的。 這里穿插一則寄存器的小知識 在存儲器 Block2 這塊區(qū)域,設(shè)計(jì)的是片上外設(shè),它們以四個(gè)字節(jié)為一個(gè)單元,共32bit,每一個(gè)單元對應(yīng)不同的功能,當(dāng)我們控制這些單元時(shí)就可以驅(qū)動外設(shè)工作。 我們可以找到每個(gè)單元的起始地址,然后通過 C語言指針的操作方式來訪問這些單元,如果每次都是通過這種地址的方式來訪問,不僅不好記憶還容易出錯(cuò), 這時(shí)我們可以根據(jù)每個(gè)單元功能的不同,以功能為名給這個(gè)內(nèi)存單元取一個(gè)別名,這個(gè)別名就是我們經(jīng)常說的寄存器, 這個(gè)給已經(jīng)分配好地址的有特定功能的內(nèi)存單元取別名的過程就叫寄存器映射。 當(dāng)然寄存器有軟件的也有硬件的,電路方面在我的新浪博客上面會有描述。
再插一則小知識,是關(guān)于強(qiáng)制類型轉(zhuǎn)換的
關(guān)于一個(gè)
int *ptr=(int *)(&a+1)
問題的探討
網(wǎng)絡(luò)上看到這樣一道有意思的題目,是關(guān)于數(shù)組與指針的問題,描述如下:
main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}
輸出為:2,5
請解釋以上代碼的輸出結(jié)果。答案如下:
*(a+1)其實(shí)很簡單就是指a[1],輸出為2. 問題關(guān)鍵就在于第二個(gè)點(diǎn),
*(ptr-1)輸出為多少?
解釋如下,&a+1不是首地址+1,系統(tǒng)會認(rèn)為加了一個(gè)整個(gè)a數(shù)組,偏移了整個(gè)數(shù)組a的大?。ㄒ簿褪?個(gè)int的大?。K?/p>
int *ptr=(int *)(&a+1);其實(shí)ptr實(shí)際是&(a[5]),也就是a+5. 原因?yàn)楹文兀?/p>
&a是數(shù)組指針,其類型為int(*)[5]; 而指針加1要根據(jù)指針類型加上一定的值,不同類型的指針+1之后增加的大小不同,
a是長度為5的int數(shù)組指針,所以要加5*sizeof(int),所以ptr實(shí)際是a[5],但是ptr與(&a+1)類型是不一樣的,這點(diǎn)非常重要,所以ptr-1只會減去sizeof(int*),
a,&a的地址是一樣的,但意思就不一樣了,a是數(shù)組首地址,也就是a[0]的地址,&a是對象(數(shù)組)首地址,a+1是數(shù)組下一元素的地址,即a[1],&a+1是下一個(gè)對象的地址,即a[5]。
小端:低地址存放低位數(shù)據(jù);
大端:低地址存放高位數(shù)據(jù);
而網(wǎng)絡(luò)中傳輸是用大端。
用代碼實(shí)現(xiàn)大小端利用了共用體的原理實(shí)現(xiàn)判斷是比較簡單的一個(gè)方法:
由于共用體中的所有元素都存放在一塊內(nèi)存空間中,而b的起始地址是從int型的起始地址對齊的。所以對一個(gè)int型的數(shù)據(jù)進(jìn)行寫1,如果是大端的話,char型的b就會為1,否則b就為0.
接下來,我們再來看看,上面所包含的寄存器,這是一個(gè)很大的量,請耐心看完,相信會有收獲的。
既然我們熟悉了底層。那么我們當(dāng)然不會止步于此,應(yīng)用層的東西,當(dāng)然也要做。
在功能描述那一章節(jié)時(shí),我們其實(shí)已經(jīng)明白了,它的具體操作和步驟,但是為了我們更加清楚明白和方便調(diào)用,我們決定采用庫函數(shù)的形式,來講述這個(gè)應(yīng)用,首先我想說的是這只是一個(gè)小的官方例程,如果后續(xù)會有大型的項(xiàng)目,不涉及保密的話,我會把它共享出來
既然我們要用看門狗,既然要使用它,我們當(dāng)然要打開它,即進(jìn)行初始化。
首先選擇時(shí)鐘
void SYS_Init(void) { /*---------------------------------------------------------------------------------------------------------*/ /* Init System Clock */ /*---------------------------------------------------------------------------------------------------------*/ /* Unlock protected registers */ SYS_UnlockReg(); /* Enable External XTAL (4~24 MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HXT_EN_Msk); /* Enable LIRC */ CLK_EnableXtalRC(CLK_PWRCTL_LIRC_EN_Msk); /* Waiting for 12MHz clock ready */ CLK_WaitClockReady( CLK_CLKSTATUS_HXT_STB_Msk); /* Waiting for LIRC clock ready */ CLK_WaitClockReady( CLK_CLKSTATUS_LIRC_STB_Msk); /* Switch HCLK clock source to HXT */ CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HXT,CLK_HCLK_CLK_DIVIDER(1)); /* Enable IP clock */ CLK_EnableModuleClock(UART0_MODULE); CLK_EnableModuleClock(WDT_MODULE);
/*
#define WDT_MODULE ((1UL<<31)|(3<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_WDT_EN_Pos )
/*!< Watchdog Timer Module */
#define MODULE_NoMsk 0x0 /*!< Not mask on MODULE index */
#define WDT_MODULE ((1UL<<31)|(3<<29)|(MODULE_NoMsk<<25)|( 0<<20)|(0<<18)|(MODULE_NoMsk<<10)|( 0<<5)|CLK_APBCLK_WDT_EN_Pos )
#define CLK_APBCLK_WDT_EN_Pos (0) /*!< CLK_T::APBCLK: WDT_EN Position */
#define CLK_APBCLK_WDT_EN_Msk (0x1ul << CLK_APBCLK_WDT_EN_Pos) /*!< CLK_T::APBCLK: WDT_EN Mask
*/
/* Select IP clock source */ CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_UART_CLK_DIVIDER(1)); CLK_SetModuleClock(WDT_MODULE, 0, 0); /* Update System Core Clock */ /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */ SystemCoreClockUpdate(); /*---------------------------------------------------------------------------------------------------------*/ /* Init I/O Multi-function */ /*---------------------------------------------------------------------------------------------------------*/ /* Set GPB multi-function pins for UART0 RXD and TXD */ SYS->PB_L_MFP &= ~(SYS_PB_L_MFP_PB0_MFP_Msk | SYS_PB_L_MFP_PB1_MFP_Msk); SYS->PB_L_MFP |= (SYS_PB_L_MFP_PB1_MFP_UART0_TX | SYS_PB_L_MFP_PB0_MFP_UART0_RX); /* Lock protected registers */ SYS_LockReg(); }
void CLK_SetModuleClock(uint32_t u32ModuleIdx, uint32_t u32ClkSrc, uint32_t u32ClkDiv)
{
uint32_t u32tmp=0,u32sel=0,u32div=0;
if(MODULE_CLKDIV_Msk(u32ModuleIdx)!=MODULE_NoMsk) {u32div =(uint32_t)&CLK->CLKDIV0+((MODULE_CLKDIV(u32ModuleIdx))*4);u32tmp = *(volatile uint32_t *)(u32div);u32tmp = ( u32tmp & ~(MODULE_CLKDIV_Msk(u32ModuleIdx)<<MODULE_CLKDIV_Pos(u32ModuleIdx)) ) | u32ClkDiv;*(volatile uint32_t *)(u32div) = u32tmp;}
#define MODULE_CLKDIV_Msk(x) ((x >>10) & 0xff) /*!< Calculate CLKDIV mask offset on MODULE index */
#define MODULE_CLKDIV_Msk(x) ((x >>10) & 0xff) /*!< Calculate CLKDIV mask offset on MODULE index */
#define MODULE_CLKDIV_Pos(x) ((x >>5 ) & 0x1f) /*!< Calculate CLKDIV position offset on MODULE index */
#define MODULE_CLKDIV_Pos(x) ((x >>5 ) & 0x1f) /*!< Calculate CLKDIV position offset on MODULE index */
( u32tmp & ~(MODULE_CLKDIV_Msk(u32ModuleIdx)<<MODULE_CLKDIV_Pos(u32ModuleIdx)) ) | u32ClkDiv;
~((1110 0000 0000 0000 0000 0000 0000>>10) <<(1110 0000 0000 0000 0000 0000 >>5))|u32Div mingbaile zhongyv
// 1110 0000 0000 0000 0000 0000 0000 0000 右移5位為0000 1110 0000 0000 0000 0000 0000 0000 0000
// 1110 0000 0000 0000 0000 0000 0000 0000 右移10位為 0000 0000 0111 0000 0000 0000 0000 0000 0000
//所謂模塊就是給時(shí)鐘的WDT_EN位一個(gè)使能
if(MODULE_CLKSEL_Msk(u32ModuleIdx)!=MODULE_NoMsk) {u32sel = (uint32_t)&CLK->CLKSEL0+((MODULE_CLKSEL(u32ModuleIdx))*4);u32tmp = *(volatile uint32_t *)(u32sel);u32tmp = ( u32tmp & ~(MODULE_CLKSEL_Msk(u32ModuleIdx)<<MODULE_CLKSEL_Pos(u32ModuleIdx)) ) | u32ClkSrc;*(volatile uint32_t *)(u32sel) = u32tmp;}}
即我們剛開始所講的設(shè)置 WTE (WDT_CTL[3]) 使能看門狗定時(shí)器和WDT 計(jì)數(shù)器開始計(jì)數(shù)。(在功能描述那一部分第一句)
/*** @brief This function make WDT module start counting with different time-out interval* @param[in] u32TimeoutInterval Time-out interval period of WDT module. Valid values are:* - \ref WDT_TIMEOUT_2POW4* - \ref WDT_TIMEOUT_2POW6* - \ref WDT_TIMEOUT_2POW8* - \ref WDT_TIMEOUT_2POW10* - \ref WDT_TIMEOUT_2POW12* - \ref WDT_TIMEOUT_2POW14* - \ref WDT_TIMEOUT_2POW16* - \ref WDT_TIMEOUT_2POW18* @param[in] u32ResetDelay Reset delay period while WDT time-out happened. Valid values are:* - \ref WDT_RESET_DELAY_3CLK* - \ref WDT_RESET_DELAY_18CLK* - \ref WDT_RESET_DELAY_130CLK* - \ref WDT_RESET_DELAY_1026CLK* @param[in] u32EnableReset Enable WDT reset system function. Valid values are TRUE and FALSE* @param[in] u32EnableWakeup Enable WDT wake-up system function. Valid values are TRUE and FALSE* @return None*/
void WDT_Open(uint32_t u32TimeoutInterval, uint32_t u32ResetDelay, uint32_t u32EnableReset, uint32_t u32EnableWakeup) { WDT->CTL = u32TimeoutInterval | u32ResetDelay | WDT_CTL_WTE_Msk | (u32EnableReset << WDT_CTL_WTRE_Pos) | (u32EnableWakeup << WDT_CTL_WTWKE_Pos); return; }
這個(gè)意思就是選擇它的超時(shí)時(shí)間,和復(fù)位延遲時(shí)間和啟動系統(tǒng)功能,和復(fù)位系統(tǒng)功能
u32TimeoutInterval WDT模塊的超時(shí)間隔時(shí)間。有效值是:
* - \ ref WDT_TIMEOUT_2POW4
* - \ ref WDT_TIMEOUT_2POW6
* - \ ref WDT_TIMEOUT_2POW8
* - \ ref WDT_TIMEOUT_2POW10
* - \ ref WDT_TIMEOUT_2POW12
* - \ ref WDT_TIMEOUT_2POW14
* - \ ref WDT_TIMEOUT_2POW16
* - \ ref WDT_TIMEOUT_2POW18
* @param [in] u32ResetDelay發(fā)生WDT超時(shí)的復(fù)位延遲時(shí)間。有效值是:
* - \ ref WDT_RESET_DELAY_3CLK
* - \ ref WDT_RESET_DELAY_18CLK
* - \ ref WDT_RESET_DELAY_130CLK
* - \ ref WDT_RESET_DELAY_1026CLK
* @param [in] u32EnableReset啟用WDT復(fù)位系統(tǒng)功能。有效值為TRUE和FALSE
* @param [in] u32EnableWakeup啟用WDT喚醒系統(tǒng)功能。有效值為TRUE和FALSE
* @返回?zé)o
* /
對應(yīng)的庫函數(shù)與表格分別是:
#define WDT_TIMEOUT_2POW4 (0UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^4 * WDT clocks */ #define WDT_TIMEOUT_2POW6 (1UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^6 * WDT clocks */ #define WDT_TIMEOUT_2POW8 (2UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^8 * WDT clocks */ #define WDT_TIMEOUT_2POW10 (3UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^10 * WDT clocks */ #define WDT_TIMEOUT_2POW12 (4UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^12 * WDT clocks */ #define WDT_TIMEOUT_2POW14 (5UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^14 * WDT clocks */ #define WDT_TIMEOUT_2POW16 (6UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^16 * WDT clocks */ #define WDT_TIMEOUT_2POW18 (7UL << WDT_CTL_WTIS_Pos) /*!< WDT setting for timeout interval = 2^18 * WDT clocks */ #define WDT_RESET_DELAY_3CLK (3UL << WDT_CTL_WTRDSEL_Pos) /*!< WDT setting reset delay to 3 WDT clocks */ #define WDT_RESET_DELAY_18CLK (2UL << WDT_CTL_WTRDSEL_Pos) /*!< WDT setting reset delay to 18 WDT clocks */ #define WDT_RESET_DELAY_130CLK (1UL << WDT_CTL_WTRDSEL_Pos) /*!< WDT setting reset delay to 130 WDT clocks */ #define WDT_RESET_DELAY_1026CLK (0UL << WDT_CTL_WTRDSEL_Pos) /*!< WDT setting reset delay to 1026 WDT clocks */
我們看一看第二句:
當(dāng)計(jì)數(shù)器達(dá)到選擇的超時(shí)間隔,看門狗定時(shí)器中斷標(biāo)志W(wǎng)DT_IS將被立即被置位,并請求WDT 中斷 (如果看門狗定時(shí)器中斷使能位WDT_IE 置位),同時(shí)緊接著超時(shí)事件會有一個(gè)指定的延時(shí)可透過 WTRDSEL 設(shè)置,用戶必須在該指定延時(shí)過期前設(shè)置WTR (WDT_CTL[0]) (看門狗定時(shí)器復(fù)位) 為高來復(fù)位18 位 WDT 計(jì)數(shù)器,以防止芯片復(fù)位。
請求中斷就得先有中斷,使能中斷:
/**
* @brief This function enables the WDT time-out interrupt
* @param None
* @return None
*/
__STATIC_INLINE void WDT_EnableInt(void) { WDT->IER = WDT_IER_IE_Msk; return; }
/** \brief Enable External Interrupt \details Enables a device-specific interrupt in the NVIC interrupt controller. \param [in] IRQn External interrupt number. Value cannot be negative. */ __STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) { NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); }
這兩個(gè)中斷,一個(gè)是WDT使能中斷,一個(gè)是外部中斷。我們還要利用定時(shí)器進(jìn)行喂狗操作,所謂喂狗:
void WDT_IRQHandler(void)
{
// Clear WDT interrupt flag
WDT_CLEAR_TIMEOUT_INT_FLAG();
// Check WDT wake up flag
if(WDT_GET_TIMEOUT_WAKEUP_FLAG()) {
printf("Wake up by WDT\n");
// Clear WDT wake up flag
WDT_CLEAR_TIMEOUT_WAKEUP_FLAG();
}
}
這里面涉及的庫函數(shù)有下面這些:看完您是否明白了?
#define WDT_ISR_WAKE_IS_Msk (0x1ul << WDT_ISR_WAKE_IS_Pos) /*!< WDT_T::ISR: WAKE_IS Mask */
#define WDT_GET_TIMEOUT_WAKEUP_FLAG() (WDT->ISR & WDT_ISR_WAKE_IS_Msk ? 1 : 0)
#define WDT_CLEAR_TIMEOUT_WAKEUP_FLAG() (WDT->ISR = WDT_ISR_WAKE_IS_Msk)
那么?功能與描述最后這一句,WDT_RST_IS 不會被看門狗復(fù)位清零。用戶可用軟件輪詢WDT_RST_IS 來識別復(fù)位源是否WDT。
然后,上今天的主菜,主程序上場:
/****************************************************************************** * @file main.c * @version V1.00 * $Revision: 3 $ * $Date: 14/09/11 7:39p $ * @brief Use WDT to wake up system from Power-down mode periodically. * * @note * Copyright (C) 2013-2014 Nuvoton Technology Corp. All rights reserved. *****************************************************************************/ #include <stdio.h> #include "Nano100Series.h" void WDT_IRQHandler(void) { // Clear WDT interrupt flag WDT_CLEAR_TIMEOUT_INT_FLAG(); // Check WDT wake up flag if(WDT_GET_TIMEOUT_WAKEUP_FLAG()) { printf("Wake up by WDT\n"); // Clear WDT wake up flag WDT_CLEAR_TIMEOUT_WAKEUP_FLAG(); } } void SYS_Init(void) { /*---------------------------------------------------------------------------------------------------------*/ /* Init System Clock */ /*---------------------------------------------------------------------------------------------------------*/ /* Unlock protected registers */ SYS_UnlockReg(); /* Enable External XTAL (4~24 MHz) */ CLK_EnableXtalRC(CLK_PWRCTL_HXT_EN_Msk); /* Enable LIRC */ CLK_EnableXtalRC(CLK_PWRCTL_LIRC_EN_Msk); /* Waiting for 12MHz clock ready */ CLK_WaitClockReady( CLK_CLKSTATUS_HXT_STB_Msk); /* Waiting for LIRC clock ready */ CLK_WaitClockReady( CLK_CLKSTATUS_LIRC_STB_Msk); /* Switch HCLK clock source to HXT */ CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HXT,CLK_HCLK_CLK_DIVIDER(1)); /* Enable IP clock */ CLK_EnableModuleClock(UART0_MODULE); CLK_EnableModuleClock(WDT_MODULE); /* Select IP clock source */ CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART_S_HXT, CLK_UART_CLK_DIVIDER(1)); CLK_SetModuleClock(WDT_MODULE, 0, 0); /* Update System Core Clock */ /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */ SystemCoreClockUpdate(); /*---------------------------------------------------------------------------------------------------------*/ /* Init I/O Multi-function */ /*---------------------------------------------------------------------------------------------------------*/ /* Set GPB multi-function pins for UART0 RXD and TXD */ SYS->PB_L_MFP &= ~(SYS_PB_L_MFP_PB0_MFP_Msk | SYS_PB_L_MFP_PB1_MFP_Msk); SYS->PB_L_MFP |= (SYS_PB_L_MFP_PB1_MFP_UART0_TX | SYS_PB_L_MFP_PB0_MFP_UART0_RX); /* Lock protected registers */ SYS_LockReg(); } int32_t main (void) { /* Init System, IP clock and multi-function I/O In the end of SYS_Init() will issue SYS_LockReg() to lock protected register. If user want to write protected register, please issue SYS_UnlockReg() to unlock protected register if necessary */ SYS_Init(); /* Init UART to 115200-8n1 for print message */ UART_Open(UART0, 115200); printf("\nThis sample code demonstrate using WDT to wake system up from power down mode\n"); // WDT register is locked, so it is necessary to unlock protect register before configure WDT SYS_UnlockReg(); // WDT timeout every 2^14 WDT clock, disable system reset, enable wake up system WDT_Open(WDT_TIMEOUT_2POW14, 0, FALSE, TRUE); // Enable WDT timeout interrupt WDT_EnableInt(); NVIC_EnableIRQ(WDT_IRQn); while(1) { // Wait 'til UART FIFO empty to get a cleaner console out while(!UART_IS_TX_EMPTY(UART0)); CLK_PowerDown(); } } /*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/
這其中還有一些我沒有講的太清楚,放心,我會讓各位都清楚明白的,我會慢慢去修正,歡迎您的指點(diǎn)
失敗正常,跌倒也正常,但是喪失了自信和斗志,只會沉淪,永遠(yuǎn)見不到太陽。常?;孟胗幸惶煳以鯓釉鯓?,但是夢醒來的時(shí)候,卻發(fā)現(xiàn)自己一無所有,要想得到,還得繼續(xù)奔跑。
掃碼關(guān)注我們
傳真:0755-82591176
郵箱:vicky@yingtexin.net
地址:深圳市龍華區(qū)民治街道民治大道973萬眾潤豐創(chuàng)業(yè)園A棟2樓A08