单片机学习路程(四)蜂鸣器唱歌

2020-08-02来源: eefocus关键字:单片机  蜂鸣器唱歌  频率

今天学习单片机蜂鸣器后,发现蜂鸣器的频率经过控制后可以实现唱歌的功能,就在网上找了相关教程,下面分享给大家。


代码亲测,可直接复制使用。


代码内附语句注释,理解应该不难。


#include

#define SYSTEM_OSC 11059200//12000000 //定义晶振频率12000000HZ 

#define SOUND_SPACE 4/5 //定义普通音符演奏的长度分率,//每4分音符间隔 

sbit BeepIO = P2^0; //定义输出管脚 

unsigned int code FreTab[12] = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表 

unsigned char code SignTab[7] = { 0,2,4,5,7,9,11 }; //1~7在频率表中的位置 

unsigned char code LengthTab[7]= { 1,2,4,8,16,32,64 }; 

unsigned char Sound_Temp_TH0,Sound_Temp_TL0; //音符定时器初值暂存 

unsigned char Sound_Temp_TH1,Sound_Temp_TL1; //音长定时器初值暂存 

//************************************************************************** 

void InitialSound(void) 

BeepIO = 1; 

Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256; // 计算TL1应装入的初值 (10ms的初装值) 

Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256; // 计算TH1应装入的初值 

TH1 = Sound_Temp_TH1; 

TL1 = Sound_Temp_TL1; 

TMOD |= 0x11; 

ET0 = 1; 

ET1 = 0; 

TR0 = 0; 

TR1 = 0; 

EA = 1; 

void BeepTimer0(void) interrupt 1 //音符发生中断 

BeepIO = !BeepIO; 

TH0 = Sound_Temp_TH0; 

TL0 = Sound_Temp_TL0; 

//************************************************************************** 

void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed) 

unsigned int NewFreTab[12]; //新的频率表 

unsigned char i,j; 

unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;

unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD; 

for(i=0;i<12;i++) // 根据调号及升降八度来生成新的频率表 

j = i + Signature; 

if(j > 11) 

j = j-12; 

NewFreTab[i] = FreTab[j]*2; 

else 

NewFreTab[i] = FreTab[j]; 

if(Octachord == 1) 

NewFreTab[i]>>=2; 

else if(Octachord == 3) 

NewFreTab[i]<<=2; 

SoundLength = 0; 

while(Sound[SoundLength] != 0x00) //计算歌曲长度 

SoundLength+=2; 

Point = 0; 

Tone = Sound[Point]; 

Length = Sound[Point+1]; // 读出第一个音符和它时时值 

LDiv0 = 12000/Speed; // 算出1分音符的长度(几个10ms) 

LDiv4 = LDiv0/4; // 算出4分音符的长度 

LDiv4 = LDiv4-LDiv4*SOUND_SPACE; // 普通音最长间隔标准 

TR0 = 0; 

TR1 = 1; 

while(Point < SoundLength) 

SL=Tone%10; //计算出音符 

SM=Tone/10%10; //计算出高低音 

SH=Tone/100; //计算出是否升半 

CurrentFre = NewFreTab[SignTab[SL-1]+SH]; //查出对应音符的频率 

if(SL!=0) 

if (SM==1) CurrentFre >>= 2; //低音 

if (SM==3) CurrentFre <<= 2; //高音 

Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//计算计数器初值 

Sound_Temp_TH0 = Temp_T/256; 

Sound_Temp_TL0 = Temp_T%256; 

TH0 = Sound_Temp_TH0; 

TL0 = Sound_Temp_TL0 + 12; //加12是对中断延时的补偿 

SLen=LengthTab[Length%10]; //算出是几分音符 

XG=Length/10%10; //算出音符类型(0普通1连音2顿音) 

FD=Length/100; 

LDiv=LDiv0/SLen; //算出连音音符演奏的长度(多少个10ms) 

if (FD==1) 

LDiv=LDiv+LDiv/2; 

if(XG!=1) 

if(XG==0) //算出普通音符的演奏长度 

if (SLen<=4) 

LDiv1=LDiv-LDiv4; 

