4、【STM32】蜂鸣器/按键实验

目录

前言

理论学习

一、蜂鸣器简介

二、机械按键简介

三、GPIO配置简介

实践学习 

一、设计规划

1.1 实验目标 

1.2 硬件资源

二、程序设计

2.1 建立工程文件

2.2 led配置

2.3 beep配置

2.4 key配置

2.5 主函数text.c

三、在线调试

3.1 相应寄存变化

3.2 关键变量变化

四、上板验证


前言

使用的是正点原子的探索者开发板进行学习,芯片:STM32F407ZGTx

学习说明此文档为本人的学习笔记,注重实践,关于理论部分会给出相应的学习链接。


本文档添加了对代码的在线调试功能,有助于大家更好理解相关寄存器的变化。


理论学习

一、蜂鸣器简介

探索者开发板上搭载的是电磁式有源蜂鸣器,关于无源蜂鸣器的介绍请参考我另一篇博文:

二、17【FPGA】无源蜂鸣器驱动实验_追逐者-桥的博客-CSDN博客蜂鸣器按其结构可分为电磁式蜂鸣器和压电式蜂鸣器两种类型。压电式蜂鸣器是以压电陶瓷的压电效应,来带动金属片的振动而发声;而电磁式蜂鸣器则是用电磁的原理,通电时将金属振动膜吸下,不通电时以振动膜的弹力弹回。https://blog.csdn.net/ARM_qiao/article/details/124837227有源蜂鸣器自带了震荡电路 ,只需要对其上电即发声;无源蜂鸣器需要提供相应的方波才发声。

32的IO口可以直接驱动LED灯(所需电流较小)。STM32F4的单个IO可以提供25mA电流,而蜂鸣器的驱动电流为30mA左右,但是STM32F4整体才150mA,直接驱动会非常浪费资源,因此IO口并不是直接驱动,而是通过三极管扩流后再驱动蜂鸣器。

二、机械按键简介

开发板上搭载的是机械微动开关按键,这种按键在使用时需要注意其抖动,按下时,信号不会立刻稳定,相关描述请参考:

二、13【FPGA】按键消抖_追逐者-桥的博客-CSDN博客按键消抖代码实现https://blog.csdn.net/ARM_qiao/article/details/124731574需要进行按键消抖,这里通常采用软件程序消抖的方法来避免抖动。

三、GPIO配置简介

由于在上一篇跑马灯博文中已经做了介绍,如果不是特别了解GPIO的配置。请参考:

[Skill] STM32的GPIO工作原理及工作模式_追逐者-桥的博客-CSDN博客STM32的IO口电路原理及工作模式如何选择GPIO口模式https://blog.csdn.net/ARM_qiao/article/details/125080228

实践学习 

一、设计规划

蜂鸣器实验和按键实验与跑马灯类似,都是对GPIO进行操作,因此本博文将两者放到了一起进行实现。

1.1 实验目标 

利用板载的4个按键,来控制板载的两个LED的亮灭和蜂鸣器的开关。

1.2 硬件资源

 除KEY_UP是高电平有效(且外部无上下拉电阻,需要在32内部设置上下拉),其他按键是低电平有效。

二、程序设计

2.1 建立工程文件

如图已经添加完的工程文件目录。

2.2 led配置

板载对应的GPIO口为PF9/10,并将其配置为通用推挽输出模式,输出速度100MHz

  • led.h文件
#ifndef _LED_H
#define _LED_H
#include "sys.h"
//LED端口定义
#define LED0 PFout(9)
#define LED1 PFout(10)

void LED_Init(void);

#endif
  • led.c文件
#include"led.h"

void LED_Init(void)
{
	RCC->AHB1ENR |= 1<<5;   //使能GPIOF时钟
	GPIO_Set(GPIOF, PIN9|PIN10,
			 GPIO_MODE_OUT, GPIO_OTYPE_PP,
			 GPIO_SPEED_100M, GPIO_PUPD_PU);
	//初值
	LED0 = 1;
	LED1 = 1;
}

2.3 beep配置

蜂鸣器比较见到,就是一个GPIO输入 高低电平

  • beep.h
#ifndef _BEEP_H
#define _BEEP_H
#include "sys.h"
#define BEEP PFout(8)

void  BEEP_Init(void);

#endif
  • beep.c

由于蜂鸣器是高电平有效,因此将端口配置为下拉推挽输出

#include"beep.h"

