123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- #include "SN_STOP.h"
- /*
- 文件名:SN_STOP.c/.h
- 作者: SN_FAE_黄泽洪
- 免责声明:无版权,可随意传播和篡改,该代码仅供开发参考,如需使用请自行验证
- 本人不担负商业使用上带来的风险。
- */
- /*
- 方法一:使用LPTIMER唤醒休眠
- //在SN_STOP.c的文件中添加用户的关闭函数和初始函数
- //退出休眠后,要重新开启的片上设备函数列表,将函数添加到此列表中
- static void OPEN(void){
-
- SN_SYSCLK_set(SYSCLK_48MHZ); //休眠退出后重新初始系统时钟
- std_delay_init();
-
- return;
- }
- //进入休眠前,要关闭的片上设备函数列表,将函数添加到此列表中
- static void CLOSE(void){
-
-
-
- //暂时没有
-
- return;
- }
-
- //在main.c文件里面
- uint8_t stop = 1;
- uint8_t k = 0 ;
-
- int main(void){
- SN_SYSCLK_set(SYSCLK_48MHZ);
- std_delay_init();
- std_delayms(3000);
- SN_GPIO_PIN_init(GPIOA ,GPIO_PIN_5 , GPIO_MODE_OUTPUT ,GPIO_PULLUP ,GPIO_OUTPUT_OPENDRAIN);
- SN_GPIO_PIN_toggle(GPIOA, GPIO_PIN_5);
-
- SN_LPtim_Rouse( 3000 ); //范围0x0000 - (0xffff-1) 使用lptimer唤醒
-
- while(1){
- if(stop){
- SN_STOP_EN(); //进入休眠
- SN_GPIO_PIN_toggle(GPIOA, GPIO_PIN_5); //退出休眠后翻转io
- SN_LPtim_ARR(3000+k*100); //修改下一次的休眠时间
- }
- k++;
- }
- }
- 方法二:使用触发唤醒
- //在SN_STOP.c的文件中添加用户的关闭函数和初始函数
- //退出休眠后,要重新开启的片上设备函数列表,将函数添加到此列表中
- static void OPEN(void){
-
- SN_SYSCLK_set(SYSCLK_48MHZ); //休眠退出后重新初始系统时钟
- std_delay_init();
-
- return;
- }
- //进入休眠前,要关闭的片上设备函数列表,将函数添加到此列表中
- static void CLOSE(void){
-
-
-
- //暂时没有
-
- return;
- }
-
- //在main.c文件里面
- uint8_t stop = 1;
- uint8_t k = 0 ;
-
- void LED(void){ //空的回调函数
-
- return;
- }
-
-
- int main(void){
- SN_SYSCLK_set(SYSCLK_48MHZ);
- std_delay_init();
- std_delayms(3000);
- SN_GPIO_PIN_init(GPIOA ,GPIO_PIN_5 , GPIO_MODE_OUTPUT ,GPIO_PULLUP ,GPIO_OUTPUT_OPENDRAIN);
- SN_GPIO_PIN_toggle(GPIOA, GPIO_PIN_5);
-
- SN_EXIT_set(GPIOA,GPIO_PIN_1,GPIO_PULLUP,LED,EXTI_TRIGGER_FALLING,NVIC_PRIO_3); //使能IO触发
-
-
- while(1){
- if(stop){
- SN_STOP_EN(); //进入休眠
- SN_GPIO_PIN_toggle(GPIOA, GPIO_PIN_5); //退出休眠后翻转io
- SN_LPtim_ARR(3000+k*100); //修改下一次的休眠时间
- }
- k++;
- }
- }
- */
- //休眠时间
- __IO uint16_t STOP_ARR = 0;
- //LPTIME标志
- __IO uint8_t LPTIME_FLG = 0;
- /*========================================================================================================== */
- /* 用户要将设备关闭和启动的接口放到下面的列表里面 |*/
- /*========================================================================================================== */
- //进入休眠前,要关闭的片上设备函数列表,将函数添加到此列表中
- static void CLOSE(void){
-
-
-
-
-
- return;
- }
- //退出休眠后,要重新开启的片上设备函数列表,将函数添加到此列表中
- static void OPEN(void){
-
- SN_SYSCLK_set(SYSCLK_48MHZ); //休眠退出后重新初始系统时钟
- std_delay_init();
-
-
- return;
- }
- /*==========================================================================================================*/
-
- /*
- 函数名称:SN_STOP_IN()
- 函数功能:进入休眠,M0内核进入休眠
- 参数:无
- 返回:无
-
- */
- void SN_STOP_EN(void){
-
- //进入休眠前关闭片上外设
- CLOSE();
-
- //进入休眠链接CMSIS接口,进入stop模式-------------------------------------------------------------------------in stop
- std_lptim_interrupt_enable(LPTIM_INTERRUPT_ARRM);
- std_lptim_enable(); //使能LPTIM
-
- if((STOP_ARR>0) && LPTIME_FLG){
- std_lptim_set_auto_reload(STOP_ARR);/* 启动LPTIM1计数 */
- std_lptim_start_counter(LPTIM_COUNT_SINGLE); //单次
- }
-
- std_pmu_enter_stop(PMU_MODE, PMU_ENTRY_LOWPOWER_MODE_WFE); //进入stop模式
- //----------------------------------------退出休眠继续执行下面的代码------------------------------------------out stop
- if(LPTIME_FLG){ std_lptim_disable(); } //关闭LPTIM
-
- //推出休眠重新开启的片上外设与系统时钟
- OPEN();
-
- }
- /*
- 函数名称:SN_LPtim_Rouse()
- 函数功能:使用系统时钟唤醒,初始化一次
- 参数:唤醒的计数值
- (周期和频率,在SN_STOP.h里面的宏定义修改,LPTIM定时器的工作参数)
- 返回:无
-
- 注意:RCL的时钟是32Khz
- 休眠时间计算公式: (32k/LPTIM_PRESCALER_DIV_x )*CNT = 休眠时间
-
- */
- void SN_LPtim_Rouse( uint16_t cnt ){
-
-
- STOP_ARR = cnt;
- SN_LPtim_SN_LPtim_EN();
-
- /* 使能RCL时钟并等待时钟稳定 */
- std_rcc_rcl_enable();
- while(std_rcc_get_rcl_ready() != RCC_CSR2_RCLRDY);
-
- /* 选择LPTIM1的时钟源为RCL */
- std_rcc_set_lptim1clk_source(RCC_LPTIM1_ASYNC_CLK_SRC_RCL);
-
- /* 使能LPTIM1时钟 */
- std_rcc_apb1_clk_enable(RCC_PERIPH_CLK_LPTIM1);
-
- std_lptim_disable(); //关闭LPTIM
-
- /* 设置LPTIM1预分频器 */
- std_lptim_set_prescaler(LPTIM_PRESCALER_DIV_x);
-
- /* 禁止LPTIM1中断唤醒*/
- std_exti_interrupt_disable(EXTI_LINE_LPTIM1);
-
- /* 使能LPTIM1事件唤醒 */
- std_exti_event_enable(EXTI_LINE_LPTIM1);
-
-
- // NVIC_SetPriority(LPTIM1_IRQn, NVIC_PRIO_0);
- // NVIC_EnableIRQ(LPTIM1_IRQn);
- }
- /*
- 函数名称:SN_LPtim_ARR
- 函数功能:更新使用系统时钟唤醒时间
- 参数:唤醒的计数值
- 返回:无
-
- 注意:
-
- */
- void SN_LPtim_ARR(uint16_t cnt){
- STOP_ARR = cnt;
- }
- /*
- 函数名称:SN_LPtim_Stop
- 函数功能:停用LPtim唤醒
- 参数:无
- 返回:无
-
- 注意:
-
- */
- void SN_LPtim_SN_LPtim_Stop(void){
- LPTIME_FLG = 0; //不使用lptime唤醒
- std_lptim_disable(); //关闭lptime
- }
-
-
- /*
- 函数名称:SN_LPtim_EN
- 函数功能:重新使用LPtim唤醒
- 参数:无
- 返回:无
-
- 注意:
-
- */
- void SN_LPtim_SN_LPtim_EN(void){
- LPTIME_FLG = 1; //使用lptime唤醒
-
- }
-
|