这是一个利用89C52RC单片机蜂鸣器演奏生日快乐歌。请高手帮我解释一下:整体思想,再在每一步添加注释。

作者&投稿:利饶 (若有异议请与网页底部的电邮联系)
请教高手,下面是51单片机蜂鸣器演奏“生日快乐”的汇编程序:~

程序中,注释已经够多了。
如果还是弄不了,不如换一个思路。

看看下面的,也许好理解一些:

http://hi.baidu.com/do_sermon/item/8cff22baf5142245bb0e1247
http://hi.baidu.com/do_sermon/item/7665ea126f32075df0090e47

把歌做成数组,定时器调用输出,按键查询调用对于数组就好

#include<reg51.h>
sbit speaker=P1^6;
unsigned char timer0h,timer0l,time;
//生日歌,这三个字节一组,分别定义:旋律(1234567)、高低音(低音、中音、高音)、节奏(长度)
code unsigned char sszymmh[]={5,1,1, 5,1,1, 6,1,2, 5,1,2, 1,2,2, 7,1,4,
5,1,1, 5,1,1, 6,1,2, 5,1,2, 2,2,2, 1,2,4,
5,1,1, 5,1,1, 5,2,2, 3,2,2, 1,2,2, 7,1,2, 6,1,2,
4,2,1, 4,2,1, 3,2,2, 1,2,2, 2,2,2, 1,2,4};
// 音阶频率表 高八位,也就是发音对应频率的高八位
code unsigned char FREQH[]={0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8, 0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i
0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,} ;
// 音阶频率表 低八位,也就是发音对应频率的低八位
code unsigned char FREQL[]={0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i
0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16, };
void delay(unsigned char t) //延时程序
{
unsigned char t1;
unsigned long t2;
for(t1=0;t1<t;t1++)
{
for(t2=0;t2<8000;t2++)
{ ; } }
TR0=0;
}
void t0int() interrupt 1 //定时器0中断服务程序,控制声音打频率
{ TR0=0;
speaker=!speaker;
TH0=timer0h;
TL0=timer0l;
TR0=1;
}
void song() //启动演奏当前频率
{ TH0=timer0h; //当前频率的高八位
TL0=timer0l; //当前频率的低八位
TR0=1; //启动定时器0
delay(time); //延时当前频率的演奏时间
}
void main(void)
{
unsigned char k,i;
TMOD=1; //置CT0定时工作方式1 EA=1; ET0=1;//IE=0x82 //CPU开中断,CT0开中断
while(1)
{
i=0;
while(i<75)
{ //音乐数组长度 ,唱完从头再来
k=sszymmh[i]+7*sszymmh[i+1]-1; //取当前节奏的频率地址
timer0h=FREQH[k]; //取当前频率高八位
timer0l=FREQL[k]; //取当前频率低八位
time=sszymmh[i+2]; //取当前频率的时长
i=i+3; //三个字节一组
song(); //演奏当前频率,共75/3,25个曲调。
}
}
}
//程序的设计思路就是将一首乐曲分成三个变量来控制,分别是曲调、所在音区、时长。而控制曲调的因素也就是频率又分成高八位和第八位两个表,每演奏一个曲调,就根据该曲调的三个变量来取值。

利用定时器输出PWM调节占空比 书上和理论知识也是这么说的吧 通俗点说:高音调高电平所占时间长 依次类想 然后对生日歌进行编码 你这个程序是经过一种算法 但是原理 不变

sszymmh,世上只有妈妈好。

参考:

http://hi.baidu.com/do_sermon/item/d6f155da37a70fe93dc2cbc1
http://hi.baidu.com/do_sermon/item/8cff22baf5142245bb0e1247


浙cz89c5的电话号码
你查询的是 浙C·Z89C5 类型:民用车辆号牌 省份:浙江 城市:温州市 需到车管所查询

有51单片机和MAX485连接的电路图吗?
http:\/\/b.hiphotos.baidu.com\/zhidao\/pic\/item\/08f790529822720e154bf1807bcb0a46f31fabc6.jpg

