【STM32F1 按键控制 Proteus仿真】

功能简介

使用库函数基于STM32F103c8t6实现对5个按键动作的检测和4个LED指示灯的控制。所要实现的效果为:

  1. 程序开始运行时,开发平台上的4 个LED 全部是熄灭状态
  2. 按下某个按键时,对应的LED点亮,其它LED熄灭,再次按下改键时,对应的LED也熄灭;
  3. 其它按键也具备这样的功能;
  4. 而第五个按键则对应这4个led的流水状态

功能实现

按键控制led

代码编程流程图

流程图

软件代码

按键部分:key.c(key.h声明一下头函数即可)

/*按键初始化*/
void Key_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//根据仿真接线选择下拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_11;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*按键扫描返回键值*/
uint8_t Key_GetNum(void)//按键按下为1,松开为0
{
	uint8_t KeyNum = 0;
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1)
	{
		Delay_ms(20);//延时消抖
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1);
		Delay_ms(20);
		KeyNum = 1;
	}
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 1)
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 1);
		Delay_ms(20);
		KeyNum = 2;
	}
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3) == 1)
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_3) == 1);
		Delay_ms(20);
		KeyNum = 3;
	}
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == 1)
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == 1);
		Delay_ms(20);
		KeyNum = 4;
	}
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 1)
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 1);
		Delay_ms(20);
		KeyNum = 5;
	}
	
	return KeyNum;
}

LED部分:

/*LED初始化*/
void LED_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化为低电平
	
	GPIO_SetBits(GPIOA, GPIO_Pin_0 |  GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3);//需使其都为高电平
}
/*LED代码*/
/*说白了就是灯状态的封装,想要灯怎么亮封装引用即可,以下使用简单的封装*/
void LED1_Turn(void) //电平反转
{
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_0);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_0);
	}
}
void LED2_Turn(void)
{
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_1);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_1);
	}
}
void LED3_Turn(void)
{
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_2);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_2);
	}
}
void LED4_Turn(void)
{
	if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_3) == 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_3);
	}
	else
	{
		GPIO_ResetBits(GPIOA, GPIO_Pin_3);
	}
}
void LED5_ON(void)
{
	GPIO_ResetBits(GPIOA, GPIO_Pin_0);
	Delay_ms(100);
	GPIO_ResetBits(GPIOA, GPIO_Pin_1);
	Delay_ms(100);
	GPIO_ResetBits(GPIOA, GPIO_Pin_2);
	Delay_ms(100);
	GPIO_ResetBits(GPIOA, GPIO_Pin_3);
	Delay_ms(100);	
}
void LED5_OFF(void)
{
	GPIO_SetBits(GPIOA, GPIO_Pin_0);
	Delay_ms(100);
	GPIO_SetBits(GPIOA, GPIO_Pin_1);
	Delay_ms(100);
	GPIO_SetBits(GPIOA, GPIO_Pin_2);
	Delay_ms(100);
	GPIO_SetBits(GPIOA, GPIO_Pin_3);
	Delay_ms(100);	
}
/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器
}

/**
  * @brief  毫秒级延时
  * @param  xms 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}

主函数main:

uint8_t KeyNum;

int main(void)
{
	LED_Init();
	Key_Init();
	while (1)
	{
		KeyNum = Key_GetNum();
		if (KeyNum == 1)
		{
			LED1_Turn();
		}
		
		if (KeyNum == 2)
		{
			LED2_Turn();
		}
		
		if (KeyNum == 3)
		{
			LED3_Turn();
		}
		
		if (KeyNum == 4)
		{
			LED4_Turn();
		}

		if (KeyNum == 5)
		{	
			while(1)
			{
				KeyNum =Key_GetNum();
				LED5_ON();
				KeyNum =Key_GetNum();
				LED5_OFF();
				}
			}				
		}
	}
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值