//THUMB指令不支持汇编内联//采用如下方法实现执行汇编指令WFI__asm void WFI_SET(void){ WFI; }//进入待机模式 //参数说明: // var = 0 ,设定为睡眠模式// var = 1 ,设定为停机模式,电流消耗在20uA左右// var = 2 ,设定为待机模式,电流消耗在2uA左右void Sys_Standby(u8 var){ RCC->APB1ENR |= 1<<28; //使能电源时钟 switch(var) { case 0:{ break; } //WFI进入睡眠模式 case 1:{ //PDDS+LPDS+SLEEPDEEP+WFI进入停机模式 SCB->SCR |= 1<<2; //使能SLEEPDEEP位 (SYS->CTRL) PWR->CR |= 1<<0; //LPDS置位 PWR->CR |= 1<<1; //PDDS置位 break; } case 2:{ //PDDS+SLEEPDEEP+WFI进入待机模式 SCB->SCR |= 1<<2; //使能SLEEPDEEP位 (SYS->CTRL) PWR->CR|=1<<1; //PDDS置位 break; } } PWR->CR |= 1<<2; //清除Wake-up 标志 PWR->CSR |= 1<<8; //允许写入RTC和BKP寄存器 WFI_SET(); //执行WFI指令 } //系统软复位void Sys_Soft_Reset(void){ SCB->AIRCR =0X05FA0000|(u32)0x04; }
#include <stm32f10x_lib.h> #include "system.h" #include "wdg.h" #include "exti.h" #define LED1 PAout(4)#define LED2 PAout(5)#define PWR_MODE_Sleep 0 //开启睡眠模式#define PWR_MODE_STOP 1 //开启停机模式#define PWR_MODE_STANDBY 0 //开启待机模式void Gpio_Init(void);int main(void){ u32 i= 10,j=10; Rcc_Init(9); //系统时钟设置 Exti_Init(GPIO_A,0,FTIR); //设置PA1为下降沿触发,参数GPIO_x 和 FTIR 在system.h中有定义 Nvic_Init(0,0,EXTI0_IRQChannel,0); //设置外部中断 Gpio_Init(); while(i--){ LED1 = !LED1; delay(30000); //延时30ms } #if PWR_MODE_Sleep //睡眠模式,外部中断唤醒后会复位 Sys_Standby(0); #elif PWR_MODE_STOP //停机模式,外部中断唤醒,唤醒后复位 Sys_Standby(1); #elif PWR_MODE_STANDBY //待机模式,由独立看门狗唤醒,唤醒后会初始化,LED闪烁5次后,暗一段时间 Iwdg_Init(3,2000); //设置为1.6s内不喂狗复位,使用独立看门狗唤醒,唤醒后复位 Sys_Standby(2); #endif while(j--){ //这段程序用于检验唤醒后是否会继续运行后面的程序,还是会导致复位 LED2 = !LED2; delay(10000); //延时10ms } }void Gpio_Init(void){ RCC->APB2ENR|=1<<2; //使能PORTA时钟 GPIOA->CRL&=0x0000FFFF; // PA0~3设置为浮空输入,PA4~7设置为推挽输出 GPIOA->CRL|=0x33334444; }
#include "stm32f10x_it.h"#include "system.h"#define LED1 PAout(4)#define LED2 PAout(5)#define LED3 PAout(6)#define LED4 PAout(7)void EXTI0_IRQHandler(void){ LED4 = !LED4; EXTI->PR = 1<<0; //清除中断标志位}
待机相关代码参见 system.c文件中
#include "stm32f10x.h"#include "stdio.h"#define PRINTF_ON 1void RCC_Configuration(void);void GPIO_Configuration(void);void NVIC_Configuration(void);void EXTI_Configuration(void);void IWDG_Configuration(void);#define PWR_MODE_Sleep 0 //开启睡眠模式#define PWR_MODE_DeepSleep 1 //开启停机模式#define PWR_MODE_STANDBY 0 //开启待机模式 vu32 DelayTime = 10000000;int main(void){ RCC_Configuration(); GPIO_Configuration(); NVIC_Configuration(); EXTI_Configuration(); SysTick_Config(10000000); while(--DelayTime); #if PWR_MODE_Sleep //睡眠模式 PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI); //唤醒后时钟变为内置8MHz #elif PWR_MODE_DeepSleep //停机模式 PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI); //唤醒后时钟变为内置8MHz #elif PWR_MODE_STANDBY //待机模式 IWDG_Configuration(); //设置为2s内不喂狗复位,使用独立看门狗唤醒 PWR_EnterSTANDBYMode(); //唤醒后会初始化程序 #endif while(1);}void IWDG_Configuration(void){ RCC_LSICmd(ENABLE); //打开LSI while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)==RESET); IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(IWDG_Prescaler_32); IWDG_SetReload(2000); //max 0xFFF 0~4095 IWDG_ReloadCounter(); IWDG_Enable();}void GPIO_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA , &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA , &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA , &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA , &GPIO_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);}void RCC_Configuration(void){ /* 定义枚举类型变量 HSEStartUpStatus */ ErrorStatus HSEStartUpStatus; /* 复位系统时钟设置*/ RCC_DeInit(); /* 开启HSE*/ RCC_HSEConfig(RCC_HSE_ON); /* 等待HSE起振并稳定*/ HSEStartUpStatus = RCC_WaitForHSEStartUp(); /* 判断HSE起是否振成功,是则进入if()内部 */ if(HSEStartUpStatus == SUCCESS) { /* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */ RCC_PCLK2Config(RCC_HCLK_Div1); /* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */ RCC_PCLK1Config(RCC_HCLK_Div2); /* 设置FLASH延时周期数为2 */ FLASH_SetLatency(FLASH_Latency_2); /* 使能FLASH预取缓存 */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */ RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); /* 使能PLL */ RCC_PLLCmd(ENABLE); /* 等待PLL输出稳定 */ while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); /* 选择SYSCLK时钟源为PLL */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* 等待PLL成为SYSCLK时钟源 */ while(RCC_GetSYSCLKSource() != 0x08); } /* 打开APB2总线上的GPIOA时钟*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE); //RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); //RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP|RCC_APB1Periph_WWDG, ENABLE); } void USART_Configuration(void){ USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; USART_ClockInitStructure.USART_Clock = USART_Clock_Disable; USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low; USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge; USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; USART_ClockInit(USART1 , &USART_ClockInitStructure); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; USART_Init(USART1,&USART_InitStructure); USART_Cmd(USART1,ENABLE);}void EXTI_Configuration(void){ EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); }void NVIC_Configuration(void){ NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);}#if PRINTF_ONint fputc(int ch,FILE *f){ USART_SendData(USART1,(u8) ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET); return ch;}#endif
#include "stm32f10x_it.h"#include "stdio.h"void EXTI0_IRQHandler(void){ GPIO_WriteBit(GPIOA,GPIO_Pin_7,Bit_SET); //EXTI_ClearFlag(EXTI_Line0); //清除此中断标志位,系统由于唤醒将直接复位}void SysTick_Handler(void){ GPIO_WriteBit(GPIOA,GPIO_Pin_4,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_4)));}
联系客服