单片机型号标识问题
24表示最高速度24MHz,P表示双列直插封装PDIP,C表示Commercial商业级产品(工作温度0~70度),如果是24PI,其中的I表示Industrial工业级产品(工作温度-40~85度)第三行的0441表示04年41周出厂 常见的AT89C5x系列基本都是12V编程的,除非你在第二行当中看到24PC-5,否则一律是12V编程的.AT89S5x系列...

Atmel单片机
Atmel一共有三个系列的单片机AT89 AT90 AT91.AT89是以51内核为标准的单片机。它是改进型的51单片机。比如说标准的8051单片机没有20pin封装的芯片。但是AT89C2051 AT89C4051都是20pin封装的单片机。它主要是把原51单片机的P0口和P2口省略了,然后再改进了一些功能。可以认为它们是精简型51单片机,比较适合...

怎么我的KEIL软件里atmei目录下没有AT89C5X系列的单片机呢?是我安装...
是啊,你安装错了,Keil有两个版本,一是Keil C51,用来编写51程序的,二是Keil Realview MDK 是用来编写ARM的,两个的界面是一样的,很明显,你这个装的是 RVMDK

...0X88F2B9F8,0X89C55008,0XB84F3CBC,0X000000001) 蓝屏后出现的代码...
朋友,电脑蓝屏的原因是很复杂的!这是软件之间有冲突!(参考第3条,软件不兼容)(答案原创,引用请说明原作者:力王历史)1。如果这是偶然,一般重启电脑,症状便可消失!2。杀毒不彻底,(使用杀毒软件,全盘扫描和自定义扫描)!如果杀到木马或病毒后,应立即重启, 重启电脑后,来到“隔离|恢复”,...

怎么使用top2007通用编程器恢复sst89e554rc
也适用于SOIC24\/SOIC20\/SOIC18 等参数类似的芯片. 一些封装类型可能有几种适配器选择. 例如: PLCC44\/D44, PLCC44\/D40-1, PLCC44\/D40-2 都是PLCC44适配器. 如果您的编程器是"A" 或 "AP" 或 "Versatile"类型, 应该选择PLCC44\/D44. PLCC40\/D40-1 适用于经济型编程器上的89C5X等芯片,...

单片机STC12C5A60S2和STC89C5X 程序一样 为何运行效果不一样呢? 附...
可能是1T模式,传统8051为12T,时间是把握不好吧,这只是猜想

keil软件编译以后有7个warning,实在不知道哪里出现问题,求各位大神帮 ...
看来,你是个新手啊,刚开始练习写程序,基础知识不是很清楚。include<stc89c5xrc.h>,这STC单片机的头文件需要用STC-ISP导出。其实,你这程序也不必用STC的头文件,就用通用的reg51.h就行。改成#include<seg51.h>是完全可以的。下面是重点错误:关面的延时子程序名是:Delay10ms(void),在主...

求仙剑1攻略
回到神庙后找奴儿,知凤凰蛋己孵出小凤凰,得到凤凰壳;回去找老婆婆,正好赶上灵儿的产期,生了一个白白胖胖的小女儿,为了忆念月如,遂把女儿取名为〃李忆如〃;而老婆婆要逍遥帮她到试炼洞去找36只傀儡虫来做药(如己有36只傀儡虫就可以不必去试炼了)。〔24〕试炼洞 到大理城外,往右走过桥,...

宿州市17099065016: 这是一个利用89C52RC单片机蜂鸣器演奏生日快乐歌.请高手帮我解释一下:整体思想,再在每一步添加注释. -
顾莺奇力: #include<reg51.h> sbit speaker=P1^6; unsigned char timer0h,timer0l,time; //生日歌,这三个字节一组,分别定义:旋律(1234567)、高低音(低音、中音、高音)、节奏(长度) code unsigned char sszymmh[]={5,1,1, 5,1,1, 6,1,2, 5,1,2, 1,2,2...

