STM32F103ZET6——按键中断控制LED蜂鸣器

正题引入:

按键中断控制LED蜂鸣器,首先确定按键属于输入信号,需要向开发板输入电平来对LED灯和蜂鸣器进行控制,那么我们需要做的分为以下几步:
  1. 首先查看开发板原理图,确定你所需要控制的KEY和LED以及BEEP位于哪个引脚

从下图可以得到KEY的引脚分别为PE2-PE3,LED引脚为PC0-PC7,BEEP引脚为PB5
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

从下图看出KEY对应为高电平时可以触发中断,LED需要低电平才可以被点亮,BEEP由于这里是无源蜂鸣器则需要不停使其引脚高低电平转换才可以响。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  1. 查看好所需要配置的GPIO引脚后,再确定引脚所需要的工作模式。这里的LED灯显而易见,肯定是需要开发板给予高低电平才可以使其工作,并且我们这里给其配置为带数字推挽输出。KEY则一般是设置为上拉输入,BEEP的工作原理模式配置与LED类似。
    下面分别是GPIOx_CRH和GPIOx_CRL的寄存器原理图
    以配置PC0为例:这里是需要给LED配置带数字推挽输出,那么则需要将GPIOx_CRL的MODE0[1:0]=01即输出模式,最大速率为10MHz
    CNF0[1:0]=00 即推挽输出模式

    配置KEY1:需要给PE1设置为上拉输入模式
    配置BEEP:需要给PB5设置为推挽输出模式

在这里插入图片描述在这里插入图片描述

  1. 接下来就是需要对上面两步进行程序化,也就是化成程序,比如这个地方需要程序化:
    LED_Init() // 初始化函数
    KEY_Init() // 初始化函数
    BEEP_Init() // 初始化函数

    初始化首先需要开启相应引脚时钟:这里LED对应的是PC引脚,那么需要使能PC的时钟以及PE和PB的时钟在这里插入图片描述
    在这里插入图片描述

    LED_Control(para1,para2)//LED控制函数
    BEEP_Ring() // BEEP控制函数
    EXTI2_IRQHandler() // 按键的中断服务函数(关键)

  2. 最后就是应用层main.c的编写,根据需求去完成。

这里分别以HAL库函数版和寄存器版进行举例

HAL库函数版:

KEY.c如下(.h文件由自己发挥):

void KEY_Init(void) // 初始化
{
		GPIO_InitTypeDef GPIO_InitStructure ={0};
		__HAL_RCC_GPIOE_CLK_ENABLE(); // 开启时钟
		/*Configure GPIO pins : PE2 PE3 PE4 */
		GPIO_InitStructure.Pin = KEY1_Pin;
			
		GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING; // 下降沿触发
		GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
		GPIO_InitStructure.Pull = GPIO_PULLUP;  // 上拉输入
		
		HAL_GPIO_Init(KEY_GPIO_Port, &GPIO_InitStructure);
		
		HAL_GPIO_WritePin(KEY_GPIO_Port, KEY1_Pin, GPIO_PIN_SET);
		HAL_NVIC_SetPriority(EXTI2_IRQn, 1, 0); 
    	HAL_NVIC_EnableIRQ(EXTI2_IRQn);
}

LED.c如下(.h文件由自己发挥):

void LED_Init(void) // LED初始化
{
		GPIO_InitTypeDef GPIO_InitStructure ={0};
		__HAL_RCC_GPIOC_CLK_ENABLE();
	
		GPIO_InitStructure.Pin = LED1_Pin ;  // LED1_Pin 相当于 PC0
		GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // 设置为推挽输出
		GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; // 低速
			
		HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStructure);	
		HAL_GPIO_WritePin(LED_GPIO_Port, LED1_Pin, GPIO_PIN_SET); // 默认输出低电平
		
}
void Led_Ctrl(int No, LED_Staus staus)
{
		switch(No)
		{
			case 1:
			{
				if(staus == LED_ON)  // 开灯
				{
							HAL_GPIO_WritePin(GPIOB, LED_Pin, GPIO_PIN_RESET);
				}
				else                 // 关灯
				{
							HAL_GPIO_WritePin(GPIOB, LED_Pin, GPIO_PIN_SET);
				}	
				break;
			}
			default:
				break;
		}
}

BEEP.c如下(.h文件由自己发挥):

