51单片机做的lcd1602音乐播放器原理图:
单片机源程序:
- #include<reg51.h>
- #define uint unsigned int
- #define uchar unsigned char
- /*------------------------------------------------
- 硬件端口定义
- ------------------------------------------------*/
- sbit SPK=P2^0; //定义音乐输出端口
- sbit key1=P3^2; //定义按键 用于 暂停
- sbit key2=P3^3; //定义按键 用于 切换
- sbit rs=P2^1;
- sbit rw=P2^2;
- sbit ep=P2^3;
- void delay1(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void write_com(uchar com)
- {
- rs=0;
- rw=0;
- ep=0;
- P0=com;
- delay1(2);
- ep=1;
- delay1(2);
- ep=0;
- delay1(2);
- }
- void write_dat(uchar dat)
- {
- rs=1;
- rw=0;
- ep=0;
- P0=dat;
- delay1(2);
- ep=1;
- delay1(2);
- ep=0;
- delay1(2);
- }
- void write_zfc(uchar *p)
- {
- while(*p!=0)
- write_dat(*p++);
- }
- void init_1602()
- {
- write_com(0x38);
- write_com(0x01);
- write_com(0x06);
- write_com(0x0c);
- }
- unsigned char W=0,T; //用于选择音乐
- unsigned char Timer0_H,Timer0_L,Time;
- void delay5ms(void) //误差 0us
- {
- unsigned char a,b;
- for(b=185;b>0;b--)
- for(a=12;a>0;a--);
- }
- void delay500ms(void) //误差 0us
- {
- unsigned char a,b,c;
- for(c=205;c>0;c--)
- for(b=116;b>0;b--)
- for(a=9;a>0;a--);
- }
- //世上只有妈妈好 数据表 音谱,高中低音,音长
- code unsigned char MUSIC[102]={ 6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,
- 6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,
- 6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,
- 5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,
- 2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0
- };
- //送别 数据表 音谱,高中低音,音长
- code unsigned char MUSIC1[174]={ 5,2,2, 3,2,1, 5,2,1, 1,3,4,
- 6,2,2, 1,3,2, 5,2,4,
- 5,2,2, 1,2,1, 2,2,1, 3,2,2, 2,2,1, 1,2,1,
- 2,2,8,
- 5,2,2, 3,2,1, 5,2,1, 1,3,3, 7,2,1,
- 6,2,2, 1,3,2, 5,2,4,
- 5,2,2, 2,2,1, 3,2,1, 4,2,3, 7,1,1,
- 1,2,8,
- 6,2,2, 1,3,2, 1,3,4,
- 7,2,2, 6,2,1, 7,2,1, 1,3,4,
- 6,2,1, 7,2,1, 1,3,1, 6,2,1, 6,2,1, 5,2,1, 3,2,1, 1,2,1,
- 2,2,8,
- 5,2,2, 3,2,1, 5,2,1, 1,3,3, 7,2,1,
- 6,2,2, 1,3,2, 5,2,4,
- 5,2,2, 2,2,1, 3,2,1, 4,2,3, 7,1,1,
- 1,2,8
- };
- //新年好 数据表 音谱,高中低音,音长
- code unsigned char MUSIC2[90]={ 1,2,1, 1,2,1, 1,2,2, 5,1,2,
- 3,2,1, 3,2,1, 3,2,2, 1,2,2,
- 1,2,1, 3,2,1, 5,2,2, 5,2,2,
- 4,2,1, 3,2,1, 2,2,4,
- 2,2,1, 3,2,1, 4,2,2, 4,2,2,
- 3,2,1, 2,2,1, 3,2,2, 1,2,2,
- 1,2,1, 3,2,1, 2,2,2, 5,1,2,
- 7,1,1, 2,2,1, 1,2,4
- };
- //童年 数据表 音谱,高中低音,音长
- code unsigned char MUSIC3[423]={ 5,1,1, 5,1,1, 3,1,1, 5,1,2, 3,1,1, 5,1,2,
- 6,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 1,2,2,
- 2,2,1, 2,2,1, 3,2,1, 2,2,2, 5,1,1, 6,1,1, 5,1,1,
- 1,2,1, 1,2,1, 5,1,1, 1,2,1, 1,2,1, 1,2,2, 1,2,1,
- 1,2,1, 5,1,2, 1,2,1, 6,1,1, 5,1,1, 3,1,1, 2,1,1,
- 1,1,2, 3,1,1, 5,1,1, 5,1,2, 5,1,1, 3,1,1,
- 6,1,1, 6,1,1, 1,2,1, 6,1,1, 6,1,1, 6,1,1, 6,1,1, 5,1,1,
- 1,2,2, 1,2,1, 1,2,1, 1,2,1, 6,1,1, 1,2,1, 6,1,1,
- 5,1,2, 0,2,1, 3,1,1, 6,1,1, 1,2,1, 6,1,1, 5,1,1,
- 3,1,1, 2,1,1, 3,1,1, 5,1,1, 5,1,2, 5,1,1, 3,1,1,
- 6,1,1, 6,1,1, 1,2,1, 6,1,1, 6,1,1, 6,1,1, 6,1,1, 5,1,1,
- 1,2,2, 1,2,1, 1,2,1, 1,2,1, 6,1,1, 6,1,1, 1,2,1,
- 2,2,2, 0,2,1, 5,1,1, 2,2,1, 5,2,1, 2,2,2,
- 5,2,1, 5,2,2, 5,2,1, 5,2,1, 5,2,1, 3,2,1, 2,2,1,
- 1,2,1, 1,2,2, 6,1,1, 6,1,1, 1,2,1, 6,1,1, 1,2,1,
- 2,2,1, 2,2,1, 2,2,1, 2,2,1, 2,2,1, 1,2,1, 3,2,1, 2,2,1,
- 2,2,8,
- 3,2,1, 3,2,2, 3,2,1, 3,2,2, 2,2,2,
- 1,2,1, 1,2,2, 1,2,1, 2,2,1, 1,2,1, 6,1,1, 5,1,1,
- 5,1,1, 5,1,2, 5,1,1, 6,1,1, 5,1,1, 2,2,1, 3,2,1,
- 1,2,8,
- 1,2,1, 5,1,2, 1,2,1, 6,1,1, 5,1,1, 3,1,1, 2,1,1,
- 1,2,6, 0,2,2
- };
- // 音阶频率表 高八位
- 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,
- };
- /*------------------------------------------------
- uS延时函数,含有输入参数 unsigned char t,无返回值
- unsigned char 是定义无符号字符变量,其值的范围是
- 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
- 长度如下 T=tx2+5 uS
- ------------------------------------------------*/
- void DelayUs2x(unsigned char t)
- {
- while(--t);
- }
- /*------------------------------------------------
- mS延时函数,含有输入参数 unsigned char t,无返回值
- unsigned char 是定义无符号字符变量,其值的范围是
- 0~255 这里使用晶振12M,精确延时请使用汇编
- ------------------------------------------------*/
- void DelayMs(unsigned char t)
- {
- while(t--)
- {
- //大致延时1mS
- DelayUs2x(245);
- DelayUs2x(245);
- }
- }
- /*------------------------------------------------
- 节拍延时函数
- 各调1/4节拍时间:
- 调4/4 125ms
- 调2/4 250ms
- 调3/4 187ms
- ------------------------------------------------*/
- void delay(uchar t)
- {
- uchar i;
- for(i=0;i<t;i++)
- DelayMs(250);
- TR0=0;
- }
- /*------------------------------------------------
- 定时器0中断
- ------------------------------------------------*/
- void TIM0_ISR() interrupt 1
- {
- TR0=0;
- SPK=!SPK;
- TH0=Timer0_H;
- TL0=Timer0_L;
- TR0=1;
- }
- /*------------------------------------------------
- 歌曲处理函数
- ------------------------------------------------*/
- void Song()
- {
- TH0=Timer0_H;//赋值定时器时间,决定频率
- TL0=Timer0_L;
- TR0=1; //打开定时器
- delay(Time); //延时所需要的节拍
- }
- /*------------------------------------------------
- 主函数
- ------------------------------------------------*/
- void led(unsigned char a);
- void main(void)
- {
- unsigned int i;
- unsigned char k;
- TMOD|=0x01; //置定时器0工作方式1
- EA=1; //打开全局中断
- ET0=1; //打开 定时器0 中断
- EX0=1; //打开 外部中断0 中断
- IT0=1; //设置为下降沿中断
- EX1=1; //打开 外部中断1 中断
- IT1=1; //设置为下降沿中断
- PX1=1; //设置 外部中断1 为高优先级
- init_1602();
-
- while(1)
- {
- //i=0;
-
- if(W==0)
- {
- T=W;
- write_com(0x81);
- write_zfc("shishangziyou");
- write_com(0xc4);
- write_zfc("mamahao");
- for(i=0;i<100;i=i+3)
- { //音乐数组长度 ,唱完从头再来
- led(MUSIC[i]);
-
- k=MUSIC[i]+7*MUSIC[i+1]-1;//去音符振荡频率所需数据
- Timer0_H=FREQH[k];
- Timer0_L=FREQL[k];
- Time=MUSIC[i+2]; //节拍时长
- // i=i+3;
- Song();
- if(T!=W)
- break;
- }
- }
-
- if(W==1)
- {
- T=W;
- write_com(0x01);
- write_com(0x80);
- write_zfc(" songbie ");
- for(i=0;i<174;i=i+3)
- { //音乐数组长度 ,唱完从头再来
- led(MUSIC1[i]);
-
- k=MUSIC1[i]+7*MUSIC1[i+1]-1;//去音符振荡频率所需数据
- Timer0_H=FREQH[k];
- Timer0_L=FREQL[k];
- Time=MUSIC1[i+2]; //节拍时长
- // i=i+3;
- Song();
- if(T!=W)
- break;
- }
- }
- if(W==2)
- {
- T=W;
- write_com(0x80);
- write_zfc(" xinnianhao ");
- for(i=0;i<90;i=i+3)
- { //音乐数组长度 ,唱完从头再来
- led(MUSIC2[i]);
-
- k=MUSIC2[i]+7*MUSIC2[i+1]-1;//去音符振荡频率所需数据
- Timer0_H=FREQH[k];
- Timer0_L=FREQL[k];
- Time=MUSIC2[i+2]; //节拍时长
- // i=i+3;
- Song();
- if(T!=W)
- break;
- }
- }
-
- if(W==3)
- {
- T=W;
- write_com(0x80);
- write_zfc(" tongnian ");
- for(i=0;i<423;i=i+3)
- { //音乐数组长度 ,唱完从头再来
- led(MUSIC3[i]);
-
- k=MUSIC3[i]+7*MUSIC3[i+1]-1;//去音符振荡频率所需数据
- Timer0_H=FREQH[k];
- Timer0_L=FREQL[k];
- Time=MUSIC3[i+2]; //节拍时长
- // i=i+3;
- Song();
- if(T!=W)
- break;
- }
- }
- }
- }
- // 频谱函数
- void led(unsigned char a)
- {
- switch(a)
- {
- case 0:P1=0xff;break;
- case 1:P1=0x7f;break;
- case 2:P1=0x7e;break;
- case 3:P1=0x7c;break;
- case 4:P1=0x78;break;
- case 5:P1=0x70;break;
- case 6:P1=0x60;break;
- case 7:P1=0x40;break;
- case 8:P1=0x00;break;
- }
- }
- // 外部中断0 中断服务程序 用于暂停
- void zhongduan0() interrupt 0
- {
- delay5ms(); //按键去抖
- if(!key1)
- {
- while(!key1); //松手检测
- while(key1&&T==W); //检测按键是否按下
- delay5ms(); //按键去抖
- while(key1&&T==W); //检测按键是否按下
- while(!key1&&T==W); //松手检测
- }
- }
- // 外部中断1 中断服务程序
- void zhongduan1() interrupt 2
- {
- delay5ms(); //按键去抖
- if(!key2)
- {
- if(W==3)
- W=0;
- else
- W++;
- while(!key2); //松手检测
- delay500ms();
-
- }
- }
复制代码
所有资料下载:
1602音乐播放器.rar
(62.63 KB, 下载次数: 59)
|