68精品久久久久久欧美,最近中文字幕完整在线看一,久久亚洲男人天堂,最近中文字幕完整视频高清1

您好,歡迎進(jìn)入深圳市穎特新科技有限公司官方網(wǎng)站!

您現(xiàn)在的位置:首頁 新聞資訊 >> 新聞頭條 >> 新唐科技nano100B的看門狗講解
新聞資訊
NEWS INFORMATION

新唐科技nano100B的看門狗講解

關(guān)鍵字:新唐單片機 看門狗 發(fā)布時間:2019-05-22

看門狗定時器的用途是在軟件出問題時執(zhí)行系統(tǒng)復(fù)位功能,這可以防止系統(tǒng)無限期地掛起。除此之外,看門狗定時器還支持將CPU 從掉電模式喚醒的功能?撮T狗定時器包含一個18 位的自由運行計數(shù)器,定時溢出間隔可編程。

特征

18-位自由運行WDT 計數(shù)器用于看門狗定時器超時間隔。
可選擇的超時間隔 (2^4 ~ 2^18),超時間隔為104 ms ~ 26.316 s (如果WDT_CLK = 10 kHz)。
復(fù)位周期 = (1 / 10 kHz) * 63,如果WDT_CLK = 10 kHz 

 

對應(yīng)的寄存器是這個

#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&sup2;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的部分就可以了。

 

功能描述

看門狗定時器的用途是在軟件出問題時執(zhí)行系統(tǒng)復(fù)位功能,這可以防止系統(tǒng)無限期地掛起。除此之外,看門狗定時器還支持將CPU 從掉電模式喚醒的功能,

此外當(dāng) CPU 進(jìn)入掉電模式時,WDT 計數(shù)器會自動重置。

看門狗定時器包含一個18 位的自由運行計數(shù)器,定時溢出間隔可編程。

接下來的表格給出了看門狗超時間隔選擇,

而接下來的圖片給出了看門狗中斷信號和復(fù)位信號的時序。

 

 

設(shè)置 WTE (WDT_CTL[3]) 使能看門狗定時器和WDT 計數(shù)器開始計數(shù)。

當(dāng)計數(shù)器達(dá)到選擇的超時間隔,看門狗定時器中斷標(biāo)志W(wǎng)DT_IS 將被立即被置位,并請求WDT 中斷 (如果看門狗定時器中斷使能位WDT_IE 置位),同時緊接著超時事件會有一個指定的延時可透過 WTRDSEL 設(shè)置,用戶必須在該指定延時過期前設(shè)置WTR (WDT_CTL[0]) (看門狗定時器復(fù)位) 為高來復(fù)位18 位 WDT 計數(shù)器,以防止芯片復(fù)位。

WTR 位在WDT 計數(shù)器復(fù)位后由硬件自動清零。

通過設(shè)置WTIS (WDT_CTL[6:4]),有8 種帶指定延時時間的超時間隔可供選擇(上面的表格)。

如果在指定延遲時間過期后,WDT 計數(shù)器沒有被清零,看門狗定時器將置位看門狗定時器復(fù)位標(biāo)志(WDT_RST_IS),并復(fù)位CPU。

這個復(fù)位將持續(xù)63 個 WDT 時鐘 (TRST),然后芯片重啟,并從復(fù)位向量(0x0000_0000) 處重新開始執(zhí)行程序。

WDT_RST_IS 不會被看門狗復(fù)位清零。用戶可用軟件輪詢WDT_RST_IS 來識別復(fù)位源是否WDT。

明白了原理,再看一下它們的寄存器,然后找到對應(yīng)的寄存器,就可以進(jìn)行配置了

寄存器是什么?在我的理解就是地址,這個地址對應(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)地址

復(fù)制代碼
復(fù)制代碼
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;

復(fù)制代碼

 

復(fù)制代碼
#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是第四位,但是它本身占三位,
//所以下一個寄存器就會移三位,又保留了一位,所以左移第八位。后面都是一樣的
#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 */