宿州市17099065016: 我要用89C52RC单片机最小系统做一个光敏电阻阻值改变单片机最小系统上的蜂鸣器就会响的电路 -
顾莺奇力: 这款单片机没有AD功能,所以要检测光敏电阻阻值的变化,需要外加一个AD转换芯片,之后定时扫描这个AD转换结果就可以实现你的功能了.

宿州市17099065016: 有谁会写单片机程序的啊?我在做一个STC89C52RC单片机与DS18B20温度传感器及蜂鸣器的温度控制报警系统, -
顾莺奇力: ^参考一下下面的报警器程序吧,这是《PROTEUS仿真100例》中的. //名称:按键发音 #include<reg51.h> #define uchar unsigned char #define uint unsigned intsbit SPK=P1^0; sbit K1=P1^7;void Alarm(uchar t) {uchar i,j;for(i=0;i<200;i++){...

宿州市17099065016: 基于STC89C52RC单片机和DS18B20完成简易现场测温系统制作 -
顾莺奇力: #include #define uint unsigned int#define uchar unsigned char#define delayNOP() {_nop_();_nop_();_nop_();_nop_();}/********************** DS18B20 指令*********************/#define ds18B20_READ_ROM 0x33 // 读 ROM 指令#define ds18B20_...

宿州市17099065016: 用STC89C52RC单片机进行数据采集,芯片为ADC0804 -
顾莺奇力: 你这个板上的单片机是STC12C5A60S2吗?看不清楚.STC12C5A60S2的P1口的8个引脚是可以作为8路的模拟量输入端,可以采集8路的数据,但不是同时的,因为内部就是一个ADC转换器,这8路需要切换的,在不同的时间内采集不同的数据.如果这个要求你能接受就可以.其实,ADC0809也是可以采集8路数据的,它也是一样需要切换的.从这个意义上说,用STC12C5A60S2是可以接受的.只要你这个板上的P1的其中4个引脚能接出来,即能接到外部的模拟信号上就可实现你的要求了.

宿州市17099065016: stc89c52rc单片机.io口接无源蜂鸣器负极,无源蜂鸣器正极接五伏电源,程序写的是io口产生 -
顾莺奇力: 单片机IO口驱动能力不是很大,直接驱动蜂鸣器有点难度,最好加个三极管驱动.

宿州市17099065016: 松乐SRD - 05VDC - SL - C继电器,用89C52RC单片机驱动,想实现高电位开启,低电位关闭. -
顾莺奇力: 1.确保三极管是好的情况下并且放大倍数100以上2. 加一个1-10K的上拉电阻3.或选STC5A60系列单片机 将P1.0配置为推挽输出即可 由P1M0 P1M1两个寄存器决定 相应位分别 置0 和14. 或将其改为低电平驱动,普通51单片机高电平输出能力只有0.2ma左右 而低电平驱动电流大得多,见下图 并且上电是高电平,不影响其工作

宿州市17099065016: 89C52RC单片机的蜂鸣器是不是P2^3?为什么下面代码下载进去没反应? -
顾莺奇力: 第一、要看你的电路具体蜂鸣器是连接到单片机的哪个管脚 第二、要看你的蜂鸣器是低电平驱动还是高电平驱动 第三、程序主循环里要加while(1)死循环

宿州市17099065016: 利用单片机的定时功能产生频率为0.5HZ的方波信号,用口线输出. -
顾莺奇力: ORG 0000H ;说明:此程序使P1.1产生一个频率为0.5HZ的PWM波SJMP MAINORG 001BHLJMP INTR ;转定时器T1的中断服务子程序ORG 0030H MAIN: MOV TMOD,#10H ;T1模式1计数MOV TH1,#0B1HMOV TL1,#0E0H ;定时20ms...

宿州市17099065016: 把单片机试验板上的STC89C52RC换成AT89S52后,蜂鸣器一直响,数码管也不停闪烁,该怎么解决 -
顾莺奇力: STC89C52RC是12T或6T,AT89S52是12T的,如果stc89c52rc选了6T,程序上的延时函数要改下,才可以,直接替换时不行的.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网