STM32—NB-IOT按键模块

实现按键控制LED颜色转换

GPIO的八种模式

  • 推挽输出(GPIO_OUT_PP)
    推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。

  • 开漏输出(GPIO_OUT_OD)
    一般来说,开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻时,只能输出低电平,如果需要同时具备输出高电平的功能,则需要接上拉电阻,很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平。比如加上上拉电阻就可以提供TTL/CMOS电平输出等。(上拉电阻的阻值决定了逻辑电平转换的速度。阻值越大,速度越低功耗越小,所以负载电阻的选择要兼顾功耗和速度。)

    开漏输出提供了灵活的输出方式,但是也有其弱点,就是带来上升沿的延时。因为上升沿是通过外接上拉无源电阻对负载充电,所以当电阻选择小时延时就小,但功耗大;反之延时大功耗小。所以如果对延时有要求,则建议用下降沿输出。

关于推挽输出和开漏输出,最后用一幅最简单的图形来概括:该图中左边的便是推挽输出模式,其中比较器输出高电平时下面的PNP三极管截止,而上面NPN三极管导通,输出电平VS+;当比较器输出低电平时则恰恰相反,PNP三极管导通,输出和地相连,为低电平。右边的则可以理解为开漏输出形式,需要接上拉。
推挽输出和开漏输出

  • 复用开漏输出(GPIO_AF_PP)和复用推挽输出(GPIO_AF_OD)
    可以理解为GPIO口被用作第二功能时的配置情况(即并非作为通用IO口使用)。
  • 上拉输入(GPIO_IPU)、下拉输入(GPIO_IPD)和模拟输入(GPIO_AIN)
    上拉指外部接上拉电阻,把电位拉高。下拉同理。
    模拟输入指输入模拟信号。
  • 浮空输入(GPIO_IN_FLOATING)
    浮空(floating)就是逻辑器件的输入引脚即不接高电平,也不接低电平。由于逻辑器件的内部结构,当它输入引脚悬空时,相当于该引脚接了高电平。一般实际运用时,引脚不建议悬空,易受干扰。 通俗讲就是让管脚什么都不接,浮空着。

CubeMX配置按键引脚

板子上有两个按键S1U、S2U,分别对应引脚PA15、PC13。
按键原理图
之前我以为按键作为外部下拉,简单的设置为gpio_input就好了,但是后面发现工程代码都生成不了,这里要提一下,硬件的中断机制,硬件有很多的中断信号,这里按键也对应的在MCU中有一个中断处理信号,所以一定要将按键的GPIO设置为中断模式(EXIT)
在这里插入图片描述
在这里简单介绍一下NVIC(嵌套向量中断控制器)。NVIC就是控制中断响应的。主要由三个参数,一个是中断使能,一个是抢占优先级,还有一个就是响应优先级。(优先级数值越小,优先级别越高)
中断使能很好理解,就是是否开启中断,如果开启中断,则满足中断触发条件时程序会跳到中断服务程序运行,否则不响应中断主程序继续运行。
抢占优先级是用来判断一个中断是否可以打断另外一个中断的中断服务程序抢先运行。例如A中断触发,正在运行A中断的服务程序,此时B中断也触发,如果B中断的抢占优先级比A的高,则程序会打断A的中断服务程序,去运行B的中断服务程序,即中断嵌套。等B的中断服务程序运行完后继续运行A的中断服务程序。如果B的抢占优先级没有高过A的抢占优先级,则程序不会打断A的中断服务程序,而是待定A的中断服务程序运行完成后才运行B的中断服务程序。
响应优先级是用来判断抢占优先级相同的几个中断那个中断会优先响应。如果几个抢占优先相同的中断同时触发,那么响应优先级高的最先运行。
判断中断的优先级,先看抢占优先级,抢占优先级高的中断优先级别高。抢占优先级相同的情况下,响应优先高的中断优先级别高。抢占优先级和响应优先级相同的情况下,更加中断向量表确定。如下为部分中断向量表,详细的可以查看stm32F7的数据手册。
在这里插入图片描述
这里因为两个按键中断分别为13和15,所以我们让10到15中断使能。

STM32时钟配置

在这里插入图片描述
外部晶振对应引脚PH0、PH1,设置为RCC_OSC模式

在这里插入图片描述
在这里插入图片描述
板子时钟频率设置为80MHZ
在这里插入图片描述
这里记得选上自动生成c文件和h文件的选项。

代码

在这里插入图片描述
这里就生成了我们的工程文件
接下来我们要实现按下key1按键改变LED的颜色,
按下key2按键开关LED,

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	switch(GPIO_Pin)
	{
		case GPIO_PIN_13:
			if(HAL_GPIO_ReadPin(GPIOB,RedLed_Pin)==GPIO_PIN_RESET)
			{
				HAL_GPIO_TogglePin(GPIOB, RedLed_Pin);
				HAL_GPIO_WritePin(GPIOB,BlueLed_Pin,GPIO_PIN_RESET);
			}
			else if(HAL_GPIO_ReadPin(GPIOB,BlueLed_Pin)==GPIO_PIN_RESET)
			{
				HAL_GPIO_TogglePin(GPIOB, BlueLed_Pin);
				HAL_GPIO_WritePin(GPIOB,GreenLed_Pin,GPIO_PIN_RESET);
			}
			else if(HAL_GPIO_ReadPin(GPIOB,GreenLed_Pin)==GPIO_PIN_RESET)
			{
				HAL_GPIO_TogglePin(GPIOB, GreenLed_Pin);
				HAL_GPIO_WritePin(GPIOB,RedLed_Pin,GPIO_PIN_RESET);
			}
			break;
		case GPIO_PIN_15:
			if(HAL_GPIO_ReadPin(GPIOB,RedLed_Pin)==GPIO_PIN_RESET)
				HAL_GPIO_TogglePin(GPIOB, RedLed_Pin);
			else if(HAL_GPIO_ReadPin(GPIOB,BlueLed_Pin)==GPIO_PIN_RESET)
				HAL_GPIO_TogglePin(GPIOB, BlueLed_Pin);
			else if(HAL_GPIO_ReadPin(GPIOB,GreenLed_Pin)==GPIO_PIN_RESET)
				HAL_GPIO_TogglePin(GPIOB, GreenLed_Pin);
			else
				HAL_GPIO_WritePin(GPIOB, RedLed_Pin, GPIO_PIN_RESET);
			break;
	}
}

调用了中断回调函数,函数在_gpio.c中有定义,只需要在main.c中定义就行了。

烧录后按key2回开启红灯,按key1可以随意切换三色灯,再按key2可以关闭LED灯。

猜你喜欢

转载自blog.csdn.net/qq_40215005/article/details/88427399