else 

LDiv1=LDiv*SOUND_SPACE; 

else 

LDiv1=LDiv/2; //算出顿音的演奏长度 

else 

LDiv1=LDiv; 

if(SL==0) LDiv1=0; 

LDiv2=LDiv-LDiv1; //算出不发音的长度 

if (SL!=0) 

TR0=1; 

for(i=LDiv1;i>0;i--) //发规定长度的音 

while(TF1==0); 

TH1 = Sound_Temp_TH1; 

TL1 = Sound_Temp_TL1; 

TF1=0; 

if(LDiv2!=0) 

TR0=0; BeepIO=1; 

for(i=LDiv2;i>0;i--) //音符间的间隔 

while(TF1==0); 

TH1 = Sound_Temp_TH1; 

TL1 = Sound_Temp_TL1; 

TF1=0; 

Point+=2; 

Tone=Sound[Point]; 

Length=Sound[Point+1]; 

BeepIO = 1; 

//************************************************************************** 

#endif 

//挥着翅膀的女孩 

unsigned char code Music_Girl[]={ 0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x03, 

0x16,0x03, 0x17,0x03, 0x17,0x03, 0x17,0x03, 0x18,0x03, 

0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x02, 0x18,0x03, 

0x17,0x03, 0x15,0x02, 0x18,0x03, 0x17,0x03, 0x18,0x02, 

0x10,0x03, 0x15,0x03, 0x16,0x02, 0x15,0x03, 0x16,0x03, 

0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x1A,0x03, 

0x1B,0x03, 0x1F,0x03, 0x1F,0x03, 0x17,0x03, 0x18,0x03, 

0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x03, 0x17,0x03, 

0x18,0x03, 0x1F,0x03, 0x1F,0x02, 0x16,0x03, 0x17,0x03, 

0x18,0x03, 0x17,0x03, 0x18,0x03, 0x20,0x03, 0x20,0x02, 

0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03, 

0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03, 

0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66, 

0x1A,0x03, 0x19,0x03, 0x15,0x03, 0x15,0x03, 0x17,0x03, 

0x16,0x66, 0x17,0x04, 0x18,0x04, 0x18,0x03, 0x19,0x03, 

0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03, 

0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03, 

0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66, 

0x1A,0x03, 0x19,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03, 

0x1F,0x00, 0x1A,0x03, 0x1A,0x03, 0x1A,0x03, 0x1B,0x03, 

0x1B,0x03, 0x1A,0x03, 0x19,0x03, 0x19,0x02, 0x17,0x03, 

0x15,0x17, 0x15,0x03, 0x16,0x03, 0x17,0x03, 0x18,0x03, 

0x17,0x04, 0x18,0x0E, 0x18,0x03, 0x17,0x04, 0x18,0x0E, 

0x18,0x66, 0x17,0x03, 0x18,0x03, 0x17,0x03, 0x18,0x03, 

0x20,0x03, 0x20,0x02, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 

0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03, 0x1B,0x03, 

0x1F,0x66, 0x1F,0x04, 0x1B,0x0E, 0x1B,0x03, 0x19,0x03, 

0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03, 

0x15,0x03, 0x15,0x03, 0x17,0x03, 0x16,0x66, 0x17,0x04, 

0x18,0x04, 0x18,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03, 

0x1F,0x66, 0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03, 

0x1B,0x03, 0x1F,0x66, 0x1F,0x03, 0x1B,0x03, 0x19,0x03, 

0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03, 

0x19,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x00, 0x18,0x02, 

0x18,0x03, 0x1A,0x03, 0x19,0x0D, 0x15,0x03, 0x15,0x02, 

0x18,0x66, 0x16,0x02, 0x17,0x02, 0x15,0x00, 0x00,0x00}; 

//同一首歌 

