初学者分享,各位大佬指正!!
我在CSDN上找的要么就是以前老的库函数不能直接拿来用,要不就是最近的,但是讲的太复杂看不懂,这篇文章代码已经跑通,只要拿来用就行,如果要整个文件的,请在评论区留言。
项目:GD32f330最小系统板实现深度睡眠模式模式与唤醒
库:标准库
停机/唤醒条件:文章中我会贴手册的图
功能/现象:控制按键,实现小灯开关,定时进入深度睡眠模式
正常模式:PA10(LED)常灭,按下PB5(给一个高电平),小灯亮一下,灯灭;
停机模式:PB5按键不动,5秒自动进入深度睡眠模式;
唤醒:按PB5 一下,灯亮一下灭,实现唤醒;
1.接线
接线图(板子自己买的GD32f330cbt6最小系统板)
红色线:3.3v
棕色线:GND
黄色线:PA10(给推挽输出)
绿色线:PB5(给上拉输入,高电平),另一端接GND
烧录:st-link
2.深度睡眠模式
2.1总体介绍
----------建议可以直接看代码------------------因为我看手册看的头晕----------
2.2深度睡眠模式
2.3 节电模式总结
2.4 PMU寄存器
3. 代码
代码分为四个文件:main.c, Stop.c, Timer.c, LED.c
.h文件不提供了,自己创建一个.h文件,把函数放进去就行。
# main.c
#include "gd32f3x0.h"
#include "systick.h"
#include "LED.h"
#include "Stop.h"
#include "Timer.h"
uint8_t Key = 0;
extern uint8_t set ;
int main(void)
{
LED_Init();
WKUP_Init();
Timer_Init();
while (1)
{
if(set == 1)
{
Sys_Enter_Stop(); // 进入深度睡眠模式
set = 0;
}
gpio_bit_write(GPIOA,GPIO_PIN_10,RESET);
}
}
#Stop.c
#include "gd32f3x0.h"
#include "systick.h"
#include "Stop.h"
#include "LED.h"
extern uint16_t Num;
//配置深度睡眠模式
void Sys_Stop(void)
{
rcu_periph_clock_enable(RCU_PMU);//使能PWU外设时钟
pmu_to_deepsleepmode(PMU_LDO_LOWPOWER,PMU_LOWDRIVER_DISABLE,WFI_CMD);
}
//系统进入深度睡眠模式
void Sys_Enter_Stop(void)
{
Sys_Stop();//启动深度睡眠模式
}
判断按键
uint8_t Check_key(void)
{
while(1)
{
if(gpio_input_bit_get(GPIOB,GPIO_PIN_5) != SET)//如果PB5按下,高电平下拉为低电平
{
Num= 0;//Num要放在这里清零,如果放在定时器在1秒按的很快内可能检测不到
gpio_bit_write(GPIOA,GPIO_PIN_10,SET);//灯闪烁一下
delay_1ms(30);
}
else
{
return 0;
}
}
}
//外部按键PB5触发中断
void EXTI4_15_IRQHandler(void)
{
if(exti_interrupt_flag_get(EXTI_5) != RESET) //确保是否产生了EXTI Line中断
{
exti_interrupt_flag_clear(EXTI_5); // 清除中断标志位
if (Check_key()) // 判断按键
{
}
}
}
//初始化
void WKUP_Init(void)
{
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_CFGCMP);
gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_5);
nvic_irq_enable(EXTI4_15_IRQn,1U,0U);
syscfg_exti_line_config( EXTI_SOURCE_GPIOB,EXTI_SOURCE_PIN5);
exti_init(EXTI_5,EXTI_INTERRUPT,EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(EXTI_5);
}
# Timer.c
#include "gd32f3x0.h"
#include "systick.h"
#include "LED.h"
uint8_t set = 0;
uint16_t Num=0; //定义在定时器中断里自增的变量
void Timer_Init(void)
{
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER2);//开启TIM2的时钟
timer_deinit(TIMER2);
timer_struct_para_init(&timer_initpara);
timer_initpara.prescaler = 8400 - 1; //预分频系数,GD32是84MHZ
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 10000 - 1; //重装载系数
timer_initpara.clockdivision = TIMER_CKDIV_DIV1; //输入捕获预分频(此处用不到)
timer_initpara.repetitioncounter = 0; //重复计数器,只有高级定时器才有,也就是中断多少次才进入中断服务函数
timer_init(TIMER2,&timer_initpara);
timer_interrupt_enable(TIMER2,TIMER_INT_UP);
timer_enable(TIMER2);
nvic_irq_enable(TIMER2_IRQn,1U,0U);
}
//中断
void TIMER2_IRQHandler(void)
{
if (timer_interrupt_flag_get(TIMER2,TIMER_INT_FLAG_UP) == SET)
{
timer_interrupt_flag_clear(TIMER2,TIMER_INT_FLAG_UP);
if(gpio_input_bit_get(GPIOB,GPIO_PIN_5) == SET)//未被按下
{
Num++;
if (Num >= 5) // 5秒计数
{
set = 1; // 设置标志位
Num = 0; // 计数器清零
}
}
}
}
#LED.c
#include "gd32f3x0.h"
void LED_Init(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_10);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
}