今天学习了STM32固件库按键程序 按键也可以多种方式点灯,在这里做一下总结。
新建固件库工程文件如何不会的话可以参考我之前写的这篇
文章。
我用的是STM32F103C8T6
我用的是STM32F103C8T6
1:按键不带锁存
不带锁存的意思就是 比如你按下按键灯亮,但是你一旦松手了灯就熄灭了,所以你想这个灯一直亮,那么你就一直按着按键不松手。
1.1例程
key.c
#include "stm32f10x.h"
#include "key.h"
void KEY_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef key_init;
key_init.GPIO_Pin = GPIO_Pin_5;
key_init.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &key_init);
}
led.c
#include "stm32f10x.h"
#include "led.h"
void LED_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef led_init;
led_init.GPIO_Pin = GPIO_Pin_13;
led_init.GPIO_Mode = GPIO_Mode_Out_PP;
led_init.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOC, &led_init);
}
main.c
#include "stm32f10x.h"
#include "led.h"
#include "key.h"
#include "delay.h"
int main()
{
LED_Init();
KEY_Init();
GPIO_SetBits(GPIOC,LED);
GPIO_SetBits(GPIOA,KEY);
while(1)
{
#if 0
if(GPIO_ReadInputDataBit(GPIOA, KEY) == 0)
{
GPIO_ResetBits(GPIOC, LED);
}
else
{
GPIO_SetBits(GPIOC,LED);
}
#endif
GPIO_WriteBit(GPIOC, LED, (BitAction)(GPIO_ReadInputDataBit(GPIOA, KEY)));
}
}
2:按键带锁存
锁存的意思就是 比如你按下按键灯亮,但是你一旦松手了灯还是亮的,跟不带锁存相反。
2.1例程
key.c 和 led.c 和上面的不带锁存是一样的代码
#include "stm32f10x.h"
#include "led.h"
#include "key.h"
#include "delay.h"
int main()
{
LED_Init();
KEY_Init();
GPIO_SetBits(GPIOC,LED);
GPIO_SetBits(GPIOA,KEY);
while(1)
{
if(GPIO_ReadInputDataBit(GPIOA, KEY) == 0)
{
delay_ms(20);
if(GPIO_ReadInputDataBit(GPIOA, KEY) == 0)
{
GPIO_WriteBit(GPIOC, LED, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOC, LED)));
}
while(!GPIO_ReadInputDataBit(GPIOA, KEY));
}
}
}
3:按键用外部中断来做
正常如何程序比较多的话,我们有时候按键是需要及时处理的,如果通过循环检测其实不太理想的,所以我们可以把按键设置为中断来做。这样就可以更有效率,能及时处理。
步骤:
1.配置GPIO(配置结构体的相关东西)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5);
GPIO_InitTypeDef key_init;
key_init.GPIO_Pin = GPIO_Pin_5;
key_init.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &key_init);
2.设置EXTI (触发方式:上升沿、下降沿、上下都触发)。
EXTI_Line: 中断线(一共20条) EXTI_Mode: EXTI 中断的模式/产生的事件 EXTI_Trigger: EXTI()触发方式 上升沿 下降沿 上下都触发) EXTI_LineCmd: 控制是否使能EXTI线,使能EXTI线或禁用
EXTI_InitTypeDef exti_init;
exti_init.EXTI_Line = EXTI_Line5;
exti_init.EXTI_Mode = EXTI_Mode_Interrupt;
exti_init.EXTI_Trigger = EXTI_Trigger_Falling;
exti_init.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti_init);
3.设置NVIC(中断优先级)
NVIC_InitTypeDef nvic_init;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
nvic_init.NVIC_IRQChannel = EXTI9_5_IRQn;
nvic_init.NVIC_IRQChannelPreemptionPriority = 0;
nvic_init.NVIC_IRQChannelSubPriority = 0;
nvic_init.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_init);
4.编写中断服务函数
当按键从高电平变成低电平,也就是下降沿的时候,会触发中断,然后会进入中断服务函数。然后我们在服务函数里面点灯即可。
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line5) != RESET)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_13);
delay_ms(1000);
GPIO_SetBits(GPIOC,GPIO_Pin_13);
}
EXTI_ClearFlag(EXTI_Line5);
}
代码:
key.c
main.c
#include "stm32f10x.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "exti.h"
int main()
{
LED_Init();
KEY_Init();
exti_Init();
GPIO_SetBits(GPIOC,GPIO_Pin_13);
GPIO_SetBits(GPIOA,GPIO_Pin_5);
while(1)
{
}
}
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line5) != RESET)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_13);
delay_ms(1000);
GPIO_SetBits(GPIOC,GPIO_Pin_13);
}
EXTI_ClearFlag(EXTI_Line5);
}
#include "stm32f10x.h"
#include "key.h"
void KEY_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5);
GPIO_InitTypeDef key_init;
key_init.GPIO_Pin = GPIO_Pin_5;
key_init.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &key_init);
}
exti.c
#include "stm32f10x.h"
#include "exti.h"
void exti_Init()
{
EXTI_InitTypeDef exti_init;
exti_init.EXTI_Line = EXTI_Line5;
exti_init.EXTI_Mode = EXTI_Mode_Interrupt;
exti_init.EXTI_Trigger = EXTI_Trigger_Falling;
exti_init.EXTI_LineCmd = ENABLE;
EXTI_Init(&exti_init);
NVIC_InitTypeDef nvic_init;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
nvic_init.NVIC_IRQChannel = EXTI9_5_IRQn;
nvic_init.NVIC_IRQChannelPreemptionPriority = 0;
nvic_init.NVIC_IRQChannelSubPriority = 0;
nvic_init.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_init);
}
delay.c
#include "stm32f10x.h"
#include "delay.h"
void delay_ms(uint16_t time)
{
uint16_t i = 0;
while(time--)
{
i = 10000;
while(i--);
}
}
如果觉得这篇文章对你有用。欢迎大家点赞、评论哈哈
需要整个工程代码和 模块的相关资料,私信我 或者 +我扣扣:844797079 。或者评论区留下的你的联系方式。
继续加油!
|