void Beep_Init(void)
{
			GPIO_InitTypeDef GPIO_InitStructure ={0};
			
			__HAL_RCC_GPIOB_CLK_ENABLE();  // 使能时钟
			
			GPIO_InitStructure.Pin = BEEP_Pin ; 	
			GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出
			GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; 
			
			HAL_GPIO_Init(BEEP_GPIO_Port, &GPIO_InitStructure);	
			HAL_GPIO_WritePin(BEEP_GPIO_Port, BEEP_Pin, GPIO_PIN_RESET);
}

void Beep_Ring(void) 
{	
			uint16_t i;
			while(i<=3000)
			{
				HAL_GPIO_TogglePin(BEEP_GPIO_Port,BEEP_Pin); 
				delaynms(30);
				i++;
			}
}

void delaynms(uint16_t i)
{
		uint16_t j;
		while(i--)
		{
				for(j = 0; j < 125; j++) // 1ms
				{	
				}
		}
}

EXTI2_IRQHandler() 如下:

void EXTI2_IRQHandler(void)
{
	HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
		LOS_TaskDelay(20); // 消除抖动
		switch(GPIO_Pin)
		{
			case GPIO_PIN_2: 
			{
					Led_Ctrl(1,LED_ON);
					Beep_Ring();
					break;
			}
			default: break;
		}
}

寄存器版:

LED.c如下(.h文件由自己发挥):

void LED_Init(void) // LED初始化
{
		RCC->APB2ENR |= (1 << 4); // 需要左移几位具体需要看前面,寄存器原理图引脚所对应为第几位
								  // 这里PC对应第四位,所以这里左移4
		GPIOC->CRL &= ~ (0xF << 0); // 置为前先清零,养成好习惯,需要左移几位同样是看引脚对应为第几位
		GPIOC->CRL |= 1 << 0; // 设置为推挽输出模式
		GPIOC->BSRR = 1 << 0; // 默认输出高电平	
}
void Led_Ctrl(int No, LED_Staus staus)
{
		switch(No)
		{
			case 1:
			{
				if(staus == LED_ON)  // 开灯
				{
							GPIOC->BRR = 1 << 0; // 开灯
				}
				else                 // 关灯
				{
							GPIOC->BSRR = 1 << 0; // 关灯
				}	
				break;
			}
			default:
				break;
		}
}

BEEP.c如下(.h文件由自己发挥):

void BEEP_Init(void) // LED初始化
{
		RCC->APB2ENR |= (1 << 2); // 需要左移几位具体需要看前面,寄存器原理图引脚所对应为第几位
		GPIOB->CRL &= ~ (0xF << 0); // 置为前先清零,养成好习惯,需要左移几位同样是看引脚对应为第几位
		GPIOB->CRL |= 1 << 20; // 设置为推挽输出模式
}

void Beep_Ring(void) 
{	
			uint16_t i;
			while(i<=3000)
			{
				GPIOB->BRR = 1 << 5; 
				delaynms(30);
				GPIOB->BSRR = 1 << 5;
				i++;
			}
}

void delaynms(uint16_t i)
{
		uint16_t j;
		while(i--)
		{
				for(j = 0; j < 125; j++) // 1ms
				{	
				}
		}
}

KEY.c如下(.h文件由自己发挥):

void KEY_Init(void) // LED初始化
{
		RCC->APB2ENR |= (1 << 0); // AFIO口的时钟源
		RCC->APB2ENR |= (1 << 6); // 需要左移几位具体需要看前面,寄存器原理图引脚所对应为第几位
		GPIOE->CRL &= ~ (0xF << 8); // 置为前先清零,养成好习惯,需要左移几位同样是看引脚对应为第几位
		GPIOE->CRL |= 8 << 8; // 设置为上拉输入模式
		GPIOE->ODR |= 1 << 2; // 默认输出高电平
		AFIO->EXTICR1 &= ~(0xF << 8);
		AFIO->EXTICR1 |= 4 << 8; // 将PE2口用作外部中断EXTI2输入
		EXTI->IMR |= 1 << 2; // 打开中断
		EXTI->FTSR |= 1 << 2; // 外部中断为下降沿触发
		NVIC_EnableIRQ(EXTI2_IRQn); // 使能中断
		NVIC_SetPriority(EXTI2_IRQn,1); // 设置中断优先级
}

void EXTI2_IRQHandler() // 中断服务函数
{
		Led_Ctrl(1,LED_ON);
		BEEP_Ring();
		EXTI->PR = 1 << 2; // 清除中断标志位
}
一起加油吧,有问题都可以在评论区留言呀,会及时回复的!
  • 15
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我蘑菇先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值