STM32按键点灯实现,按下亮、再按熄灭,附GPIO输入输出源代码

效果图:

1、模块化编程思想:

封装LED点灯函数:

模块化编程思想就是将重复使用的代码封装起来,在主函数中再进行调用,这样能提高代码的简洁性和可读性。这里给出一个LED灯的程序的例程:

创建文件:

创建一个文件夹用来存放这些封装好的模块代码,再创建两个文件第一个是LED.c,第二个是LED.h;如下图所示

LED.h用来存放这个程序可以对外提供的函数或变量的声明。

LED.c用来实现这些函数的主体代码。

LED.h的代码:

#ifndef __LED_H//防止头文件重复包含代码
#define __LED_H
void LED_Init(uint16_t GPIO_PIN);
void GPIOA_LED_CONTROL(uint16_t GPIO_PIN, uint8_t sign);
void LED_Turn(uint16_t GPIO_PIN);
#endif

LED.c的代码:

#include "stm32f10x.h"                  // Device header

void LED_Init(uint16_t GPIO_PIN){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//ctrl + Alt + 空格:可以出现代码提示
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_ResetBits(GPIOA,  GPIO_PIN);
}
void LED_Turn(uint16_t GPIO_PIN) {//反转当前led状态
	if(GPIO_ReadOutputDataBit(GPIOA,GPIO_PIN) == 0){
		GPIO_SetBits(GPIOA,GPIO_PIN);
	}
	else{
		GPIO_ResetBits(GPIOA, GPIO_PIN);
	}
}
void GPIOA_LED_CONTROL(uint16_t GPIO_PIN, uint8_t sign) {
	if(sign == ENABLE){
		GPIO_SetBits(GPIOA, GPIO_PIN);
	}
	if(sign == DISABLE){
		GPIO_ResetBits(GPIOA, GPIO_PIN);
	}
}

主函数调用:

在主函数里添加头文件#include "LED.H"就可以在main函数内直接调用LED_Init()函数来实现LED的初始化

封装按键函数:

创建文件:

创建Key.c和Key.h两个文件:

这里按键采用低电平触发,设置为上拉输入IPU

如果不清楚哪个是上拉下拉输入可以参考下面代码及注释

 输入模式的几种标准库代码:

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);	//读取输入数据寄存器某一端口的输入值
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);						//读取整个输入寄存器
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //读取输出寄存器的某一个位,用于输出模式下,看一下自己输出的是什么
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);						//读取整个输出寄存器

 Key.h的代码:

#ifndef __KEY_H//防止头文件重复包含代码
#define __KEY_H
void Key_Init(uint16_t GPIO_PIN);
uint8_t Key_GetNum(void);
#endif

Key.c的代码:

/*uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);	//读取输入数据寄存器某一端口的输入值
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);						//读取整个输入寄存器
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //读取输出寄存器的某一个位,用于输出模式下,看一下自己输出的是什么
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);						//读取整个输出寄存器
*/
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
void Key_Init(uint16_t GPIO_PIN){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//下拉输入IPD,上拉输入IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//这一行可以不写,在输入模式下这一行不起作用
	GPIO_Init(GPIOB,  &GPIO_InitStructure);
}
uint8_t Key_GetNum() {
	uint8_t KeyNum = 0;
	if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == 0){//按键按下,这一位为1
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_4) == 0);//如果一直不松手那么程序就卡在这里
		Delay_ms(20);
		KeyNum = 1;//返回按键的值
	}
	if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) == 0){//按键按下,这一位为2
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) == 0);//如果一直不松手那么程序就卡在这里
		Delay_ms(20);
		KeyNum = 2;//返回按键的值
	}
	if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) == 0){//按键按下,这一位为3
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) == 0);//如果一直不松手那么程序就卡在这里
		Delay_ms(20);
		KeyNum = 3;//返回按键的值
	}
	return KeyNum;
}

最终实现:

电路接法:

LED接A1,A2,A3这三个引脚,一脚接GND,另一脚接GPIO端口,输出为高电平时,LED点亮。

按键接B4、B5、B6这三个引脚 ,一脚接GND,另一脚接GPIO端口,按键按下,GPIO输入为低电平。

主函数代码:

首先初始化LED和按键的引脚,初始化就会执行LED.c和Key.c中相应的代码。

while循环:使用KeyNum接收按键函数返回的值,当按键按下,翻转引脚电平。

按键函数和翻转实现函数也在Key.c和LED.c中可以自行查看

#include "stm32f10x.h"                  // Device header
#include "DELAY.h"
#include "LED.H"
#include "Key.h"
uint8_t KeyNum;
int main() {
	LED_Init(GPIO_Pin_1 | GPIO_Pin_2 |GPIO_Pin_3);
	Key_Init(GPIO_Pin_4 | GPIO_Pin_5 |GPIO_Pin_6);
	//GPIOA_LED_CONTROL(GPIO_Pin_1,ENABLE);
	while(1){
		KeyNum = Key_GetNum();
		if(KeyNum == 1) {
			LED_Turn(GPIO_Pin_1);
		}
		if(KeyNum == 2) {
			LED_Turn(GPIO_Pin_2);
		}
		if(KeyNum == 3) {
			LED_Turn(GPIO_Pin_3);
		}
	}
}

作者:爱打代码的小高

物联沃分享整理
物联沃-IOTWORD物联网 » STM32按键点灯实现,按下亮、再按熄灭,附GPIO输入输出源代码

发表评论