踩过的坑!!!红外接收模块输出接口和独立按键k3共用的p32引脚,所以有红外的时候单片机会误以为按了k3按键,测试的时候要把红外接收拔掉,蜂鸣器连接的IO口是P25(江科的是P15),之前学习的时候看弹幕说型号选stc89c51rc2(但我这里的代码没改),就一直选的这个,蜂鸣器也能正常播放提示音,但到后面播放天空之城就会出现音调不准的情况,所以选stc89c51就行,但一定要把P15改成P25!!!
蜂鸣器介绍
驱动方式不同,有源一般用在固定提示驱动简单,无源类似扬声器,普中有源,如何分辨有无源,正负极的判断
在电路中的符号
驱动原理
单片机IO口提高控制信号,实际驱动来自VCC,NPN高电平导通,限流电阻,小电流信号控制大电流蜂鸣器响(图1),PNP低电平导通(图2),单片机IO口不能直接驱动蜂鸣器,就要通过一个芯片ULN2003
ULN2003
com公共端口,7个非门(由达林顿管组成,具有很强的驱动能力),ULN2003芯片接在其中一路
五线四相步进电机,左边(P15)为IO口,提供信号(普中新版开发板改成了P25,这里用的还是江科提供的PPT内容),BZ连接到蜂鸣器
c1、c2之间相差8度,c到d是一个全音,中间的黑键是中界线(半音),数字上下加点配合升高半音(#),降低半音(b),只要模拟出音的高低和按下按键的时间长短,就能完成音乐的演奏 。
通过定时器控制蜂鸣器多长时间响一次,由于频率不好计算,一般采用周期,一个机器周期等于12个晶振周期,11.0592M/12=对应的机器频率,1/12这个频率才是对应的周期。IO口翻转,将周期分为2部分,一部分是发声,一部分是不发声。
驱动方式
自激蜂鸣器是直流电压驱动的,不需要利用交流信号进行驱动,只需对驱动口输出驱动电平并通过三极管放大驱动电流就能使蜂鸣器发出声音。
单片机驱动他激蜂鸣器的方式有两种:一种是PWM 输出口直接驱动,另一种是利用I/O 定时翻转电平产生驱动波形对蜂鸣器进行驱动。
PWM 输出口直接驱动是利用PWM 输出口本身可以输出一定的方波来直接驱动蜂鸣器。在单片机的软件设置中有几个系统寄存器是用来设置PWM 口的输出的,可以设置占空比、周期等等,通过设置这些寄存器产生符合蜂鸣器要求的频率的波形之后,只要打开PWM 输出,PWM 输出口就能输出该频率的方波,这个时候利用这个波形就可以驱动蜂鸣器了。
利用I/O 定时翻转电平来产生驱动波形的方式会比较麻烦一点,必须利用定时器来做定时,通过定时翻转电平产生符合蜂鸣器要求的频率的波形,这个波形就可以用来驱动蜂鸣器了。比如为100Hz 的蜂鸣器的驱动,可以知道周期为10000μs,这样只需要驱动蜂鸣器的I/O 口每5000μs 翻转一次电平就可以产生一个频率为100Hz,占空比为1/2duty 的方波,再通过三极管放大就可以驱动这个蜂鸣器了。
代码部分
main.c
#include <at89c51RC2.h>
#include "key.h"
#include "smgshow.h"
#include "buzzer.h"
unsigned char keynum;
void main()
{
smgshow(1,0);//初始化(要拔掉红外否则显示有误)
while (1)
{
keynum=key();
if(keynum)//如果按键按下
{
smgshow(1,keynum);//数码管静态显示按键序号
buzzer_time(1000);
}
}
}
buzzer.c
#include <at89c51RC2.h>
#include <INTRINS.H>
sbit buzzer=P2^5;//重新命名蜂鸣器连接的IO口
void Delay500us(void) //@11.0592MHz 延时500微秒
{
unsigned char data i;
_nop_();
i = 227;
while (--i);
}
void buzzer_time(unsigned int xms)
{
unsigned int i;
for(i=0;i<xms*2;i++)//蜂鸣器以1000Hz的频率响xms*2毫秒
{
buzzer=!buzzer;//高电平0.5ms,低电平0.5ms,蜂鸣器周期1ms,频率1000Hz
Delay500us();
}
}
标签:buzzer,蜂鸣器,51,提示音,单片机,IO,驱动,include
From: https://blog.csdn.net/2301_80057226/article/details/143375676