按键控制LED灯
按键控制LED的开发流程:
第一步:使能功能复用时钟

第二布,配置复用寄存器
第三步,配置中断屏蔽寄存器
固件库按键控制LED灯
外部中断EXTI结构体:
typedef struct
{
uint32_t EXTI_Line;
EXTIMode_TypeDef EXTI_Mode;
EXTITrigger_TypeDef EXTI_Trigger;
FunctionalState EXTI_LineCmd;
}EXTI_InitTypeDef;
外部中断EXTI相关库函数:
void EXTI_DeInit(void);
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
void EXTI_StructInit(EXTI_InitTypeDef* EXTI_InitStruct);
void EXTI_GenerateSWInterrupt(uint32_t EXTI_Line);
FlagStatus EXTI_GetFlagStatus(uint32_t EXTI_Line);
void EXTI_ClearFlag(uint32_t EXTI_Line);
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
软件流程设计
- 初始化系统
初始化GPIO、EXTI外设时钟
初始化按键和LED引脚
初始化EXTI外部中断条件
初始化NVIC嵌套中断控制器及分组
- 编写外部中断函数
判断按键是否按下控制LED灯
weak:若弱定义;如果用户没有自己定义的中断函数,则系统默认执行系统自定义的中断函数,如果用户有定义中断函数则优先执行用户的中断函数。
实现代码
LED
led.h
#ifndef LED_H_
#define LED_H_
void LED_Init(void);
#endif
led.c
#include "led.h"
#include "stm32f10x.h"
//初始化LED灯的函数------------函数的定义、声明、调用(led.c led.h main.c)
void LED_Init(void)
{
//1.初始化led引脚GPIOA1
GPIO_InitTypeDef led_initstruct; //定义GPIO的结构体
//2.³õʼ>>¯Ê±ÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//时钟的初始化
led_initstruct.GPIO_Pin = GPIO_Pin_1;
led_initstruct.GPIO_Speed = GPIO_Speed_2MHz;
led_initstruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA,&led_initstruct); //初始化GPIO结构体
}
按键
shake.h
#ifndef SHAKE_H_
#define SHAKE_H_
void Shake_Init(void);
#endif
shake.c
#include "stm32f10x.h"
#include "shake.h"
void Shake_Init(void)
{
GPIO_InitTypeDef shake_initstruct;
EXTI_InitTypeDef exti_initstruct;
NVIC_InitTypeDef nvic_initstruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);//时钟初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC分配
shake_initstruct.GPIO_Mode=GPIO_Mode_IPU; //按键
shake_initstruct.GPIO_Pin=GPIO_Pin_0;
GPIO_Init(GPIOA, &shake_initstruct);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//GPIO中断线
exti_initstruct.EXTI_Line =EXTI_Line0; //中断
exti_initstruct.EXTI_Mode = EXTI_Mode_Interrupt;
exti_initstruct.EXTI_Trigger = EXTI_Trigger_Falling;
exti_initstruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti_initstruct);
//NVIC
nvic_initstruct.NVIC_IRQChannel =EXTI0_IRQn; //f10x.h中寻找
nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 0;
nvic_initstruct.NVIC_IRQChannelSubPriority = 0;
nvic_initstruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_initstruct);
}
main.c
#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "bear.h"
#include "key.h"
#include "shake.h"
void delay(uint16_t time)
{
uint16_t i=0;
while(time--)
{
i =12000;
while(i--);
}
}
int main()
{
LED_Init();
Shake_Init();
GPIO_SetBits( GPIOA, GPIO_Pin_1);
while(1)
{
}
}
void EXTI0_IRQHandler() //中断函数
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)//外部中断获取标志位,即查看是否满足中断条件
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
EXTI_ClearITPendingBit(EXTI_Line0); //外部中断标志位清除,为下一次中断留出位置,一般与EXTI_GetITStatus一起使用
}
}
个人感悟:
难,要多练!!!