基于STM32F103入门2——按键点灯


今天学习了STM32固件库按键程序 按键也可以多种方式点灯,在这里做一下总结。
新建固件库工程文件如何不会的话可以参考我之前写的这篇 文章。
我用的是STM32F103C8T6
我用的是STM32F103C8T6

1:按键不带锁存

不带锁存的意思就是 比如你按下按键灯亮,但是你一旦松手了灯就熄灭了,所以你想这个灯一直亮,那么你就一直按着按键不松手。

1.1例程

key.c

/*========================key.c=========================*/
#include "stm32f10x.h"
#include "key.h"

/*按键初始化函数*/
void KEY_Init(void)
{
	//1.打开控制GPIOA的时钟(APB2)
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
		
	//2.配置结构体	
	GPIO_InitTypeDef key_init;
	key_init.GPIO_Pin   = GPIO_Pin_5;      	//GPIOC A5引脚
	key_init.GPIO_Mode  = GPIO_Mode_IPU; 	//上拉输入	
	//led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz
	
	//3.对成员进行初始化
	GPIO_Init(GPIOA, &key_init);
}

led.c

#include "stm32f10x.h"
#include "led.h"

void LED_Init(void)
{	
	//1.打开控制GPIOC的时钟(APB2)
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	
	//2.配置结构体	
	GPIO_InitTypeDef led_init;
	led_init.GPIO_Pin   = GPIO_Pin_13;      //GPIOC13引脚
	led_init.GPIO_Mode  = GPIO_Mode_Out_PP; //推挽输出	
	led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz
	
	//3.对成员进行初始化
	GPIO_Init(GPIOC, &led_init);
}

main.c

#include "stm32f10x.h"
#include "led.h"
#include "key.h"
#include "delay.h"

int  main()
{
	LED_Init(); //LED初始化
	KEY_Init(); //按键初始化
	GPIO_SetBits(GPIOC,LED);	//LED设置高电平
	GPIO_SetBits(GPIOA,KEY);	//按键设置高电平
	
	while(1)
	{
		#if 0
		/*示例1:无锁存*/
		if(GPIO_ReadInputDataBit(GPIOA, KEY) == 0) 	//读取按键是否被按下 	
		{		
			GPIO_ResetBits(GPIOC, LED); 	//LED点亮		
		}
		else
		{
			GPIO_SetBits(GPIOC,LED);		//LED熄灭
		}
		#endif
		
		/*示例2:无锁存*/
		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(); //LED初始化
	KEY_Init(); //按键初始化
	GPIO_SetBits(GPIOC,LED);	//LED设置高电平
	GPIO_SetBits(GPIOA,KEY);	//按键设置高电平
	
	while(1)
	{
		/*示例3:有锁存 每按一次 灯取反*/
		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(配置结构体的相关东西)

//1.打开控制GPIOA的时钟(APB2)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 	//我们设置复用 用作外部中断
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5); //设置A5引脚为 外部中断引脚

//2.配置结构体	
GPIO_InitTypeDef key_init;
key_init.GPIO_Pin   = GPIO_Pin_5;      	//GPIO A5引脚
key_init.GPIO_Mode  = GPIO_Mode_IPU; 	//上拉输入	
//led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz

//3.对成员进行初始化
GPIO_Init(GPIOA, &key_init);

2.设置EXTI (触发方式:上升沿、下降沿、上下都触发)。

EXTI_Line: 中断线(一共20条)
EXTI_Mode: EXTI 中断的模式/产生的事件
EXTI_Trigger: EXTI()触发方式 上升沿 下降沿 上下都触发)
EXTI_LineCmd: 控制是否使能EXTI线,使能EXTI线或禁用

//4.配置EXTI外部中断结构体
EXTI_InitTypeDef exti_init;

exti_init.EXTI_Line = EXTI_Line5; 		//A5引脚 所以是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(中断优先级)

//5.配置NVIC优先级结构体
NVIC_InitTypeDef nvic_init;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //配置第四组

nvic_init.NVIC_IRQChannel = EXTI9_5_IRQn; //A5引脚嘛 选择通道5
nvic_init.NVIC_IRQChannelPreemptionPriority = 0; //设置抢占优先级 0级
nvic_init.NVIC_IRQChannelSubPriority = 0; //设置子优先级 0级
nvic_init.NVIC_IRQChannelCmd = ENABLE; //打开NVIC优先级开关

//对成员进行初始化
NVIC_Init(&nvic_init);

4.编写中断服务函数

当按键从高电平变成低电平,也就是下降沿的时候,会触发中断,然后会进入中断服务函数。然后我们在服务函数里面点灯即可。


void EXTI9_5_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line5) != RESET) //如果发生外部中断
	{
		GPIO_ResetBits(GPIOC,GPIO_Pin_13);	//开灯	LED设置低电平
		delay_ms(1000);						//亮灯1秒
		GPIO_SetBits(GPIOC,GPIO_Pin_13);	//关灯	LED设置高电平
	}
	
	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(); //LED初始化
	KEY_Init(); //按键初始化
	exti_Init(); //外部中断初始化
	GPIO_SetBits(GPIOC,GPIO_Pin_13);	//LED设置高电平
	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);	//开灯	LED设置低电平
		delay_ms(1000);						//亮灯1秒
		GPIO_SetBits(GPIOC,GPIO_Pin_13);	//关灯	LED设置高电平
	}
	
	EXTI_ClearFlag(EXTI_Line5); //清除标志位
}