void BEEP_Init(void)
{
	RCC->AHB1ENR |= 1<<5;
	GPIO_Set(GPIOF, PIN8,
			 GPIO_MODE_OUT, GPIO_OTYPE_PP, 
			 GPIO_SPEED_100M, GPIO_PUPD_PU);
	BEEP = 0;   //初值关闭蜂鸣器
}

2.4 key配置

  • key.h
#ifndef _KEY_H
#define _KEY_H
#include "sys.h"
#define KEY0  PEin(4)   //PE4
#define KEY1  PEin(3)	//PE3
#define KEY2  PEin(2)	//PE2
#define WK_UP PAin(0)	//PA0
#define KEY0_PRES 1   //KEY0 
#define KEY1_PRES 2   //KEY1 
#define KEY2_PRES 3   //KEY2 
#define WKUP_PRES 4   //KEY_UP ( WK_UP)

void KEY_Init(void);
u8 KEY_Scan(u8 mode);       //按键扫描函数

#endif
  • key.c
#include"key.h"
#include"delay.h"     //ÐèÒªÑÓ³ÙÅжÏÏû³ý¶¶¶¯
void KEY_Init(void)
{
	RCC->AHB1ENR |= 1<<0;    //GPIOA
	RCC->AHB1ENR |= 1<<4;    //GPIOE
	GPIO_Set(GPIOA, PIN0, GPIO_MODE_IN,
			 0, 0,  			
			 GPIO_PUPD_PD);     //PA0 高电平有效因此为下拉
	GPIO_Set(GPIOE, PIN2|PIN3|PIN4, GPIO_MODE_IN,
			 0, 0,
			 GPIO_PUPD_PU);     //低电平有效,上拉
}
u8 KEY_Scan(u8 mode)
{
	static u8 key_up = 1;   //静态局部变量
	if(mode) key_up = 1;    //当有按键按下时,按下标志
	if(key_up && (KEY0==0 || KEY1==0 || KEY2==0 || WK_UP==1))  
	{
		delay_ms(10);       //ÑÓ³ÙÅжϣ¬ÒÔÏû³ý¶¶¶¯
		key_up = 0;
		if(KEY0==0) return 1;
		else if(KEY0==0) return 1;
		else if(KEY1==0) return 2;
		else if(KEY2==0) return 3;
		else if(WK_UP==1) return 4;
	}
	else if(KEY0==1 && KEY1==1 && KEY2==1 && WK_UP==0) 
		key_up =1;
	return 0;    //ÎÞ°´¼ü°´ÏÂ
}

一定要注意高低电平有效,本人在敲代码的时候PA0(高电平有效)设置为了上拉(有问题);PE2-4(低电平)设置为了下拉(错误)。   如果这样设置就会出现,按键是否按下一直有效,因为按下也是相应的状态。 

2.5 主函数text.c

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "beep.h"
#include "key.h"
int main(void)
{
	u8 key;
	Stm32_Clock_Init(336,8,2,7);   //设置时钟 168M
	delay_init(168);
	LED_Init();
	BEEP_Init();
	KEY_Init();
	LED0 = 0;
	while(1)
	{
		key = KEY_Scan(0);   
		if(key)
		{
			switch(key)
			{
				case WKUP_PRES:    
					BEEP =! BEEP;
					break;
				case KEY2_PRES:
					LED0 =! LED0;
					break;
				case KEY1_PRES:
					LED1 =! LED1;
					break;				
				case KEY0_PRES:
					LED0 =! LED0;
					LED1 =! LED1;
					break;													
			}  
		}else delay_ms(10);      		       
	}	
}

三、在线调试

下载完成完成后,打开调试,点击运行,并调出相关的寄存器。

3.1 相应寄存变化

  • 按键GPIOE口,可以看出按键的相关位的状态,如图由于按键低电平有效(上拉),此时相应的位被拉高。

  • LED灯/蜂鸣器的GPIOF口,输出数据ODR 寄存器状态(低电平有效),默认LED0亮;蜂鸣器高电平有效(不响) 。

 当KEY0按键按下时,PE4由高电平变为低电平,LED0,LED1状态转换

 蜂鸣器类似,这里不做演示。

3.2 关键变量变化

点击可以添加变量,然后添加变量;也可以直接选中变量点击右键选择“add "key"to Watch1。

在变量key后面打一个断点,将代码运行到此

 在板子上按下KEY0,可以观察到扫描函数返回值,key=1。与上面的寄存器变化相对应。

四、上板验证

整体编译没有问题:

 下载到板卡中即可实现相应的功能。

  • 6
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

追逐者-桥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值