上面是它的最底層部分,您看懂了么?其實就是強制地址轉(zhuǎn)換,分配地址,然后根據(jù)地址進(jìn)行。配置寄存器就是給他們一個輸入,或者輸出。不過雖然本質(zhì)就是這樣,但操作并不簡單,
因為他們的寄存器很多,而且大多要涉及外圍電路和外部器件,任何一個環(huán)節(jié)出錯,都不可能達(dá)到效果,雖然麻煩,但大部分都是有規(guī)律的。
這里穿插一則寄存器的小知識

在存儲器 Block2 這塊區(qū)域,設(shè)計的是片上外設(shè),它們以四個字節(jié)為一個單元,共32bit,每一個單元對應(yīng)不同的功能,當(dāng)我們控制這些單元時就可以驅(qū)動外設(shè)工作。
我們可以找到每個單元的起始地址,然后通過 C語言指針的操作方式來訪問這些單元,如果每次都是通過這種地址的方式來訪問,不僅不好記憶還容易出錯,
這時我們可以根據(jù)每個單元功能的不同,以功能為名給這個內(nèi)存單元取一個別名,這個別名就是我們經(jīng)常說的寄存器,
這個給已經(jīng)分配好地址的有特定功能的內(nèi)存單元取別名的過程就叫寄存器映射。

當(dāng)然寄存器有軟件的也有硬件的,電路方面在我的新浪博客上面會有描述。

再插一則小知識,是關(guān)于強制類型轉(zhuǎn)換的

關(guān)于一個

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)其實很簡單就是指a[1],輸出為2. 問題關(guān)鍵就在于第二個點,

*(ptr-1)輸出為多少?

