STM32F103ZE—GPIO的输入输出(点亮LED,检测按键)

        有关GPIO的输入输出原理请看我的文章STM32ZET6—寄存器编程(自写固件库)-优快云博客

有关工程建立的操作请看我的文章STM32F103ZE—STM32标准库及工程文件的建立-优快云博客

GPIO的输出—点亮LED小灯

原理图

        我们以第一个LED小灯R为例。

        从电路图上看,小灯是共阳极的,为了使电流流通,当PB5为低电平的时候,R小灯导通,所以,我们需要控制PB5输出一个低电平。

编程

        但我们建立好工程文件后,我们在USER文件夹下建立新文件夹并命名为led,在这个文件夹里新建bsp_led.h,bsp_led.c(名字可以随便取)两个文件。在keil5的工程目录USER里添加bsp_led.c文件。

我们在bsp_led.c里写如下代码:

#include "bsp_led.h"

void LED_GPIO_Config(void)
{
	//定义GPIO初始化结构体
	GPIO_InitTypeDef  GPIO_InitStruct;
	
	//在GPIO结构体中添加引脚口
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
	//定义输出模式,这里是通用推挽输出
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	//定义输出的速度,50MHz
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	//调用GPIO初始化函数,将要初始化的GPIOB和GPIOB的结构体配置传入GPIO初始化函数
	GPIO_Init(GPIOB, &GPIO_InitStruct);
	//开启GPIOB的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
}

        这里面的函数,结构体在“stm32f10x_gpio.h”和时钟“stm32f10x_rcc.h”当中寻找,大家可以按照函数名,函数注释了解功能。例如:打开“stm32f10x_gpio.h”,滑动鼠标滑轮到文件底部。

        我们根据GPIO_Init(.....)的函数名可以知道,这个是GPIO初始化函数,鼠标右击函数

跳转到GPIO_Init(....)函数的定义处,依据函数处的说明来使用

配置完GPIO的初始化后,记得还要开启对应GPIOB时钟时钟。

在stm32中我们配置一些功能时大致分为

1,初始化函数

2,开启时钟

3,特殊功能特殊配置

写完bsp_led.c在bsp_led.h里面做一些声明和引用。

#ifndef _BSP_LED_H
#define _BSP_LED_H

#include "stm32f10x.h"

#define ON	0
#define OFF 1
#define LED_R(a)	if(a)\
						GPIO_SetBits(GPIOB, GPIO_Pin_5); \
					else \
						GPIO_ResetBits(GPIOB, GPIO_Pin_5);

void LED_GPIO_Config(void);

#endif /* _BSP_LED_H */

 

#ifndef _BSP_LED_H
#define _BSP_LED_H

.....................................

#endif /* _BSP_LED_H */

  这三段内容是为了防止在多文件调用过程中出现的重复包含和定义,其逻辑是这样的。

        如果没有定义“bsp_led.h”                ==        #ifndef _BSP_LED_H

        那就定义"bsp_led.h"                       ==        #define _BSP_LED_H

        结束了,注释一下/*bsp_led.h*/         ==     #endif /* _BSP_LED_H */  

  这样的宏定义后,在程序中ON就是1,OFF就是0(这样做的目的是为了增加可读性,ON和OFF比1和0容易理解)

        宏定义        ON          1        

        宏定义        OFF        0

  这是宏定义的一种用法,其逻辑是,定义了LED_R(a),如果a是真值(真值就是1),就执行GPIO_SetBits(GPIOB, GPIO_Pin_5);。如果a是假值(假值就是0),就执行 GPIO_ResetBits(GPIOB, GPIO_Pin_5);。

  \是C语言的一种用法,用来连接上下代码的。

  GPIO_SetBits(GPIOB, GPIO_Pin_5);和GPIO_ResetBits(GPIOB, GPIO_Pin_5);用法在“stm32f10x_gpio.h”里。