unsigned char code Music_Same[]={ 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x66, 0x18,0x03, 

0x17,0x02, 0x15,0x02, 0x16,0x01, 0x15,0x02, 0x10,0x02, 

0x15,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x02, 

0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x02, 0x18,0x66, 

0x17,0x03, 0x19,0x02, 0x16,0x03, 0x17,0x03, 0x16,0x00, 

0x17,0x01, 0x19,0x02, 0x1B,0x02, 0x1B,0x70, 0x1A,0x03, 

0x1A,0x01, 0x19,0x02, 0x19,0x03, 0x1A,0x03, 0x1B,0x02, 

0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x18,0x66, 0x18,0x03, 

0x19,0x02, 0x1A,0x02, 0x19,0x0C, 0x18,0x0D, 0x17,0x03, 

0x16,0x01, 0x11,0x02, 0x11,0x03, 0x10,0x03, 0x0F,0x0C, 

0x10,0x02, 0x15,0x00, 0x1F,0x01, 0x1A,0x01, 0x18,0x66, 

0x19,0x03, 0x1A,0x01, 0x1B,0x02, 0x1B,0x03, 0x1B,0x03, 

0x1B,0x0C, 0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x1F,0x01, 

0x1A,0x01, 0x18,0x66, 0x19,0x03, 0x1A,0x01, 0x10,0x02, 

0x10,0x03, 0x10,0x03, 0x1A,0x0C, 0x18,0x0D, 0x17,0x03, 

0x16,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x70, 

0x18,0x03, 0x17,0x02, 0x15,0x03, 0x15,0x03, 0x16,0x66, 

0x16,0x03, 0x16,0x02, 0x16,0x03, 0x15,0x03, 0x10,0x02, 

0x10,0x01, 0x11,0x01, 0x11,0x66, 0x10,0x03, 0x0F,0x0C, 

0x1A,0x02, 0x19,0x02, 0x16,0x03, 0x16,0x03, 0x18,0x66, 

0x18,0x03, 0x18,0x02, 0x17,0x03, 0x16,0x03, 0x19,0x00, 

0x00,0x00 }; 

//两只蝴蝶 