解釋如下,&a+1不是首地址+1,系統(tǒng)會認(rèn)為加了一個整個a數(shù)組,偏移了整個數(shù)組a的大小(也就是5個int的大。K

int *ptr=(int *)(&a+1);其實ptr實際是&(a[5]),也就是a+5. 原因為何呢?

&a是數(shù)組指針,其類型為int(*)[5]; 而指針加1要根據(jù)指針類型加上一定的值,不同類型的指針+1之后增加的大小不同,

a是長度為5的int數(shù)組指針,所以要加5*sizeof(int),所以ptr實際是a[5],但是ptr與(&a+1)類型是不一樣的,這點非常重要,所以ptr-1只會減去sizeof(int*),

a,&a的地址是一樣的,但意思就不一樣了,a是數(shù)組首地址,也就是a[0]的地址,&a是對象(數(shù)組)首地址,a+1是數(shù)組下一元素的地址,即a[1],&a+1是下一個對象的地址,即a[5]。

 

先看下面這個例子:
struct Test
{
    int Num;
    char *pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p;
    假設(shè)p 的值為0x100000。如下表表達(dá)式的值分別為多少?
p + 0x1 = 0x___ ?
(unsigned long)p + 0x1 = 0x___?
(unsigned int*)p + 0x1 = 0x___?
    我相信會有很多人一開始沒看明白這個問題是什么意思。其實我們再仔細(xì)看看,這個知識點似曾相識。一個指針變量與一個整數(shù)相加減,到底該怎么解析呢?還記得前面我們的表達(dá)式“a+1”與“&a+1”之間的區(qū)別嗎?其實這里也一樣。指針變量與一個整數(shù)相加減并不是用指針變量里的地址直接加減這個整數(shù)。這個整數(shù)的單位不是byte 而是元素的個數(shù)。所以:p + 0x1 的值為0x100000+sizof(Test)*0x1。至于此結(jié)構(gòu)體的大小為20byte,前面的章節(jié)已經(jīng)詳細(xì)講解過。所以p +0x1 的值為:0x100014。(0X100000+20(0X100014)),(unsigned long)p + 0x1 的值呢?這里涉及到強制轉(zhuǎn)換,將指針變量p 保存的值強制轉(zhuǎn)換成無符號的長整型數(shù)。任何數(shù)值一旦被強制轉(zhuǎn)換,其類型就改變了。所以這個表達(dá)式其實就是一個無符號的長整型數(shù)加上另一個整數(shù)。所以其值為:0x100001。(unsigned int*)p + 0x1 的值呢?這里的p 被強制轉(zhuǎn)換成一個指向無符號整型的指針。所以其值為0x100000+sizof(unsigned int)*0x1,等于0x100004。上面這個問題似乎還沒啥技術(shù)含量,下面就來個有技術(shù)含量的:
在x86 系統(tǒng)下,其值為多少?
int main()
{
    int a[4]={1,2,3,4};
    int *ptr1=(int *)(&a+1);
    int *ptr2=(int *)((int)a+1);
    printf("%x,%x",ptr1[-1],*ptr2);
    return 0;
}
    一個懂匯編的人,這種題實在是小case。
    下面就來分析分析這個問題:根據(jù)上面的講解,&a+1 與a+1 的區(qū)別已經(jīng)清楚。
    ptr1:將&a+1 的值強制轉(zhuǎn)換成int*類型,賦值給int* 類型的變量ptr,ptr1 肯定指到數(shù)組a 的下一個int 類型數(shù)據(jù)了。
    ptr1[-1]被解析成*(ptr1-1),即ptr1 往后退4 個byte。所以其值為0x4。
    ptr2:按照上面的講解,(int)a+1 的值是元素a[0]的第二個字節(jié)的地址。
   然后把這個地址強制轉(zhuǎn)換成int*類型的值賦給ptr2,也就是說*ptr2 的值應(yīng)該為元素a[0]的第二個字節(jié)開始的連續(xù)4 個byte 的內(nèi)容。
    好,問題就來了,這連續(xù)4 個byte 里到底存了什么東西呢?也就是說元素a[0],a[1]里面的值到底怎么存儲的。這就涉及到系統(tǒng)的大小端模式了,如果懂匯編的話,這根本就不是問題。既然不知道當(dāng)前系統(tǒng)是什么模式,那就得想辦法測試。大小端模式與測試的方法在第一章講解union 關(guān)鍵字時已經(jīng)詳細(xì)討論過了,請翻到彼處參看,這里就不再詳述。我們可以用下面這個函數(shù)來測試當(dāng)前系統(tǒng)的模式。
int checkSystem( )
{
    union check
    {
        int i;
        char ch;
    } c;
    c.i = 1;
    return (c.ch ==1);
}
    如果當(dāng)前系統(tǒng)為大端模式這個函數(shù)返回0;如果為小端模式,函數(shù)返回1。也就是說如果此函數(shù)的返回值為1 的話,*ptr2 的值為0x2000000。
如果此函數(shù)的返回值為0 的話,*ptr2 的值為0x100。
關(guān)于系統(tǒng)的大小端呢,看下文

小端:低地址存放低位數(shù)據(jù);

大端:低地址存放高位數(shù)據(jù);

而網(wǎng)絡(luò)中傳輸是用大端。

用代碼實現(xiàn)大小端利用了共用體的原理實現(xiàn)判斷是比較簡單的一個方法:

[html] view plain copy
 
  1. #include <stdio.h>  
  2. union n{  
  3.     int a;  
  4.     char b;  
  5. };  
  6. int main(){  
  7.     union n ss;  
  8.     ss.a=1;  
  9.     if(ss.b!=0)  
  10.         printf("Little\n");  
  11.     else   
  12.         printf("Big\n");  
  13.     return 0;  
  14. }  

由于共用體中的所有元素都存放在一塊內(nèi)存空間中,而b的起始地址是從int型的起始地址對齊的。所以對一個int型的數(shù)據(jù)進(jìn)行寫1,如果是大端的話,char型的b就會為1,否則b就為0.

接下來,我們再來看看,上面所包含的寄存器,這是一個很大的量,請耐心看完,相信會有收獲的。

 

既然我們熟悉了底層。那么我們當(dāng)然不會止步于此,應(yīng)用層的東西,當(dāng)然也要做。

在功能描述那一章節(jié)時,我們其實已經(jīng)明白了,它的具體操作和步驟,但是為了我們更加清楚明白和方便調(diào)用,我們決定采用庫函數(shù)的形式,來講述這個應(yīng)用,首先我想說的是這只是一個小的官方例程,如果后續(xù)會有大型的項目,不涉及保密的話,我會把它共享出來

既然我們要用看門狗,既然要使用它,我們當(dāng)然要打開它,即進(jìn)行初始化。

首先選擇時鐘

復(fù)制代碼
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

//所謂模塊就是給時鐘的WDT_EN位一個使能

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;}}

 
復(fù)制代碼

 

 