#define LED_R(a)    if(a)\
                                        GPIO_SetBits(GPIOB, GPIO_Pin_5); \
                                    else \
                                        GPIO_ResetBits(GPIOB, GPIO_Pin_5);

  主函数main()里面写。

#include "stm32f10x.h"
#include "bsp_led.h"

int main(void)
{
	LED_GPIO_Config();
	
	LED_R(ON);
}

小灯点亮

GPIO的输入—按键检测

按下K2点亮R小灯。

原理图

硬件消抖原理

        当K2没有被按下时,PC13与GND相连,为低电平。

        当K2被按下时,1,3导通,首先C61电容充电,当C61充电完成,电流会通过电阻接GND,此时,PC13检测C61电容为高电平。

        这里我们不需要软件消抖,因为加了一个C61电容实现硬件消抖。

        原理如下:K2被按下时,如果存在抖动,K2这个按键上的1,3在短时间内是不断地接通断开。

        当1,3接通时,因为GND有一个R65的电阻存在,电路会优先给C61充电,因为当前是抖动状态,C61是不会充满电的。

        当1,3断开时,C61存储的电流会通过R65电阻流入GND(因为R65的阻值比单片机要小,所以是不会流入PC13进而流入单片机的),所以,C61放电完成。这样就可以实现消抖。

        如果不是抖动,1,3导通,首先C61电容充电,当C61充电完成,电流会通过电阻接GND,此时,PC13检测C61电容为高电平。

编程

        但我们建立好工程文件后,我们在USER文件夹下建立新文件夹并命名为key,在这个文件夹里新建key.h,key.c(名字可以随便取)两个文件。在keil5的工程目录USER里添加key.c文件。

        我们在key.c里写如下代码:

#include "key.h"
void Key_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	/*开启按键端口的时钟*/
	RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);
	
	//选择按键的引脚
	GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN; 
	// 设置按键的引脚为浮空输入
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
	//使用结构体初始化按键
	GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);
	
	//选择按键的引脚
	GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN; 
	//设置按键的引脚为浮空输入
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
	//使用结构体初始化按键
	GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);	
}

 /*
 * 函数名:Key_Scan
 * 描述  :检测是否有按键按下
 * 输入  :GPIOx:x 可以是 A,B,C,D或者 E
 *		     GPIO_Pin:待读取的端口位 	
 * 输出  :KEY_OFF(没按下按键)、KEY_ON(按下按键)
 */
uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{			
	/*检测是否有按键按下 */
	if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON )  
	{	 
		/*等待按键释放 */
		while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON);   
		return 	KEY_ON;	 
	}
	else
		return KEY_OFF;
}

key.h写如下代码:

#ifndef __KEY_H
#define	__KEY_H


#include "stm32f10x.h"

//  引脚定义
#define    KEY1_GPIO_CLK     RCC_APB2Periph_GPIOA
#define    KEY1_GPIO_PORT    GPIOA			   
#define    KEY1_GPIO_PIN		 GPIO_Pin_0

#define    KEY2_GPIO_CLK     RCC_APB2Periph_GPIOC
#define    KEY2_GPIO_PORT    GPIOC		   
#define    KEY2_GPIO_PIN		  GPIO_Pin_13


 /** 按键按下标置宏
	*  按键按下为高电平,设置 KEY_ON=1, KEY_OFF=0
	*  若按键按下为低电平,把宏设置成KEY_ON=0 ,KEY_OFF=1 即可
	*/
#define KEY_ON	1
#define KEY_OFF	0

void Key_GPIO_Config(void);
uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);


#endif /* __KEY_H */

同时我们在配置好LED小灯。

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


int main(void)
{
	LED_GPIO_Config();
	Key1_Config();
	LED_B(OFF);
	
	while(1)
	{
			if(KeyScan(GPIOC, GPIO_Pin_13)==Key_ON)
			{
				LED_B(ON);
			}	
	}
}

因本人水平有限,不足之处在所难免,敬请各位网友指正

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值