STM32入坑(11)LED闪烁+按键控制蜂鸣器(轮询法、中断法)

LED闪烁+按键控制蜂鸣器

  • 简介
  • 配置方法(轮询法)
    • 1. 配置LED
    • 2.配置延时
    • 3.配置按键
    • 4.编写主函数
  • 实验代码(轮询法)
  • 配置方法(中断法)
    • 1. 配置LED
    • 2.配置延时
    • 3.配置按键
    • 4.配置中断
    • 5.编写主函数
  • 实验代码(中断法)
  • 注意事项:

简介

实验名称:LED闪烁+按键控制蜂鸣器
实验现象:两个LED小灯闪烁,按下按键KEY1蜂鸣器响,再按一下蜂鸣器不不响
硬件需求:STM32单片机,LED灯,按键,蜂鸣器

配置方法(轮询法)

1. 配置LED

实现LED初始化函数LED_Init();

2.配置延时

实现延时函数:void delay_ms(u16 nms)

3.配置按键

实现按键初始化函数:void KEY_Init(void);
实现按键扫描函数:uint8_t KEY_Scan(uint8_t mode)

4.编写主函数

最重要的就是主函数了,不能采用普通的延时做法:LED1亮–延时–LED1灭–LED2亮–延时–LED2灭–延时–扫描按键。这样的做法会使单片机处理信息阻塞,导致按键不灵敏。
应该使用轮询法:单片机有个小延时,比如10ms,到时间后变量i++。i达到设定值LED闪烁,其他时间扫描按键实现蜂鸣器响/不响。

实验代码(轮询法)

KEY和LED的代码在前面都有,没有变化,这里只贴出主函数。

int main(void)
{
	uint32_t i=0;
	LED_Init();
	KEY_Init(); 
	LED1 = 1;
	LED2 = 1;
	while(1)
	{
		switch(i)
		{
			case 100:LED1 = 0;LED2 = 1;break;
			case 200:LED1 = 1;LED2 = 0;i=0;break;
		}
		i++;
		SysTick_delay_ms(10);
		if(KEY_Scan(0)==2)BEEP=!BEEP;
	}
 }

主函数就是如此简单,就不唠叨了。主要就是while中不断扫描按键,当i的值达到100和200时实现LED翻转。重点是理解轮询法。

配置方法(中断法)

1. 配置LED

实现LED初始化函数LED_Init();

2.配置延时

实现延时函数:void delay_ms(u16 nms)

3.配置按键

实现按键初始化函数:void KEY_Init(void);
(这里就不需要按键扫描了)

4.配置中断

实现中断函数:void MyEXTI_Config(void);//优先级和端口要初始化
实现中断服务函数:void EXTI9_5_IRQHandler(void);//根据硬件配置

5.编写主函数

实验代码(中断法)

主函数:

int main(void)
{
	uint32_t i=0;
	LED_Init();
	KEY_Init(); 
	MyEXTI_Config();	//多了这句,配置中断
	LED1 = 1;
	LED2 = 1;
	while(1)
	{
		switch(i)
		{
			case 100:LED1 = 0;LED2 = 1;break;
			case 200:LED1 = 1;LED2 = 0;i=0;break;
		}
		i++;
		SysTick_delay_ms(10);
		//这里不需要按键扫描了
	}
 }

主函数中加入了中断配置函数,删除了按键扫描函数。
按键控制蜂鸣器的功能放入了中断服务函数,如下:

void EXTI9_5_IRQHandler(void)
{
	u32 i;
	for(i=0;i<100000;i++);
//	SysTick_delay_ms(30);
	if(KEY0==0)
//	if(EXTI_GetITStatus(EXTI_Line5) != RESET)
	{
		BEEP=!BEEP;
	}
	EXTI_ClearITPendingBit(EXTI_Line5);
}

注意事项:

主函数中的while使用了滴答延时函数,在中断中就不能使用滴答延时函数,否则会造成程序卡死。中断中使用的是for循环实现延时。如果控制效果不佳,可以根据硬件延长或缩短for循环时间。

程序已经过调试验证
完整程序传送门:
https://download.csdn.net/download/m0_46195580/13757707

你可能感兴趣的:(单片机,单片机,stm32,经验分享)