GPIO输出——固件库点LED GPIO输入——按键检测

GPIO输出—固件库点亮LED灯

在这里插入图片描述

点亮led灯的原理:LED的阳极接高电平,阴极接IO口。要LED灯亮就要形成闭合回路,IO口接入低电平就能形成闭合回路,点亮LED

一个led驱动的三大功能:

  1. LED亮
  2. LED灭
  3. LED翻转

新建led.c led.h 两个文件存放GPIO初始化函数 (加入工程后记得添加路径!!!)
编写头文件格式:(这样写是为了防止重复定义)

			#ifndef __LED__H
			#define __LED__H
			#endif

在头文件中写宏定义
宏定义是为了方便移植和方便自己有一些很繁琐的变量不用多次去写不易出错

如何寻找固件库的函数:

  1. 首先需要用到什么样的函数就去哪里找,例如用到RCC就去RCC的头文件,用到GPIO就去GPIO的头文件
  2. 在头文件的函数声明,根据函数名找到对应的函数
  3. 跳转到该函数查看函数的作用

自定义GPIO初始化函数:在这过程中我们需要用到固件库的
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)函数
这个函数的功能是:根据GPIO_InitStruct中的指定参数初始化GPIO
如何实现GPIO_Init这个函数?
一开始寻找到对应的引脚,再用结构体指针指向要操作的寄存器,最后赋值就可以实现GPIO的初始化

			void LED_GPIO_Config(void)
			{
			//定义一个GPIO_InitTypeDe类型的变量
				GPIO_InitTypeDef   GPIO_InitStruct;

				//使能外部时钟
			    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,ENABLE);

				//初始化之后引脚默认为低电平,所以初始化的时候把电平拉高
					GPIO_SetBits(LEDR_GPIO_PORT, LEDR_GPIO_PIN);
					GPIO_SetBits(LEDG_GPIO_PORT, LEDG_GPIO_PIN);
					GPIO_SetBits(LEDB_GPIO_PORT, LEDB_GPIO_PIN);
					//初始化GPIO
				    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
				    GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
				    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
				    GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
				    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
				    GPIO_Init(LEDR_GPIO_PORT, &GPIO_InitStruct);
					//调用函数
				    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_11;
				    GPIO_Init(LEDG_GPIO_PORT, &GPIO_InitStruct);

				    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12;
				    GPIO_Init(LEDB_GPIO_PORT, &GPIO_InitStruct);

			}

最后回到main函数控制GPIO引脚的高低电平,从而实现LED的亮、灭和翻转。
可以使用固件库的函数,也可以操作寄存器。
用固件库会用到以下函数:
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) //置位
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //复位
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); //翻转

操作寄存器:

			#define digitalHi(p,i)         {p->BSRRH=i;}
			#define digitalLo(p,i)         {p->BSRRL=i;}
			#define digitalToggle(p,i)     {p->ODR^=i;}

GPIO输入—按键检测

按键是否按下:按键的另一端接3.3的电源,若没有按下,按键所在的电路是不导通的,若按下,按键所在电路导通。检测按键接的引脚的高低电平,就可以判断按键是否按下。
在这里插入图片描述

与上述点LED灯一样,新建KEY.c KEY.h存放初始化GPIO的函数
还要写一个检测按键是否按下的函数
需要用到uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)//读取指定引脚的电平状态
//按键一直按着不松开,等到松开后才返回值,就是一直按着LED灯的状态不会改变

			 uint8_t  KEY_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
			{
			    if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==1)
			    {
			        while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==1);
			        return 1;
			    }
			    else
			        return 0;
			}

其实也可以不写这个函数,在main函数中直接检测

				只要检测到GPIO引脚是高电平,即按键是按下状态,LED就翻转 						
				if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==KEY_ON)
				{
				 GPIO_ToggleBits(GPIOH,GPIO_Pin_11);
				delay(100);
				}

GPIO—位带操作

STM32中必须通过访问位带别名区才能实现位带操作,位带区分为外设位带区和SARM位带区。ABH1和APB1/2这几条总线上的寄存器才有位带别名区。位带区要经过膨胀才能变成位带别名区,一个位膨胀变成4个字节,这样可以高效访问。

//位带区地址转换成位带别名区地址
((addr & 0xF0000000)+0x02000000+((addr &0x000FFFFF)<<5)+(bitnum<<2))
通过指针操作这地址,实现寄存器映射,从而控制引脚的高低电平

发布了13 篇原创文章 · 获赞 19 · 访问量 1821

猜你喜欢

转载自blog.csdn.net/qq_44622367/article/details/96850699