目录
接上一讲,今天的通过按键控制蜂鸣器、光敏电阻声光报警两个例子继续学习GPIO的输出和输入函数。
另外新创建了公众号“宝藏Code园”,本系列相关代码将在公众号里面开源。需要本例子代码可以关注公众号后台回复“第二讲”获取(免费),或者点击置顶资源链接。
1.硬件准备
二极管,面包板,跳线若干,按键,光敏电阻,蜂鸣器,STM32F103C8T6最小系统板。
2.理论知识
2.1 蜂鸣器
- 有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定
- 无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音
-
2.2 按键
- 按键:常见的输入设备,按下导通,松手断开
- 按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动
3.接线图
接线过程中,一定要仔细,选择端口不一样,记得在代码中也要调整哦。图中显示器部分可忽略。
按键控制蜂鸣器
光敏电阻声光报警
4.代码部分
GPIO部分的代码讲解,见第一讲。
5.实际操作
5.1 打开工程模板
工程模板获取方式在文章开头 。
5.2 新建文件
为了方便代码编写,可以把每个模块代码写入单独文件中,最后在主函数调用即可。
1.新建文件
2.保存文件,保存到Hardware文件夹中
3.加入库
5.3 编写蜂鸣器代码
Buzzer.c中代码
#include "stm32f10x.h" // Device header
//初始化BUZZER
void Buzzer_Init(void) //.记住h声明
{
//RCC开启GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//结构体初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
//复制结构体名字,用点把结构体成员都引出来
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出,高低电平均可
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//将结构体地址放到Init函数的第二个参数
GPIO_Init(GPIOA, &GPIO_InitStructure);
//蜂鸣器默认关闭
GPIO_SetBits(GPIOA,GPIO_Pin_11 );
}
//开启Buzzer
void Buzzer_ON(void)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_11);
}
//关闭Buzzer
void Buzzer_OFF(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_11);
}
//状态取反,翻转
void Buzzer_Turn(void)
{
if (GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_11) ==0)//如果输出寄存器为0
{
GPIO_SetBits(GPIOA,GPIO_Pin_11);
}
else//如果输出寄存器为1
{
GPIO_ResetBits(GPIOA,GPIO_Pin_11);
}
}
5.4 编写按键代码
Key.c中的代码
代码当中用到的消除抖动的延时函数,已经帮大家写好了,直接用进行,直接下载工程文件获取就行。
#include "stm32f10x.h" // Device header
#include "Delay.h"
//初始化按键
void Key_Init(void) //.记住h声明
{
//RCC开启GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//结构体初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
//复制结构体名字,用点把结构体成员都引出来
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//将结构体地址放到Init函数的第二个参数
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//读取按键值
//按键键码默认给0,没有按键按下,返回0
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0;
//GPIO读取函数
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0)
{
Delay_ms(20);//消除抖动
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0)//按键一直按下,直到松手
Delay_ms(20);
KeyNum = 1;
}
return KeyNum;
}
5.5 编写LED代码
Led.c中的代码
#include "stm32f10x.h" // Device header
//初始化LED
void LED_Init(void) //.记住h声明
{
//RCC开启GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//结构体初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
//复制结构体名字,用点把结构体成员都引出来
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出,高低电平均可
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//将结构体地址放到Init函数的第二个参数
GPIO_Init(GPIOA, &GPIO_InitStructure);
//LED默认关闭
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
//点亮LED1
void LED1_ON(void)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
//熄灭LED1
void LED1_OFF(void)
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
//LED1状态取反,翻转
void LED1_Turn(void)
{
if (GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1) ==0)
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
else
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
}
5.6 编写光敏电阻代码
LightSensor.c中的代码
#include "stm32f10x.h"
void LightSensor_Init(void)
{
//RCC开启GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//结构体初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
//复制结构体名字,用点把结构体成员都引出来
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//将结构体地址放到Init函数的第二个参数
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//读取端口函数
//返回端口值
uint8_t LightSensor_Get(void)
{
return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);
}
5.7 编写按键控制蜂鸣器的主函数
所有调用到的函数文件,都需要在主函数前面声明
#include "stm32f10x.h" // Device header
#include "Buzzer.h"
#include "Key.h"
//定义全局变量
uint8_t KeyNum;
int main(void)
{
//初始化
Buzzer_Init();
Key_Init();
while (1)
{
KeyNum = Key_GetNum();//不断读取键码值,放在KeyNum变量里
if (KeyNum == 1)
{
Buzzer_Turn();
}
}
}
5.8 编写光敏电阻声光报警的主函数
#include "stm32f10x.h" // Device header
#include "Buzzer.h"
#include "LightSensor.h"
#include "LED.h"
#include "Delay.h"
int main(void)
{
//初始化
Buzzer_Init();
LightSensor_Init();
LED_Init();
while (1)
{
if (LightSensor_Get() == 1)
{
LED1_ON();
Delay_ms(100);
LED1_OFF();
Delay_ms(100);
Buzzer_ON();
Delay_ms(100);
Buzzer_OFF();
Delay_ms(100);
}
else
{
Buzzer_OFF();
LED1_OFF();
}
}
}