#include "stm32f10x.h"
#include "key.h"

/*按键初始化函数*/
void KEY_Init(void)
{
	//1.打开控制GPIOA的时钟(APB2)
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 	//复用 用作外部中断
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5); //设置A5引脚为 外部中断引脚
	
	//2.配置结构体	
	GPIO_InitTypeDef key_init;
	key_init.GPIO_Pin   = GPIO_Pin_5;      	//GPIOC13引脚
	key_init.GPIO_Mode  = GPIO_Mode_IPU; 	//上拉输入	
	//led_init.GPIO_Speed = GPIO_Speed_10MHz; //10MHz
	
	//3.对成员进行初始化
	GPIO_Init(GPIOA, &key_init);
}

exti.c

#include "stm32f10x.h"
#include "exti.h"


void exti_Init()
{		
	//4.配置EXTI外部中断结构体
	EXTI_InitTypeDef exti_init;
	
	exti_init.EXTI_Line = EXTI_Line5; 			//A5引脚
	exti_init.EXTI_Mode = EXTI_Mode_Interrupt; 	//中断模式
	exti_init.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发 
	exti_init.EXTI_LineCmd = ENABLE; 			//打开外部中断开关
	
	//对成员进行初始化
	EXTI_Init(&exti_init);
	
	
	//5.配置NVIC优先级结构体
	NVIC_InitTypeDef nvic_init;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //配置第四组
	
	
	nvic_init.NVIC_IRQChannel = EXTI9_5_IRQn; //通道5
	nvic_init.NVIC_IRQChannelPreemptionPriority = 0; //设置抢占优先级 0级
	nvic_init.NVIC_IRQChannelSubPriority = 0; //设置子优先级 0级
	nvic_init.NVIC_IRQChannelCmd = ENABLE; //打开NVIC优先级开关
	
	//对成员进行初始化
	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 。或者评论区留下的你的联系方式。

继续加油!

  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
基于STM32F103C8T6的按键控制可以通过操作矩阵键盘来实现。在这个过程中,需要使用消抖和松手检测来确保按键的正常工作。具体的步骤如下: 1. 首先,连接矩阵键盘到STM32F103C8T6单片机。矩阵键盘通常由多个行和列的按键组成,每个按键都有一个唯一的行列位置。 2. 接下来,配置STM32F103C8T6的GPIO引脚。将矩阵键盘的行与GPIO的输出引脚相连,将矩阵键盘的列与GPIO的输入引脚相连。 3. 在编程中,需要使用GPIO输入输出的库函数来配置和控制引脚。通过设置引脚的输入和输出模式,可以实现对矩阵键盘的扫描和控制。 4. 在进行按键扫描时,需要遍历每个列,然后逐个检查行的状态。如果某个按键按下,则对应的行列位置的状态将会变化。 5. 为了消除抖动现象,可以在按键被按下时加入消抖处理。这可以通过在每次检测到按键按下状态时进行延时来实现。 6. 此外,还可以加入松手检测,以确保按键在松开时能及时被检测到。可以通过检测按键的状态变化,如果在一段时间内按键保持松开状态,则认为按键已经松开。 以上就是基于STM32F103C8T6的按键控制的一些步骤和注意事项。通过配置GPIO引脚、进行按键扫描、消抖和松手检测等操作,可以实现对矩阵键盘的控制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [STM32F103C8T6 操作矩阵键盘](https://blog.csdn.net/qq_58676187/article/details/125840694)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮卡丘吉尔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值