单片机STM32入门——(2)按键控制

  • 1.理论分析
  • 1.1按键电平分析
  • 1.2按键扫描程序逻辑
  • 2.程序编写
  • 2.1按键扫描程序
  • 2.1.1按键扫描程序的头文件
  • 2.1.2按键扫描程序
  • 2.2主程序


在第一次的学习中已经提到了,我们在需要修改控制灯的状态的时候,都需要重新修改并下载程序,那么我们本次将通过按键来控制LED灯的亮灭。
分别由两个按键控制LED1和LED2

1.理论分析

1.1按键电平分析

理论情况按键的电压波形应该为方波

STM32L0 cubemx 按键唤醒_#include


但是实际按键电压波形,会有电压抖动,我们需要通过延时来进行按键消抖,这里需要用到延时函数delay_ms()

STM32L0 cubemx 按键唤醒_#include_02

1.2按键扫描程序逻辑

通过分析,我们可以知道。

  • 第一步,判断是否有按键按下,有按键按下时,将继续执行,没有按键按下时,将返回0,即没有按键按下。
  • 第二步,当判断为有按键按下时,判断为key0还是key1,当为key0时,返回1,即为按键1按下;当为key1时,返回为2,即为按键2按下。

Created with Raphaël 2.2.0 Start 是否有按键按下 是否为key0 ? return 1 End 是否为key1? return 2 return 0 yes no yes no yes


2.程序编写

2.1按键扫描程序

2.1.1按键扫描程序的头文件

首先我们需要GPIO数据读取函数,从PD8和PD9读取数据,并记为key0 和 key1,
然后需要声明void key_init(); int key_scan();这两个函数

#ifndef _KEY_H
#define _KEY_H

#include "sys.h"

//从PD8和PD9读取数据
#define key0 GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_9)
#define key1 GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_8)

void key_init();
int key_scan();

#endif

2.1.2按键扫描程序

按键扫描程序中,我们需要编写void key_init()按键初始化函数,其功能为,初始化定义PD8 和 PD9接口。还需要编写int key_scan()按键扫描函数,通过读取按键电平的变化来判断是否有按键按下与是哪一个按键按下。

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

void key_init(){//初始化按键
	
	GPIO_InitTypeDef GPIO_InitStruture;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);//打开PD时钟
	
	GPIO_InitStruture.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
	GPIO_InitStruture.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8; //设置端口
	GPIO_Init(GPIOD,&GPIO_InitStruture);//初始化POID
}

int key_scan()
{
	static u8 flag = 1;//之前没有按键按下
	if(flag==1&&(key0==0||key1==0))//之前没有按键按下且当前有key0或者key1按下时
	{
		flag = 0;//按键key0或者key1按下,flag置0(即为有按键按下)
		delay_ms(10);//延时按键消抖
		if(key0==0){
			return 1;
		}else if(key1==0){
			return 2;
		}
	}else if(key0==1&&key1==1) flag = 1;//没有按键按下时,flag置1
	
	return 0;//无按键按下
}

2.2主程序

首先在主程序中定义无符号的字符变量key
在while循环中通过从按键扫描函数中读取的数值来判断应该控制哪一个灯的状态。
其中特别注意 按键读取函数key = key_scan();需要写在while循环中,因为每一次的循环所扫描到的按键数值不一样。
tips我就在第二次编写时,出现了这样的错误,困扰了很久。

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

int main()
{
	u8 key = 0;//按键数
	led_init();//LED初始化函数
	key_init();//按键初始化函数
	delay_init();
	
	while(1)
	{
		key = key_scan();//必须反在while循环中,每一次读取的函数值不同
		if(key==1||key==2)//当为按键1或者2时,执行
		{
			switch (key){
				case 1://按键1控制LED1
					LED1 =! LED1;
					break;
				case 2://按键2控制LED2
					LED2 =! LED2;
					break;
			}
		}
	}
}

将程序编译下载后,便能通过按键来控制LED1和LED2的状态了。

本次我们学习了如何用按键来控制LED灯的状态,那么下一次的学习,我们将来了解怎样使用矩阵键盘,下一次的难度将会比前两次的学习更大。加油!冲!!