unsigned char code Music_Two[] ={ 0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03, 

0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02, 

0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03, 

0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x16,0x03, 

0x17,0x01, 0x16,0x03, 0x17,0x03, 0x16,0x03, 0x15,0x01, 

0x10,0x03, 0x15,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03, 

0x16,0x03, 0x15,0x03, 0x10,0x03, 0x15,0x03, 0x16,0x01, 

0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03, 

0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02, 

0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03, 

0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x19,0x03, 

0x19,0x01, 0x19,0x03, 0x1A,0x03, 0x19,0x03, 0x17,0x01, 

0x16,0x03, 0x16,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03, 

0x16,0x03, 0x15,0x03, 0x10,0x03, 0x10,0x0D, 0x15,0x00, 

0x19,0x03, 0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03, 

0x1B,0x03, 0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03, 

0x16,0x0D, 0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03, 

0x1A,0x02, 0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03, 

0x16,0x01, 0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03, 

0x19,0x02, 0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E, 

0x1B,0x04, 0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 

0x1B,0x04, 0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03, 

0x17,0x0D, 0x16,0x03, 0x17,0x03, 0x19,0x01, 0x19,0x03, 

0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03, 0x1B,0x03, 

0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03, 0x16,0x03, 

0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03, 0x1A,0x02, 

0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x01, 

0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03, 0x19,0x03, 

0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04, 

0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04, 

0x17,0x16, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04, 

0x1A,0x03, 0x19,0x03, 0x17,0x

[1] [2]
关键字:单片机  蜂鸣器唱歌  频率 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic504965.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:51单片机的蜂鸣器写歌的音阶
下一篇:8051单片机(STC89C52)两个倒计时器同步计数

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

AVR第11课:如何对待我们的单片机
大家学习MCS51单片机和AVR单片机,又或者是PIC单片机,又或者是MSP430单片机之后,是否感觉自己可以成为一名工程师了呢?我在这里来说说我的看法吧。我们学习这些单片机的时候,先学习了理论知识,这个一般是书本上的理论知识,比如介绍单片机的发展、单片机的应用领域、单片机的原理等等。然后呢找一块开发板,对着视频教程学习,边看视屏边做实验,学习完之后呢,去做那么一两个小项目,比如“基于LabView和PWM的霍尔测速和控速的直流电机系统”,这个项目呢,相对来说综合要求能力比较高,如果一个人能够坐下来的话,你的能力就算不错了,相当不错了。从设计电路图、焊接电路板、写程序、调试等等下来,会有很大的提高。如果仅仅做了实验,我可以告诉
发表于 2020-07-25
AVR单片机控制发光二极管
点亮ARV单片机开发板上的一个LED灯原理图: 分析:上面的截图就是单片机和LED灯的连接原理图,其中J6是一个排阻,起到限流的作用,防止LED电流过大而烧坏。排阻的内部就是一组并联的电阻:bubuko.com,布布扣提示:算一下这个排阻的电阻的大小,二极管的工作电流是3mA,工作电压时1.7V,VCC的电压时5V。所以电阻上的电流是3mA,电压是3.3V,所以电阻的阻值是1.1KΩ。因为所有的二极管都是通过一个限流电阻共阳极的,所以只需要在Q端给一个低电平就能点亮这个发光二极管。Q端的电平通过一个573锁存器受控于D端的电平高低,也就是单片机的PB端口。这样我们就能通过写程序控制PB端口的高低电平来实现二极管的亮灭
发表于 2020-07-25
AVR<font color='red'>单片机</font>控制发光二极管
基于IAR环境下STM32F103单片机读取BME280程序
自己编写的基于IAR环境下STM32F103单片机读取BME280程序,没有太多的寄存器操作,简单易懂,可以直接调用,上电后只要对IO口初始化,调用函数Bme_ReadDigValue()读取校准寄存器参数并保存,再调用函数Bme_Init()初始化之后就可以用函数Bme_ReadStatus()读取传感器状态判断是否读取数据了,也可不判断传感器状态直接读取数据,读取数据直接调用函数ReadBme280()。单片机源程序:void ReadBme280(){        u32 value_ad;        double var1; 
发表于 2020-07-25
MSP430单片机定时器TA中断 程序
程序1#include  <msp430x41x.h>void main(void){  WDTCTL = WDTPW + WDTHOLD;                       // 停止看门狗  FLL_CTL0 |= XCAP18PF;                         // 配置晶振负载电容  P1DIR |
发表于 2020-07-25
第三章 硬件基础知识学习
通过上一课的学习,我们貌似成功的点亮了一个LED小灯,但是还有一些知识大家还没有彻底明白。单片机是根据硬件电路图的设计来写代码的,所以我们不仅仅要学习编程知识,还有硬件知识,也要进一步的学习,这节课我们就要来穿插介绍电路硬件知识。3.1 电磁干扰EMI第一个知识点,去耦电容的应用,那首先要介绍一下去耦电容的应用背景,这个背景就是电磁干扰,也就是传说中的EMI。1、冬天的时候,尤其是空气比较干燥的内陆城市,很多朋友都有这样的经历,手触碰到电脑外壳、铁柜子等物品的时候会被电击,实际上这就是“静电放电”现象,也称之为ESD。2、不知道有没有同学有这样的经历,早期我们使用电钻这种电机设备,并且同时在听收音机或者看电视
发表于 2020-07-25
第三章 硬件基础知识学习
第五章 定时器和数码管
通过上节课的实验,大家会发现,我们逐渐进入比较实质性的学习了,需要记住的内容也更多了,个别地方可能会感觉吃力。但是大家不要担心,要有信心。这个跟小孩学走路一样,刚开始走路不太稳,没关系,多走几步多练练。看视频的时候要注意专心,一遍看不懂,思考一下,再回头看第二遍和第三遍,没准一下就明白了。如果三遍还看不明白,那就把不懂的问题放一放,继续往下学两课再回头看一次,也可以到QQ群里或单片机论坛http://www.51hei.com/bbs/ 里多咨询一下其他的同学,讨论一下,可能就会茅塞顿开。1.1 基本数字逻辑门电路不管是数字电路,还是C语言,我们都会经常遇到逻辑运算和逻辑电路,在这里我介绍一下,大家先简单了解
发表于 2020-07-25
第五章 定时器和数码管
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved