【普中 51-Ai8051 开发攻略】-- 第 7 章 蜂鸣器实验
(1)实验平台普中 51-Ai8051 开发板https://item.taobao.com/item.htm?abbucket17id1026052331067(2)资料下载 普中科技-各型号产品资料下载链接前面章节我们已经介绍了使用单片机的 IO 口输出高低电平 本章我们通过另外一个实验来讲述单片机 IO 口的输出。 通过单片机的一个 IO 口控制板载无源蜂鸣器 实现蜂鸣器控制。 本章分为如下几部分内容7.1 实验介绍7.1.1 实验简介7.1.2 实验目的7.2 硬件设计7.3 软件设计7.3.1 创建和配置工程7.3.1.1 GPIO 配置7.3.1.2 生成工程7.3.2 添加用户驱动代码7.3.2.1 beep.h 文件7.3.2.2 beep.c 文件7.3.2.3 main.c 文件7.4 实验现象7.1 实验介绍7.1.1 实验简介蜂鸣器分有源和无源 有源蜂鸣器控制相对简单 只需得电即可发出声音而无源蜂鸣器需要连续输出一定频率的脉冲信号才能使蜂鸣器发出声音 即循环让 IO 口输出高低电平 最佳发声频率在 1.5K-5KHz 之间 当然其它频率值也能发出声音。 改变脉冲信号的频率和占空比可改变声音的音调和音量。7.1.2 实验目的让芯片的 IO 口连续输出一定频率的脉冲信号 控制板载无源蜂鸣器发声。7.2 硬件设计本实验使用到硬件资源如下1 蜂鸣器模块2 GPIO蜂鸣器模块电路如下所示从电路图中可以看到 芯片的 P25 引脚是用来控制蜂鸣器的 驱动电路ULN2003 芯片 OUT5 管脚输出驱动蜂鸣器 ULN2003 芯片使用简单 输入为高电平输出则为低电平 输入为低电平 输出则为高组态 输出低电平时蜂鸣器得到电压 高组态时 蜂鸣器断开 只要不断输出一定频率高低电平脉冲信号即可发出声音。7.3 软件设计7.3.1 创建和配置工程按照前面章节内容创建一份新工程 并命名为 03-beep 如下所示7.3.1.1 GPIO 配置使能端口和时钟 将 P25 口设置为推挽输出模式、 使能下拉电阻等 如下图所示7.3.1.2 生成工程配置完成后 按下代码生成按钮 自动创建工程 系统开始生成初始化代码。生成工程文件目录如下图所示在工程文件夹内新建一个 APP 文件夹 用于存储用户编写的外设驱动 方便后期工程管理和程序移植。 在 APP 文件夹下新建 beep 文件夹 并在该文件夹内新建 beep.c 和 beep.h 文件 用于保存蜂鸣器相关驱动 如下所示然后再导出的工程中添加 APP 组 并将 beep.c 导入到工程组内 最后添加头文件路径 否则编译将报错。 如下添加完以后 如下图所示7.3.2 添加用户驱动代码7.3.2.1 beep.h 文件#ifndef _beep_H #define _beep_H #include config.h //管脚定义 #define BEEP P25 //函数声明 void BEEP_Alarm(u16 times,u16 us); #endif该文件主要是对 beep.c 源文件的函数声明以及端口管脚的宏定义 方便其他文件调用该函数。 在该头文件中可以看到使用了一个定义头文件的结构 代码如下#ifndef _beep_H #define _beep_H //此处省略头文件定义的内容 #endif它的功能是防止头文件被重复包含 避免引起编译错误。 在头文件的开头使用“ #ifndef” 关键字 判断标号“ _beep_H” 是否被定义 若没有被定义则从“ #ifndef” 至“ #endif” 关键字之间的内容都有效 也就是说 这个头文件若被其它文件“ #include” 它就会被包含到其该文件中 且头文件中紧接着使用“ #define” 关键字定义上面判断的标号“ _beep_H” 。 当这个头文件被同一个文件第二次“ #include” 包含的时候 由于有了第一次包含中的“ #define _beep_H” 定义 这时再判断“ #ifndef _beep_H” 判断的结果就是假了 从“ #ifndef” 至“ #endif” 之间的内容都无效 从而防止了同一个头文件被包含多次 编译时就不会出现“ redefine重复定义 ” 的错误了。一般来说 我们不会直接在 C 的源文件写两个“#include” 来包含同一个头文件但可能因为头文件内部的包含导致重复 这种代码主要是避免这样的问题。 如“beep.h” 文件中调用了#include “config.h” 头文件 可能我们写主程序的时候会在 main 文件开始处调用#include “config.h” 和“beep.h” 这个时候“config.h” 文件就被包含两次了 如果在头文件中没有这种机制 编译器就会报错。7.3.2.2 beep.c 文件beep.c 中只需添加相应头文件和蜂鸣器控制函数如下#include beep.h //蜂鸣器报警 //times 报警次数 //us 延时微秒时间 void BEEP_Alarm(u16 times,u16 us) { while(times--) { BEEP!BEEP; delay_us(us); } }该函数用于实现蜂鸣器报警功能 通过函数参数可控制报警次数和每次响时间。7.3.2.3 main.c 文件//AICUBE_USER_HEADER_REMARK_BEGIN /* 深圳市普中科技有限公司PRECHIN 普中 * 在线视频https://space.bilibili.com/2146492485/video 官网www.prechin.cn * 实验名称蜂鸣器实验 * * 接线说明蜂鸣器模块--单片机IO * BEEP--P25 * * 实验现象程序下载成功后蜂鸣器发出“滴”声后停止 * * 注意事项 * */ //AICUBE_USER_HEADER_REMARK_END #include config.h //默认已包含stdio.h、intrins.h、ai_usb.h等头文件 //AICUBE_USER_INCLUDE_BEGIN // 在此添加用户头文件包含 #include beep.h //AICUBE_USER_INCLUDE_END //AICUBE_USER_GLOBAL_DEFINE_BEGIN // 在此添加用户全局变量定义、用户宏定义以及函数声明 //AICUBE_USER_GLOBAL_DEFINE_END //////////////////////////////////////// // 项目主函数 // 入口参数: 无 // 函数返回: 无 //////////////////////////////////////// void main(void) { //AICUBE_USER_MAIN_INITIAL_BEGIN // 在此添加用户主函数初始化代码 //AICUBE_USER_MAIN_INITIAL_END SYS_Init(); //AICUBE_USER_MAIN_CODE_BEGIN // 在此添加主函数中运行一次的用户代码 BEEP_Alarm(500,1000); //AICUBE_USER_MAIN_CODE_END while (1) { //AICUBE_USER_MAIN_LOOP_BEGIN // 在此添加主函数中用户主循环代码 //AICUBE_USER_MAIN_LOOP_END } } //////////////////////////////////////// // 系统初始化函数 // 入口参数: 无 // 函数返回: 无 //////////////////////////////////////// void SYS_Init(void) { EnableAccessXFR(); //使能访问扩展XFR AccessCodeFastest(); //设置最快速度访问程序代码 AccessIXramFastest(); //设置最快速度访问内部XDATA IAP_SetTimeBase(); //设置IAP等待参数,产生1us时基 P0M0 0x00; P0M1 0x00; //初始化P0口为准双向口模式 P1M0 0x00; P1M1 0x00; //初始化P1口为准双向口模式 P2M0 0x00; P2M1 0x00; //初始化P2口为准双向口模式 P3M0 0x00; P3M1 0x00; //初始化P3口为准双向口模式 P4M0 0x00; P4M1 0x00; //初始化P4口为准双向口模式 P5M0 0x00; P5M1 0x00; //初始化P5口为准双向口模式 P6M0 0x00; P6M1 0x00; //初始化P6口为准双向口模式 P7M0 0x00; P7M1 0x00; //初始化P7口为准双向口模式 CLK_Init(); //时钟模块初始化 PORT2_Init(); //P2口初始化 //AICUBE_USER_INITIAL_CODE_BEGIN // 在此添加用户初始化代码 //AICUBE_USER_INITIAL_CODE_END } //////////////////////////////////////// // 微秒延时函数 // 入口参数: us (设置延时的微秒值) // 函数返回: 无 //////////////////////////////////////// void delay_us(uint16_t us) { do { NOP(34); //(MAIN_Fosc 500000) / 1000000 - 6 } while (--us); } //////////////////////////////////////// // 毫秒延时函数 // 入口参数: ms (设置延时的毫秒值) // 函数返回: 无 //////////////////////////////////////// void delay_ms(uint16_t ms) { uint16_t i; do { i MAIN_Fosc / 6000; while (--i); } while (--ms); } //AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN // 在此添加用户函数实现代码 //AICUBE_USER_FUNCTION_IMPLEMENT_END7.4 实验现象将程序编译下载到目标板运行 实验现象 蜂鸣器发出“滴” 声后停止。