初学者分享,各位大佬指正!!
项目:stm32f103c8t6待机模式(与第一篇区别在于使用PB5控制小灯和开启待机模式,只能使用PB5实现待机,无法使用PB5唤醒,因为待机模式下引脚高阻态)
现象:
正常模式:按下PB5,实现控制PA1小灯(非开关小灯);
待机模式:按下PB5 3s,实现待机,PA1小灯灭;
唤醒:复位唤醒
接线图:(我用的是江科大的配件,STlink烧录)
1.待机模式/唤醒说明:(与第一篇相同)
1.1 待机条件:
1.当进入睡眠模式时,使能外部的SLEEPDEEP信号,以允许停止系统时钟。
2.电源控制寄存器(PWR_CR)中PDDS位,设置为1。
3.电源控制/状态寄存器(PWR_CSR) 中EWUP位,设置为1。
1.2 唤醒条件(4选1):
条件:WKUP引脚的上升沿(给PA0一个高电平)(选择这一个)
2.代码:(修改了)
1.main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Key.h"
#include "LED.h"
#include "Standby.h"
uint8_t Key = 0;
int main(void)
{
GPIO_Config();
LED_Init();
WKUP_Init();
while (1)
{
// Key = Key_GetNum();
// if (Key == 1)
// {
// GPIO_WriteBit(GPIOA, GPIO_Pin_1,Bit_SET);
// Delay_ms(100);
// Key = 0;
// }
GPIO_WriteBit(GPIOA, GPIO_Pin_1,Bit_RESET);
}
}
2.Standby.c
#include "stm32f10x.h"
#include "Standby.h"
#include "Delay.h"
#include "Key.h"
#include "LED.h"
/* 按下PB5按键 正常点亮关闭小灯PA1,长按3s PB5进入待机模式,小灯熄灭,按一下复位唤醒*/
//待机模式
void Sys_Standby(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR外设时钟
PWR_WakeUpPinCmd(ENABLE); //使能唤醒管脚功能,在WkUp的上升沿进行
PWR_EnterSTANDBYMode(); //进入待机(STANDBY)模式 设置相应的进入条件(已经封装成了完整的函数)
}
//系统进入待机模式
//1.复位所有的io
//2.待机模式设置
void Sys_Enter_Standby(void)
{
RCC_APB2PeriphResetCmd(0x01fc,DISABLE);//复位
Sys_Standby();//启动待机模式
}
//检测WKUP脚的信号
u8 Check_WKUP(void)
{
uint16_t t=0; //记录按下的时间
while(1)
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)==Bit_SET)//判断按下的时间
{
t++; //已经按下了
Delay_ms(30);
if(t>=70) //按下超过2秒钟
{
return 1; //按下2s以上了
}
else
{
GPIO_WriteBit(GPIOA, GPIO_Pin_1,Bit_SET);
}
}
else
{
return 0;
}
}
}
//中断
void EXTI9_5_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line5); // 清除中断标志位
if (Check_WKUP()) // 检查按键是否长按2秒
{
Sys_Enter_Standby(); // 进入待机模式
}
}
//PA0 WKUP唤醒初始化
void WKUP_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);//使能GPIOA和复用功能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//使用外部中断方式
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource5); //中断线5连接GPIOB.5
EXTI_InitStructure.EXTI_Line = EXTI_Line5; //设置按键所有的外部线路
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设外外部中断模式:EXTI线路为中断请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); // 初始化外部中断
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级2级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
// if(Check_WKUP()) Sys_Standby(); //按键未按下或按下时间不足 3 秒,进入待机模式
}
3.LED.c
#include "stm32f10x.h" // Device header
void LED_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
4.Key.c(PB5引脚模式变了)
#include "stm32f10x.h" // Device header
#include "Delay.h"
// 初始化GPIO
void GPIO_Config(void)
{
// 使能GPIOA和GPIOB时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
// 配置PB5为浮空输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
uint8_t Key_GetNum(void)
{
uint8_t Keyum = 0;
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) == 1)
{
Delay_ms(20);
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) == 1);
Delay_ms(20);
Keyum = 1;
}
return Keyum;
}