前两天上单片机课,讲了蜂鸣器有关内容,顺便写了个蜂鸣器播放音乐的小程序;
程序在code文件夹下,使用keil4编译,并附带仿真,仿真环境为Proteus7.8;
想强调的一个问题是音调之间加延时真的很重要,不然特别难听
ppt中讲解了蜂鸣器的有关知识,最后有关于执行流程的讲解
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
ppt教程预览:
单片机源程序如下:
- /***************
- author:zc
- description: 蜂鸣器播放音乐 天空之城
- 晶振11.0592Mhz
- 实现方法:
- while(1)循环中生成音调方波;
- 定时器1记录每个音调的时长并切换音调
- ****************/
- #include "reg51.h"
- #include "intrins.h"
- unsigned int tones[]= //C调音调
- {
- 3816,3401,3030,2865,2551,2272,2024, //低音
- 1912,1703,1517,1432,1275,1136,1012, //中音
- 965, 851, 758, 715, 605, 538, 466 //高音
- };
- unsigned char code sky[]={ //谱子
- //格式: 音调, 音度, 拍数
- //例: 4,1,1 //音调fa,中音,时长半拍
- //0代表空音
- 0,0,2,
- 0,0,2,
- 0,0,2,
- 6,1,1,
- 7,1,1,
- 1,2,3,
- 7,1,1,
- 1,2,2,
- 3,2,2,
- 7,1,4,
- 0,2,2,
- 3,1,1,
- 3,1,1,
- 6,1,3,
- 5,1,1,
- 6,1,2,
- 1,2,2,
- 5,1,4,
- 0,1,2,
- 3,1,2,
- 4,1,3,
- 3,1,1,
- 4,1,2,
- 1,2,2,
- 3,1,3,
- 0,0,1,
- 1,2,1,
- 1,2,1,
- 1,2,1,
- 7,1,3,
- 4,1,1,
- 4,1,2,
- 7,1,2,
- 7,1,4,
- 0,0,2,
- 6,1,1,
- 7,1,1,
- 1,2,3,
- 7,1,1,
- 1,2,2,
- 3,2,2,
- 7,1,4,
- 0,0,2,
- 3,1,1,
- 3,1,1,
- 6,1,3,
- 5,1,1,
- 6,1,2,
- 1,2,2,
- 5,1,4,
- 0,0,2,
- 2,1,1,
- 3,1,1,
- 4,1,2,
- 1,2,1,
- 7,1,2,
- 1,2,3,
- 2,2,1,
- 2,2,1,
- 3,2,1,
- 1,2,3,
- 0,0,2,
- 1,2,1,
- 7,1,1,
- 6,1,1,
- 6,1,1,
- 7,1,2,
- 5,1,2,
- 6,1,4,
- 0,0,2,
- 1,2,1,
- 2,2,1,
- 3,2,3,
- 2,2,1,
- 3,2,2,
- 5,2,2,
- 2,2,4,
- 0,0,2,
- 5,1,1,
- 5,1,1,
- 1,2,3,
- 7,1,1,
- 1,2,2,
- 3,2,2,
- 3,2,4,
- 0,0,2,
- 6,1,1,
- 7,1,1,
- 1,2,2,
- 7,1,2,
- 2,2,1,
- 2,2,1,
- 1,2,3,
- 5,1,1,
- 5,1,3,
- 0,0,1,
- 4,2,2,
- 3,2,2,
- 2,2,2,
- 1,2,2,
- 3,2,4,
- 0,0,2,
- 3,2,2,
- 6,2,4,
- 5,2,2,
- 5,2,2,
- 3,2,1,
- 2,2,1,
- 1,2,4,
- 0,2,1,
- 1,2,1,
- 2,2,2,
- 1,2,1,
- 2,2,1,
- 2,2,2,
- 5,2,2,
- 3,2,4,
- 0,2,2,
- 3,2,2,
- 6,2,4,
- 5,2,4,
- 3,2,1,
- 2,2,1,
- 1,2,4,
- 0,0,1,
- 1,2,1,
- 2,2,2,
- 1,2,1,
- 2,2,1,
- 2,2,2,
- 7,1,2,
- 6,1,2,
- };
- sbit Buzzer=P3^0; //定义buzzer引脚
- void delay_ms( unsigned int t) ; //毫秒延时12MHz下
- void delay_us( unsigned int t) ; //微妙延时12MHz下
- void play_tone(unsigned int tone); //播放音调函数,即方波发生器
- void time_init( void ); //初始化定时器
- unsigned char s=0, t_tone=0; //s用作定时器计时, t_tone保存音调时长
- unsigned int tone=0; //tone保存音调,
- char *tone_p=sky; //指针指向要播放的曲目
- void main( void )
- {
- time_init(); //初始化定时器
- while(1)
- if(tone!=0)play_tone(tone); //一直在播放音调,播放的音调由定时器切换,
- //音调时常由定时器决定
- } //如果tone==0 不进入播放
- void time_init( void )
- {
- TMOD|=0x10; //使用定时器1
- TH1=(65536-65000)/256; //装初值
- TL1=(65536-65000)%256;
- EA = 1; //开中断,打开定时器开关
- ET1 = 1;
- TR1 = 1;
- }
- void timer1( void ) interrupt 3 //定时器1 中断
- {
- TH1=(65536-50000)/256; //装初值
- TL1=(65536-50000)%256;
- s++;
- if(s>=4*t_tone) //一个音节播放的时间,这里可以通过调t_tone前的系数可以改变时长
- {
- s=0; //讲计时器清零
- if((*tone_p)!=0) //如果音不是0
- tone = tones[*tone_p+7*(*(tone_p+1))-1]; //赋值音调
- else
- tone = 0; //关了蜂鸣器
- t_tone = *(tone_p+2); //取时间啊
- tone_p+=3; //移动指针
- delay_ms(30); //延时一下,不延时特别难听
- }
- }
- void play_tone(unsigned int tone) //播音调函数,就是方波发生器
- {
- Buzzer=!Buzzer;
- delay_us(tone);
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
test2.rar
(2.16 MB, 下载次数: 542)
|