From e3c576d1913062e992fe14e6e7745d55b39e9e20 Mon Sep 17 00:00:00 2001 From: nnhy Date: Fri, 6 Nov 2015 08:19:55 +0000 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B7=B1=E5=BA=A6=E7=9D=A1?= =?UTF-8?q?=E7=9C=A0=E3=80=81=E5=81=9C=E6=AD=A2=E3=80=81=E5=BE=85=E6=9C=BA?= =?UTF-8?q?=E4=B8=89=E7=A7=8D=E4=BD=8E=E5=8A=9F=E8=80=97=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=EF=BC=8C=E5=80=9F=E5=8A=A9=E7=9C=8B=E9=97=A8=E7=8B=97=E5=94=A4?= =?UTF-8?q?=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- RTC.cpp | 32 ++++++++++------- Sys.cpp | 27 +++++++++++++++ Sys.h | 4 +++ WatchDog.cpp | 97 ++++++++++++++++++++++++++++++++-------------------- 4 files changed, 109 insertions(+), 51 deletions(-) diff --git a/RTC.cpp b/RTC.cpp index 9603e55d..f740d2b2 100644 --- a/RTC.cpp +++ b/RTC.cpp @@ -284,27 +284,32 @@ int HardRTC::Sleep(int ms) RTC_AlarmStructInit(&alr); int second = ms / 1000; + int minute = second / 60; - RTC_AlarmCmd( RTC_Alarm_A, DISABLE ); /* Disable the Alarm A */ - alr.RTC_AlarmTime.RTC_H12 = RTC_H12_AM; - alr.RTC_AlarmTime.RTC_Hours = second / 60 / 60; - alr.RTC_AlarmTime.RTC_Minutes = (second / 60) % 60; - alr.RTC_AlarmTime.RTC_Seconds = second % 60; + // 关闭警报 + RTC_AlarmCmd( RTC_Alarm_A, DISABLE ); + alr.RTC_AlarmTime.RTC_H12 = RTC_H12_AM; + alr.RTC_AlarmTime.RTC_Hours = minute / 60; + alr.RTC_AlarmTime.RTC_Minutes = minute % 60; + alr.RTC_AlarmTime.RTC_Seconds = second % 60; - /* Set the Alarm A */ - alr.RTC_AlarmDateWeekDay = 0x31; - alr.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; + // 设置警报 + alr.RTC_AlarmDateWeekDay = 31; + alr.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date; alr.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay; - RTC_SetAlarm( RTC_Format_BIN, RTC_Alarm_A, &alr ); /* Configure the RTC Alarm A register */ + RTC_SetAlarm( RTC_Format_BIN, RTC_Alarm_A, &alr ); - RTC_ITConfig( RTC_IT_ALRA, ENABLE ); /* Enable the RTC Alarm A Interrupt */ + // 打开警报中断 + RTC_ITConfig( RTC_IT_ALRA, ENABLE ); - RTC_AlarmCmd( RTC_Alarm_A, ENABLE ); /* Enable the alarm A */ + // 打开警报 + RTC_AlarmCmd( RTC_Alarm_A, ENABLE ); #endif - /* Wait until last write operation on RTC registers has finished */ + // 等待写入操作完成 RTC_WaitForLastTask2(); + Sys.Trace(1); // 进入低功耗模式 PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); @@ -370,6 +375,7 @@ void AlarmHandler(ushort num, void* param) { SmartIRQ irq; + Sys.Trace(4); HardRTC* rtc = (HardRTC*)param; if(RTC_GetITStatus(RTC_IT_ALR) != RESET) @@ -384,7 +390,7 @@ void AlarmHandler(ushort num, void* param) SYSCLKConfig_STOP(); rtc->LoadTicks(); - //debug_printf("离开低功耗模式\r\n"); + debug_printf("离开低功耗模式\r\n"); } HardRTC* HardRTC::Instance() diff --git a/Sys.cpp b/Sys.cpp index ea28269c..3ee4e4a6 100644 --- a/Sys.cpp +++ b/Sys.cpp @@ -432,6 +432,33 @@ bool TSys::SetTaskPeriod(uint taskid, int period) void TSys::Reset() { NVIC_SystemReset(); } +#include "WatchDog.h" + +void TSys::Stop(uint msTime) +{ + debug_printf("TSys::Stop Time=%d \r\n", msTime); + + if(!msTime) msTime = 0xFFFF; + WatchDog::Start(msTime); + PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); +} + +void TSys::DeepSleep(uint msTime) +{ + debug_printf("TSys::DeepSleep Time=%d \r\n", msTime); + + PWR_EnterSleepMode(PWR_SLEEPEntry_WFI); +} + +void TSys::Standby(uint msTime) +{ + debug_printf("TSys::Standby Time=%d \r\n", msTime); + + if(!msTime) msTime = 0xFFFF; + WatchDog::Start(msTime); + PWR_EnterSTANDBYMode(); +} + void TSys::Start() { Started = true; diff --git a/Sys.h b/Sys.h index 1cfd60c9..53757cdd 100644 --- a/Sys.h +++ b/Sys.h @@ -121,6 +121,10 @@ public: bool Started; void Start(); // 开始系统大循环 + + void Stop(uint msTime = 0); + void DeepSleep(uint msTime = 0); + void Standby(uint msTime = 0); }; extern TSys Sys; //创建一个全局的Sys对象 会在main函数之前执行构造函数(!!!!!) diff --git a/WatchDog.cpp b/WatchDog.cpp index 2361dcf8..d64ca8d7 100644 --- a/WatchDog.cpp +++ b/WatchDog.cpp @@ -59,13 +59,8 @@ WatchDog::~WatchDog() ConfigMax(); } -bool WatchDog::Config(uint ms) +void OpenWatchDog() { - if(ms == 0) - { - debug_printf("WatchDog msTimeout %dms must larger than 0ms\r\n", ms); - return false; - } RCC_LSICmd(ENABLE); /* 检查系统是否从IWDG重置恢复 */ if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET) @@ -75,6 +70,49 @@ bool WatchDog::Config(uint ms) } /* 打开IWDG_PR和IWDG_RLR寄存器的写访问 */ IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); +} + +void SetWatchDog(byte pre, uint reload) +{ + IWDG_SetPrescaler(pre); + /*if(ms < (0x0FFF * 32 / 40)) + { + // IWDG计数器时钟: LSI/32=40KHz/32=1250Hz,每周期0.8ms + IWDG_SetPrescaler(IWDG_Prescaler_32); + } + else + { + // IWDG计数器时钟: LSI/64=40KHz/64=625Hz,每周期0.4ms + IWDG_SetPrescaler(IWDG_Prescaler_64); + + // 直接除以2,后面不用重复计算 + ms >>= 2; + }*/ + + /* 设置计数器重载值为超时时间 + Counter Reload Value = ms / 1000 / IWDG计数器时钟周期 + = ms / 1000 / (1/(LSI/mul)) + = ms * LSI / (mul * 1000) + = ms * 40k / (mul * 1000) + = ms * 40 / mul + */ + IWDG_SetReload(reload); + + /* 重载 IWDG 计数器 */ + IWDG_ReloadCounter(); + + /* 打开 IWDG (LSI将由硬件打开) */ + IWDG_Enable(); +} + +bool WatchDog::Config(uint ms) +{ + if(ms == 0) + { + debug_printf("WatchDog msTimeout %dms must larger than 0ms\r\n", ms); + return false; + } + OpenWatchDog(); byte pre = IWDG_Prescaler_4; int mul = 4; @@ -103,20 +141,6 @@ bool WatchDog::Config(uint ms) debug_printf("WatchDog msTimeout must smaller than %dms\r\n", 0x0FFF * 256 / 40); return false; } - IWDG_SetPrescaler(pre); - /*if(ms < (0x0FFF * 32 / 40)) - { - // IWDG计数器时钟: LSI/32=40KHz/32=1250Hz,每周期0.8ms - IWDG_SetPrescaler(IWDG_Prescaler_32); - } - else - { - // IWDG计数器时钟: LSI/64=40KHz/64=625Hz,每周期0.4ms - IWDG_SetPrescaler(IWDG_Prescaler_64); - - // 直接除以2,后面不用重复计算 - ms >>= 2; - }*/ /* 设置计数器重载值为超时时间 Counter Reload Value = ms / 1000 / IWDG计数器时钟周期 @@ -125,13 +149,7 @@ bool WatchDog::Config(uint ms) = ms * 40k / (mul * 1000) = ms * 40 / mul */ - IWDG_SetReload(ms * 40 / mul); - - /* 重载 IWDG 计数器 */ - IWDG_ReloadCounter(); - - /* 打开 IWDG (LSI将由硬件打开) */ - IWDG_Enable(); + SetWatchDog(pre, ms * 40 / mul); Timeout = ms; @@ -140,13 +158,11 @@ bool WatchDog::Config(uint ms) void WatchDog::ConfigMax() { - /* 打开IWDG_PR和IWDG_RLR寄存器的写访问 */ - IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); + OpenWatchDog(); - // 独立看门狗无法关闭 - IWDG_SetPrescaler(IWDG_Prescaler_256); - IWDG_SetReload(0x0FFF); - IWDG_ReloadCounter(); + SetWatchDog(IWDG_Prescaler_256, 0x0FFF); + + Timeout = 0x0FFF * 256 / 40; } void WatchDog::Feed() @@ -163,11 +179,16 @@ void FeedDogTask(void* param) void WatchDog::Start(uint ms, uint msFeed) { static WatchDog dog; - dog.Config(ms); + static uint tid = 0; - // 减小一点,避免来不及喂狗 - //int us = msFeed * 1000; + if(ms > 0x0FFF) + dog.ConfigMax(); + else + dog.Config(ms); - debug_printf("WatchDog::Start "); - Sys.AddTask(FeedDogTask, &dog, msFeed, msFeed, "看门狗"); + if(!tid && msFeed > 0 && msFeed <= 26000) + { + debug_printf("WatchDog::Start "); + tid = Sys.AddTask(FeedDogTask, &dog, msFeed, msFeed, "看门狗"); + } }