#include "bsp_exti.h"
#include "Led_Key.h"
#include "bsp_SysTick.h"
int main(void)
{
int i;
SysTick_Configuration(); //定时器初始化
PA0_EXTI0_Configurature(); //按键中断初始化
Led_Configuration(); //GPIOA_Pin_1引脚初始化
while(1)
{
for(i=0;i<10;i++)
{
GPIO_WriteBit(GPIOA,GPIO_Pin_1,Bit_SET);
Delay_us(200000); //200ms延时
GPIO_WriteBit(GPIOA,GPIO_Pin_1,Bit_RESET);
Delay_us(200000);
}
__WFI(); //CPU进入睡眠模式
}
}
在 bsp_SysTick.c文件中初始化滴答定时器,用来在main函数中定时
#include "bsp_SysTick.h"
unsigned int TimingDelay; //定义了一个全局变量
void SysTick_Configuration(void)
{
SysTick_Handler(void)中断处理函数中
while(SysTick_Config(72))
;
//SysTick->CTRL == 1000 0000 0000 0111 为其寄存器的值
// 1 == 0000 0000 0000 0001
SysTick->CTRL &=~(1<<0); //暂时初始化后先关闭定时器,使用前在开启
// 1左移0位后,再取反,最后与SysTick->CTRL寄存器的值相与
}
void Delay_us(unsigned int n)
{
TimingDelay=n;
SysTick->CTRL |=(1<<0); //开启Sys_Tick
while(TimingDelay)
;
SysTick->CTRL &=~(1<<0); //关闭Sys_Tick
}
在Led_Key.c文件中对GPIOA中的Pin_1引脚进行初始化
#include "Led_Key.h"
void Led_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
在bsp_exti.c文件中对GPIOA中的Pin_0引脚进行初始化,并开启中断,且对中断进行配置
#include "bsp_exti.h"
void PA0_EXTI0_Configurature(void)
{
NVIC_InitTypeDef NVIC_InitStructure; //外部中断初始化
GPIO_InitTypeDef GPIO_InitStructure; //GPIOA端口初始化
EXTI_InitTypeDef EXTI_InitStructure; //外部中断功能、模式初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//开启GPIOA与中断的时钟
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//设置优先级分组
NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//将GPIOA0设置为外部中断
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 EXTI0_IRQHandler(void)//中断处理函数
{
if(EXTI_GetFlagStatus(EXTI_Line0)==SET) //再次判断是否发生中断,EXTI_GetFlagStatus()这个函数返回值为SET或RESET
{
EXTI_ClearITPendingBit(EXTI_Line0);//清除标志位
}
}
在中断处理函数EXTI0_IRQHandler()中,我们不需要进行其他操作,但一定要记得清除中断标志位。
到这里就完成了
将程序烧录到板子中,可以看到接在GPIOA_Pin_1引脚上的灯将会闪烁10次,随后CPU进入睡眠模式,可通过按与GPIOA_Pin_0引脚相接的开关,来进入中断,从而唤醒CPU,接着又在while循环中重复,并又进入睡眠模式。
本文介绍了一种基于STM32的嵌入式系统设计,通过配置GPIOA_Pin_1实现LED灯的闪烁,并利用GPIOA_Pin_0进行按键中断,以唤醒处于睡眠模式的CPU。
1843