即我們剛開始所講的設(shè)置 WTE (WDT_CTL[3]) 使能看門狗定時器和WDT 計數(shù)器開始計數(shù)。(在功能描述那一部分第一句)

復(fù)制代碼

/*** @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;
}

復(fù)制代碼

這個意思就是選擇它的超時時間,和復(fù)位延遲時間和啟動系統(tǒng)功能,和復(fù)位系統(tǒng)功能

u32TimeoutInterval WDT模塊的超時間隔時間。有效值是:
 * - \ 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超時的復(fù)位延遲時間。有效值是:
 * - \ 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ù)與表格分別是:

復(fù)制代碼
#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 */
復(fù)制代碼

我們看一看第二句:

當(dāng)計數(shù)器達(dá)到選擇的超時間隔,看門狗定時器中斷標(biāo)志W(wǎng)DT_IS將被立即被置位,并請求WDT 中斷 (如果看門狗定時器中斷使能位WDT_IE 置位),同時緊接著超時事件會有一個指定的延時可透過 WTRDSEL 設(shè)置,用戶必須在該指定延時過期前設(shè)置WTR (WDT_CTL[0]) (看門狗定時器復(fù)位) 為高來復(fù)位18 位 WDT 計數(shù)器,以防止芯片復(fù)位。

請求中斷就得先有中斷,使能中斷:

復(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;
}
復(fù)制代碼
復(fù)制代碼
/**
  \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));
}
復(fù)制代碼

 

 

這兩個中斷,一個是WDT使能中斷,一個是外部中斷。我們還要利用定時器進(jìn)行喂狗操作,所謂喂狗:

看門狗定時器(Watchdog Timer ,看門狗)電路一般有一個輸入,這個輸入被稱作"喂狗".
 
MCU 正常工作的時候,每隔一段時間輸出一個信號到喂狗端,給 WDT 清零。如果超過規(guī)定的時間不喂狗(一般在程序跑飛時),WDT 定時超過,就會給出一個復(fù)位信號到MCU,讓MCU 復(fù)位,防止MCU 死機。
 
看門狗需要在規(guī)定時間內(nèi)喂狗,這里所說的“規(guī)定時間”就是看門狗定時器計數(shù)溢出時間,即一旦到達(dá)計數(shù)閾值,看門狗就會產(chǎn)生復(fù)位。CPU必須在這個周期內(nèi)對這個定時器進(jìn)行清零處理,讓看門狗定時器重新計數(shù),防止看門狗產(chǎn)生復(fù)位。

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。

然后,上今天的主菜,主程序上場:

復(fù)制代碼
/******************************************************************************
 * @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. ***/

這其中還有一些我沒有講的太清楚,放心,我會讓各位都清楚明白的,我會慢慢去修正,歡迎您的指點

失敗正常,跌倒也正常,但是喪失了自信和斗志,只會沉淪,永遠(yuǎn)見不到太陽。常;孟胗幸惶煳以鯓釉鯓樱菈粜褋淼臅r候,卻發(fā)現(xiàn)自己一無所有,要想得到,還得繼續(xù)奔跑。

聯(lián)系方式0755-82591179

傳真:0755-82591176

郵箱:vicky@yingtexin.net

地址:深圳市龍華區(qū)民治街道民治大道973萬眾潤豐創(chuàng)業(yè)園A棟2樓A08

和硕县| 诏安县| 宝清县| 古浪县| 武鸣县| 扎兰屯市| 同江市| 德钦县| 阿荣旗| 邹城市| 康平县| 志丹县| 会昌县| 五常市| 陇南市| 洪雅县| 陇西县| 尉犁县| 格尔木市| 鄯善县| 灌阳县| 宁河县| 丽水市| 德州市| 朝阳县| 岳普湖县| 民丰县| 广宁县| 西畴县| 乐昌市| 鄂尔多斯市| 田阳县| 揭西县| 卢龙县| 新密市| 独山县| 闻喜县| 上栗县| 陆川县| 泰和县| 柘荣县|