6342|24

192

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

自己想的第一个程序,总是在板子上实现不了,求大神 [复制链接]

思路想法

按下 独立按键s9(开机键) 后8*8点阵显示DGXT流动 1602 液晶显示welcome
在此以后
 按下s1(音乐A键)后8*8点阵显示DGXT流动 1602 液晶显示ZHIYOUMAMAHAO
和液晶上 时间计数 从00:00:00开始,同时蜂鸣器演奏音乐A

 按下s5(音乐B键)后8*8点阵显示DGXT流动 1602 液晶显示SONGBIE
和液晶上 时间计数 从00:00:00开始,同时蜂鸣器演奏音乐B

在音乐播放的时候 可以按s1或者s5换歌  也可以按下s9复位开机显示

(我自己想的还有很多不完善的地方,比如说关机,音乐停止时延时一会液晶时间清零音乐从新开始,我都没想出来咋写)

遇到问题

我把每个都做成独立的子函数了 分别调用 都可以实现 (在自己的开发板上)
液晶和 8*8点阵可以同时实现

但是 音乐和液晶不能同时实现

我觉得是中断冲突??还是优先级问题?

还有就是最后的按键 不会弄 实现不了

主函数的写法想到了用中断,只能实现开机(按下s9)后再按s1(音乐A键)8*8点阵循环,液晶显示歌名,但是液晶时间不动...

还有很多困难从写子函数到连线到最后的调试弄了好久了...

(流程图现在还不大会写,只能这样了)

程序如下:

.....

程序太长.....

点歌系统编程.rar

2.75 KB, 下载次数: 5

点歌系统思路.rar

527 Bytes, 下载次数: 5

此帖出自51单片机论坛

最新回复

对于那种才几百行的程序我是懒得用模块化了  详情 回复 发表于 2011-11-15 10:29
点赞 关注
 

回复
举报

192

帖子

0

TA的资源

纯净的硅(初级)

沙发
 

#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit s1=P2^3;//s1放音乐A
sbit s5=P2^2;//s5放音乐B
sbit s9=P2^1;//s9开机键
sbit p2_0=P2^0;//行列键盘变成独立键盘
sbit lcden=P2^7;//液晶
sbit lcdrs=P2^6;//液晶
sbit lcdrw=P2^5;//液晶
sbit speaker=P2^4;//蜂鸣器

unsigned char timer0h, timer0l, time;//蜂鸣器
uchar count;//液晶显示
char miao,shi,fen;//液晶显示
uchar aa;//按键s1中断
uchar i,j;

uchar code table[]={
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//双色点阵位选
uchar code table1[]={
0x0,0x3c,0x42,0x81,0x81,0x81,0xff,0x0,
0x0,0x0f,0x84,0x82,0x82,0x82,0x7c,0x0,
0x0,0x42,0x24,0x18,0x18,0x24,0x42,0x0,
0x40,0x40,0x40,0x7e,0x40,0x40,0x40,0x0,
0x0,0x3c,0x42,0x81,0x81,0x81,0xff,0x0,
0x0,0x0f,0x84,0x82,0x82,0x82,0x7c,0x0,
0x0,0x42,0x24,0x18,0x18,0x24,0x42,0x0,
0x40,0x40,0x40,0x7e,0x40,0x40,0x40,0x0};//点阵显示DGXT
uchar code table3[]="    WELCOME";//液晶初始显示
uchar code table4[]="  ZHIYOUMAMAHAO";//液晶显示A歌名世上只有妈妈好
uchar code table5[]="    00:00:00";//液晶显示音乐时间
uchar code table6[]="     SONGBIE";//液晶显示B歌名送别

// 频率-半周期数据表 高八位   
/*
code unsigned char FREQH[] = {
    0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8,    //低音1234567
    0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC,//1,2,3,4,5,6,7,i
    0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE,            //高音 234567
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF};   //超高音 1234567
// 频率-半周期数据表 低八位
code unsigned char FREQL[] = {
    0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6,    //低音1234567
    0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B, 0x8F, //1,2,3,4,5,6,7,i
    0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D,             //高音 234567
    0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16};   //超高音 1234567
//世上只有妈妈好数据表 


code unsigned char mamahao[] = {
6, 2, 3,  5, 2, 1,  3, 2, 2,  5, 2, 2,  1, 3, 2,  6, 2, 1,  5, 2, 1,
//一个音符有三个数字。前为第几个音、中为第几个八度、后为时长(以半拍为单位)。
//6, 2, 3 分别代表:6, 中音, 3个半拍;
//5, 2, 1 分别代表:5, 中音, 1个半拍;
//3, 2, 2 分别代表:3, 中音, 2个半拍;
//5, 2, 2 分别代表:5, 中音, 2个半拍;
//1, 3, 2 分别代表:1, 高音, 2个半拍;
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 songbie[] = {
5, 2, 2,          3, 2, 1,          5, 2, 1,          1, 3, 4,
//嗦,中音,2个半拍; 咪,中音,1个半拍; 嗦,中音,1个半拍; 哆,高音,4个半拍
6, 2, 2,          1, 3, 1,          6, 2, 1,          5, 2, 4,
//啦,中音,2个半拍; 哆,高音,1个半拍; 啦,中音,1个半拍; 嗦,中音,4个半拍
5, 2, 2,          3, 2, 1,          5, 2, 1,          1, 3, 4,
//嗦,中音,2个半拍; 咪,中音,1个半拍; 嗦,中音,1个半拍; 哆,高音,4个半拍
6, 2, 2,          1, 3, 1,          6, 2, 1,          5, 2, 4,
//啦,中音,2个半拍; 哆,高音,1个半拍; 啦,中音,1个半拍; 嗦,中音,4个半拍
0, 0, 0};

void t0int() interrupt 1         //T0中断程序,控制发音的音调
{
    TR0 = 0;                     //先关闭T0
    speaker = !speaker;          //输出方波, 发音
    TH0 = timer0h;               //下次的中断时间, 这个时间, 控制音调高低
    TL0 = timer0l;
    TR0 = 1;                     //启动T0
}

void delay1(unsigned char t)     //音乐延时程序,控制发音的时间长度
{
    unsigned char t1;
    unsigned long t2;
    for(t1 = 0; t1 < t; t1++)    //双重循环, 共延时t个半拍
      for(t2 = 0; t2 < 8000; t2++); //延时期间, 可进入T0中断去发音
    TR0 = 0;                        //关闭T0, 停止发音
}

void song()                      //演奏一个音符
{
    TH0 = timer0h;               //控制音调
    TL0 = timer0l;
    TR0 = 1;                     //启动T0, 由T0输出方波去发音
    delay1(time);                 //控制时间长度
}
void display_FMQ_MMH()//演奏世上只有妈妈好
{
    unsigned char k, a;
    TMOD = 1;                    //置T0定时工作方式1
    ET0 = 1;                     //开T0中断
    EA = 1;                      //开CPU中断
    while(1)
 {
      a = 0;
      time = 1;
      while(time)
  {
        k = mamahao[a] + 7 * mamahao[a + 1] - 1;
                      //第i个是音符, 第i+1个是第几个八度
        timer0h = FREQH[k];      //从数据表中读出频率数值
        timer0l = FREQL[k];      //实际上, 是定时的时间长度
        time = mamahao[a + 2];   //读出时间长度数值
        a += 3;
        song();                  //发出一个音符
  } 
  }
}
/*void display_FMQ_SB()//演奏送别
{
    unsigned char k, i;
    TMOD = 1;                    //置T0定时工作方式1
    ET0 = 1;                     //开T0中断
    EA = 1;                      //开CPU中断
    while(1)
 {
      i = 0;
      time = 1;
      while(time)
  {
        k = songbie + 7 * songbie[i + 1] - 1;
                      //第i个是音符, 第i+1个是第几个八度
        timer0h = FREQH[k];      //从数据表中读出频率数值
        timer0l = FREQL[k];      //实际上, 是定时的时间长度
        time = songbie[i + 2];   //读出时间长度数值
        i += 3;
        song();                  //发出一个音符
  } 
  }
}
*/
void delay(uint z)//普通延时
{
 uint x,y;
 for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}

void write_com(uchar com)//液晶写指令
{
 lcdrs=0;//写指令
 P0=com;
 delay(5);
 lcden=1;
 delay(5);
 lcden=0;//以上都是根据指令表写出
}
void write_data(uchar date)//液晶写数据
{
 lcdrs=1;//写数据
 P0=date;
 delay(5);
 lcden=1;
 delay(5);
 lcden=0;//以上都是根据指令表写出
}

 

void write_sfm(uchar add,uchar date)//液晶显示时分秒
{
 uchar shi,ge;
 shi=date/10;
 ge=date%10;//秒的
 write_com(0x80+0x40+add);
 write_data(0x30+shi);
 write_data(0x30+ge);
}
void init1()//音乐A初始化液晶显示
{
 uchar num;
 s1=1;//初始化s1
 lcdrw=0;//写入为0
 lcden=0;
 write_com(0x38);//开显示
 write_com(0x0c);//不显示光标
 write_com(0x06);
 write_com(0x01);//清屏
 write_com(0x80);
 for(num=0;num<15;num++)
  {
   write_data(table4[num]);
   delay(5);
  }
 write_com(0x80+0x40);
 for(num=0;num<12;num++)
  {
   write_data(table5[num]);
   delay(5);
  } 
 TMOD=0x10;//定时器1的方式1
 TH1=(65536-50000)/256;
 TL1=(65536-50000)%256;//初值
 EA=1;
 ET1=1;
 TR1=1;//启动定时器


}

void display_YJ_A()//液晶显示音乐A和时间计数
{
 init1();
// while(1)
// {
  for(i=0;i<32;i++)//点阵显示DGXT
  {   
   for(j=0;j<8;j++)
   {
    P3=table[j];//红
    P1=table1[j+i];//绿
    delay(5);
   }
   delay(5);
  }
// }
}
void tiner0() interrupt 1//液晶显示所用中断1
{
 TH1=(65536-50000)/256;
 TL1=(65536-50000)%256;//初值
 count++;
  if(count==20)//20ms
  {
   count=0;//清零
   miao++;
   if(miao==60)
    {
     miao=0;
     fen++;
     if(fen==60)
      {
       fen=0;
       shi++;
       if(shi==24)
       {
        shi=0;        
       }
       write_sfm(4,shi);
      }
      write_sfm(7,fen);      
    }
    write_sfm(10,miao);
  }
}

void init2()//音乐B初始化液晶显示
{
 uchar num;
 s5=1;//初始化s5
 lcdrw=0;//写入为0
 lcden=0;
 write_com(0x38);//开显示
 write_com(0x0c);//不显示光标
 write_com(0x06);
 write_com(0x01);//清屏
 write_com(0x80);
 for(num=0;num<12;num++)
  {
   write_data(table6[num]);
   delay(5);
  }
 write_com(0x80+0x40);
 for(num=0;num<12;num++)
  {
   write_data(table5[num]);
   delay(5);
  } 
 TMOD=0x10;//定时器0的方式1
 TH1=(65536-50000)/256;
 TL1=(65536-50000)%256;//初值
 EA=1;
 ET1=1;
 TR1=1;//启动定时器
}
void display_YJ_B()//液晶显示音乐B和时间计数
{
 init2();
// while(1)
// {
  for(i=0;i<32;i++)//点阵显示DGXT
  {   
   for(j=0;j<8;j++)
   {
    P3=table[j];//红
    P1=table1[j+i];//绿
    delay(5);
   }
   delay(5);
  }
// }
}
void tiner1() interrupt 1//液晶显示所用中断0
{
 TH1=(65536-50000)/256;
 TL1=(65536-50000)%256;//初值
 count++;
  if(count==20)//20ms
  {
   count=0;//清零
   miao++;
   if(miao==60)
    {
     miao=0;
     fen++;
     if(fen==60)
      {
       fen=0;
       shi++;
       if(shi==24)
       {
        shi=0;        
       }
       write_sfm(4,shi);
      }
      write_sfm(7,fen);      
    }
    write_sfm(10,miao);
  } 
}

void display_YJ_WELCOME()//液晶初始化显示欢迎
{
 uchar num; 
 lcdrw=0;//写入为0
 lcden=0;
 write_com(0x38);//开显示
 write_com(0x0c);//不显示光标
 write_com(0x06);
 write_com(0x01);//清屏
 write_com(0x80);
 for(num=0;num<11;num++)
  {
   write_data(table3[num]);
   delay(5);
  }
 while(1)
 {
  for(i=0;i<32;i++)//点阵显示DGXT
  {   
   for(j=0;j<8;j++)
   {
    P3=table[j];//红
    P1=table1[j+i];//绿
    delay(5);
   }
   delay(5);
  }
 } 

}
/*void init()
{
 s1=1;//初始化s1
 s5=1;//初始化s5
 s9=1;//初始化s9 
}*/
/*void display_DZ()//点阵显示DGXT
{
 uchar i,j;
 init();
 while(1)
 {
  for(i=0;i<32;i++)//点阵显示DGXT
  {   
   for(j=0;j<8;j++)
   {
    P3=table[j];//红
    P1=table1[j+i];//绿
    delay(5);
   }
   delay(5);
  }
 }
}
*/
void keyscan1()//音乐A键
{
  // display_FMQ_MMH();//放音乐A世上只有妈妈好
   display_YJ_A();//液晶显示音乐A和时间计数点阵
}
void keyscan2()//音乐B键
{
//   display_FMQ_SB();//放音乐B送别
   display_YJ_B();//液晶显示音乐B和时间计数点阵
}
void keyscan3()//开机键
{
   display_YJ_WELCOME();//显示欢迎
}
void init()
{
 s1=1;//初始化s1
 s5=1;//初始化s5
 s9=1;//初始化s9 
}
void main()
{
 p2_0=0;//行列键盘变成独立键盘
 init();
 TMOD=0x01;//定时器0的方式1
 TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;//初值
 EA=1;
 ET0=1;
 TR0=1;//启动定时器 
 if(s9==0)
 {
  delay(5);
  if(s9==0)
  {
  keyscan3(); 
  delay(5);
//   if(s5==0)
//   {
//    delay(5);
//    if(s5==0)
//    { 
//     keyscan2();
//     delay(5);
//    }
//   }
  }
 delay(10);//延时10ms去后面抖动
 }
}
void tiner_s5() interrupt 1//按键s1所用中断
{
 TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;//初值
 aa++;
 if(s1==0)
 {
  delay(5);
  if(s1==0)
  {
  keyscan1(); 
  delay(5);
  }
 delay(10);//延时10ms去后面抖动
 }
}

此帖出自51单片机论坛
 
 
 

回复

192

帖子

0

TA的资源

纯净的硅(初级)

板凳
 

先谢谢看贴回帖的朋友了,QQ526844809
如果你有时间可以加我 具体聊聊!
此帖出自51单片机论坛
 
 
 

回复

3404

帖子

6

TA的资源

裸片初长成(初级)

4
 

那些功能实现不了呢?一步一步的来,先把每个功能单独调出来,然后再一个一个组合!

此帖出自51单片机论坛
 
 
 

回复

192

帖子

0

TA的资源

纯净的硅(初级)

5
 

回复 4楼 jishuaihu 的帖子

我现在遇到的问题就是在组合的时候 组合起来就实现不了了..
能实现的功能 单独点阵,3个液晶显示,3个液晶显示加时间,单独的演奏音乐,按s9开机键点阵循环液晶显示,单独按下s1键点阵+液晶+时间,单独s4也可以基本就这些
问题 音乐加不上去 我想单独按s1点阵+液晶+时间 但是音乐A不演奏。
在不加音乐时,我按下s9开机键后 在按下s1只是点阵+液晶显示但是液晶时间不走,不知道为什?
此帖出自51单片机论坛
 
 
 

回复

315

帖子

0

TA的资源

五彩晶圆(初级)

6
 

void tiner1() interrupt 1

void tiner_s5() interrupt 1

2个interrupt 1,好神奇

此帖出自51单片机论坛
 
 
 

回复

192

帖子

0

TA的资源

纯净的硅(初级)

7
 

回复 6楼 孤獨の快樂 的帖子

:rose: 我中断用的不好 ,求详解
此帖出自51单片机论坛
 
 
 

回复

315

帖子

0

TA的资源

五彩晶圆(初级)

8
 

原帖由 51学习者 于 2011-11-13 12:52 发表 :rose: 我中断用的不好 ,求详解

interrupt 0  指明是外部中断0;
interrupt 1  指明是定时器中断0;
interrupt 2  指明是外部中断1;
interrupt 3  指明是定时器中断1;
interrupt 4  指明是串行口中断;

2个interrupt 1,真不知道定时器中断要响应哪个中断函数了

此帖出自51单片机论坛
 
 
 

回复

192

帖子

0

TA的资源

纯净的硅(初级)

9
 

回复 8楼 孤獨の快樂 的帖子

我用了4次interrupt 1 应该是不对吧!!???
但是我想用4次定时器中断咋办??
此帖出自51单片机论坛
 
 
 

回复

7228

帖子

195

TA的资源

五彩晶圆(高级)

10
 

回复 9楼 51学习者 的帖子

看你楼上的 手说的
此帖出自51单片机论坛
 
 
 

回复

535

帖子

0

TA的资源

五彩晶圆(初级)

11
 

回复 9楼 51学习者 的帖子

就好像你只有两块钱,包子一块钱一个(物价上涨,不可能了。。。)
但是你肚子饿了,想要吃四个包子,然后你怎么办啊。。。当然是用其他的替换啊。。。。程序上做优化啊。。。。
此帖出自51单片机论坛
 
 
 

回复

315

帖子

0

TA的资源

五彩晶圆(初级)

12
 

原帖由 51学习者 于 2011-11-13 13:27 发表 我用了4次interrupt 1 应该是不对吧!!???但是我想用4次定时器中断咋办??

void tiner0() interrupt 1

void tiner1() interrupt 1

这两个的函数不是一样吗?分两个干嘛?

 

51只有2个定时器。

如果你想执行不同的中断的函数,只要设置个变量标志,改变该变量来执行不同的函数,当然没法同时。

话说,你这程序需要同时使用几个定时器?

[ 本帖最后由 孤獨の快樂 于 2011-11-13 14:15 编辑 ]
此帖出自51单片机论坛
 
 
 

回复

192

帖子

0

TA的资源

纯净的硅(初级)

13
 

回复 11楼 小小白 的帖子

谢了斑竹
我先想想方法吧 不行的话继续抱大神
此帖出自51单片机论坛
 
 
 

回复

315

帖子

0

TA的资源

五彩晶圆(初级)

14
 

如果不同时使用定时器,可以这样

void tiner0() interrupt 1

{if(flag==0)

 {

 

 }

else if(flag==1)

{

 

}

```

}

此帖出自51单片机论坛
 
 
 

回复

192

帖子

0

TA的资源

纯净的硅(初级)

15
 

回复 14楼 孤獨の快樂 的帖子

if((miao==05)&&(fen==0)&&(shi==0)==1)
{
        while(1);
}

液晶时间计时
我想让他在00:00:05这停下 咋弄 ??
上边的 不对我自己写的
还有谢了朋友是中断的问题目前时间可以动了,我在继续探索
此帖出自51单片机论坛
 
 
 

回复

192

帖子

0

TA的资源

纯净的硅(初级)

16
 

回复 11楼 小小白 的帖子

小白斑竹在不?
我的程序在大家的帮助下改好多了,按键的问题解决了,
是中断的问题。
现在面临的问题就是,音乐子程序不行(当我想点阵液晶时间音乐一起实现时,此时不行),要是只有单独的音乐子程序是可以发音的...
还有一个问题是,时间只要一开始走动就不会复位,如按s1走到15秒,在按下s5就会从15秒开始计时...
帮忙看下 谢了
此帖出自51单片机论坛
 
 
 

回复

192

帖子

0

TA的资源

纯净的硅(初级)

17
 

#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit s1=P2^3;//s1放音乐A
sbit s5=P2^2;//s5放音乐B
sbit s9=P2^1;//s9开机键
sbit p2_0=P2^0;//行列键盘变成独立键盘
sbit lcden=P2^7;//液晶
sbit lcdrs=P2^6;//液晶
sbit lcdrw=P2^5;//液晶
sbit speaker=P2^4;//蜂鸣器

unsigned char timer0h, timer0l, time;//蜂鸣器
uchar count;//液晶显示
char miao,shi,fen;//液晶显示
uchar aa;//按键s1中断
uchar i,j;

uchar code table[]={
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//双色点阵位选
uchar code table1[]={
0x0,0x3c,0x42,0x81,0x81,0x81,0xff,0x0,
0x0,0x0f,0x84,0x82,0x82,0x82,0x7c,0x0,
0x0,0x42,0x24,0x18,0x18,0x24,0x42,0x0,
0x40,0x40,0x40,0x7e,0x40,0x40,0x40,0x0,
0x0,0x3c,0x42,0x81,0x81,0x81,0xff,0x0,
0x0,0x0f,0x84,0x82,0x82,0x82,0x7c,0x0,
0x0,0x42,0x24,0x18,0x18,0x24,0x42,0x0,
0x40,0x40,0x40,0x7e,0x40,0x40,0x40,0x0};//点阵显示DGXT
uchar code table3[]="    WELCOME";//液晶初始显示
uchar code table4[]="  ZHIYOUMAMAHAO";//液晶显示A歌名世上只有妈妈好
uchar code table5[]="    00:00:00";//液晶显示音乐时间
uchar code table6[]="     SONGBIE";//液晶显示B歌名送别

// 频率-半周期数据表 高八位   
code unsigned char FREQH[] = {
    0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8,    //低音1234567
    0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC,//1,2,3,4,5,6,7,i
    0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE,            //高音 234567
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF};   //超高音 1234567
// 频率-半周期数据表 低八位
code unsigned char FREQL[] = {
    0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6,    //低音1234567
    0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B, 0x8F, //1,2,3,4,5,6,7,i
    0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D,             //高音 234567
    0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16};   //超高音 1234567
//世上只有妈妈好数据表 

code unsigned char mamahao[] = {
6, 2, 3,  5, 2, 1,  3, 2, 2,  5, 2, 2,  1, 3, 2,  6, 2, 1,  5, 2, 1,
//一个音符有三个数字。前为第几个音、中为第几个八度、后为时长(以半拍为单位)。
//6, 2, 3 分别代表:6, 中音, 3个半拍;
//5, 2, 1 分别代表:5, 中音, 1个半拍;
//3, 2, 2 分别代表:3, 中音, 2个半拍;
//5, 2, 2 分别代表:5, 中音, 2个半拍;
//1, 3, 2 分别代表:1, 高音, 2个半拍;
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 songbie[] = {
5, 2, 2,          3, 2, 1,          5, 2, 1,          1, 3, 4,
//嗦,中音,2个半拍; 咪,中音,1个半拍; 嗦,中音,1个半拍; 哆,高音,4个半拍
6, 2, 2,          1, 3, 1,          6, 2, 1,          5, 2, 4,
//啦,中音,2个半拍; 哆,高音,1个半拍; 啦,中音,1个半拍; 嗦,中音,4个半拍
5, 2, 2,          3, 2, 1,          5, 2, 1,          1, 3, 4,
//嗦,中音,2个半拍; 咪,中音,1个半拍; 嗦,中音,1个半拍; 哆,高音,4个半拍
6, 2, 2,          1, 3, 1,          6, 2, 1,          5, 2, 4,
//啦,中音,2个半拍; 哆,高音,1个半拍; 啦,中音,1个半拍; 嗦,中音,4个半拍
0, 0, 0};
void t0int() interrupt 1         //T0中断程序,控制发音的音调
{
    TR0 = 0;                     //先关闭T0
    speaker = !speaker;          //输出方波, 发音
    TH0 = timer0h;               //下次的中断时间, 这个时间, 控制音调高低
    TL0 = timer0l;
    TR0 = 1;                     //启动T0
}
void delay1(unsigned char t)     //音乐延时程序,控制发音的时间长度
{
    unsigned char t1;
    unsigned long t2;
    for(t1 = 0; t1 < t; t1++)    //双重循环, 共延时t个半拍
      for(t2 = 0; t2 < 8000; t2++); //延时期间, 可进入T0中断去发音
    TR0 = 0;                        //关闭T0, 停止发音
}
void song()                      //演奏一个音符
{
    TH0 = timer0h;               //控制音调
    TL0 = timer0l;
    TR0 = 1;                     //启动T0, 由T0输出方波去发音
    delay1(time);                 //控制时间长度
}


void display_FMQ_MMH()//演奏世上只有妈妈好
{
    unsigned char k, a;
    TMOD = 1;                    //置T0定时工作方式1
    ET0 = 1;                     //开T0中断
    EA = 1;                      //开CPU中断
    while(1)
 {
      a = 0;
      time = 1;
      while(time)
  {
        k = mamahao[a] + 7 * mamahao[a + 1] - 1;
                      //第i个是音符, 第i+1个是第几个八度
        timer0h = FREQH[k];      //从数据表中读出频率数值
        timer0l = FREQL[k];      //实际上, 是定时的时间长度
        time = mamahao[a + 2];   //读出时间长度数值
        a += 3;
        song();                  //发出一个音符
  } 
  }
}

void display_FMQ_SB()//演奏送别
{
    unsigned char k, i;
    TMOD = 1;                    //置T0定时工作方式1
    ET0 = 1;                     //开T0中断
    EA = 1;                      //开CPU中断
    while(1)
 {
      i = 0;
      time = 1;
      while(time)
  {
        k = songbie + 7 * songbie[i + 1] - 1;
                      //第i个是音符, 第i+1个是第几个八度
        timer0h = FREQH[k];      //从数据表中读出频率数值
        timer0l = FREQL[k];      //实际上, 是定时的时间长度
        time = songbie[i + 2];   //读出时间长度数值
        i += 3;
        song();                  //发出一个音符
  } 
  }
}

void delay(uint z)//普通延时
{
 uint x,y;
 for(x=z;x>0;x--)
  for(y=110;y>0;y--);
}
void write_com(uchar com)//液晶写指令
{
 lcdrs=0;//写指令
 P0=com;
 delay(5);
 lcden=1;
 delay(5);
 lcden=0;//以上都是根据指令表写出
}
void write_data(uchar date)//液晶写数据
{
 lcdrs=1;//写数据
 P0=date;
 delay(5);
 lcden=1;
 delay(5);
 lcden=0;//以上都是根据指令表写出
}
void write_sfm(uchar add,uchar date)//液晶显示时分秒
{
 uchar shi,ge;
 shi=date/10;
 ge=date%10;//秒的
 write_com(0x80+0x40+add);
 write_data(0x30+shi);
 write_data(0x30+ge);
}
void init1()//音乐A初始化液晶显示
{
 uchar num;
 s1=1;//初始化s1
 lcdrw=0;//写入为0
 lcden=0;
 write_com(0x38);//开显示
 write_com(0x0c);//不显示光标
 write_com(0x06);
 write_com(0x01);//清屏
 write_com(0x80);
 for(num=0;num<15;num++)
  {
   write_data(table4[num]);
   delay(5);
  }
 write_com(0x80+0x40);
 for(num=0;num<12;num++)
  {
   write_data(table5[num]);
   delay(5);
  } 
 TMOD=0x10;//定时器1的方式1
 TH1=(65536-50000)/256;
 TL1=(65536-50000)%256;//初值
 EA=1;
 ET1=1;
 TR1=1;//启动定时器


}

void display_YJ_A()//液晶显示音乐A和时间计数
{
 init1();
 for(i=0;i<32;i++)//点阵显示DGXT
 {   
  for(j=0;j<8;j++)
  {
   P3=table[j];//红
   P1=table1[j+i];//绿
   delay(5);
  }
 delay(5);
 }
}
void tiner0() interrupt 3//液晶显示所用中断1定时中断
{
 TH1=(65536-50000)/256;
 TL1=(65536-50000)%256;//初值
 count++;
  if(count==20)//20ms
  {
   count=0;//清零            
   miao++;
   if(miao==60)
    {
     miao=0;
     fen++;
     if(fen==60)
      {
       fen=0;
       shi++;
       if(shi==24)
       {
        shi=0;        
       }
       write_sfm(4,shi);
      }
      write_sfm(7,fen);      
    }
    write_sfm(10,miao);
  }
}

void init2()//音乐B初始化液晶显示
{
 uchar num;
 s5=1;//初始化s5
 lcdrw=0;//写入为0
 lcden=0;
 write_com(0x38);//开显示
 write_com(0x0c);//不显示光标
 write_com(0x06);
 write_com(0x01);//清屏
 write_com(0x80);
 for(num=0;num<12;num++)
  {
   write_data(table6[num]);
   delay(5);
  }
 write_com(0x80+0x40);
 for(num=0;num<12;num++)
  {
   write_data(table5[num]);
   delay(5);
  } 
  delay(20);
  count++;
  if(count==20)//20ms
  {
   miao++;
   if(miao==60)
    {
     miao=0;
     fen++;
     if(fen==60)
      {
       fen=0;
       shi++;
       if(shi==24)
       {
        shi=0;        
       }
       write_sfm(4,shi);
      }
      write_sfm(7,fen);      
    }
    write_sfm(10,miao);
  }
}
void display_YJ_B()//液晶显示音乐B和时间计数
{
 init2();
 for(i=0;i<32;i++)//点阵显示DGXT
 {   
  for(j=0;j<8;j++)
  {
   P3=table[j];//红
   P1=table1[j+i];//绿
   delay(5);
  }
 delay(5);
 }
}
void display_YJ_WELCOME()//液晶初始化显示欢迎
{
 uchar num; 
 lcdrw=0;//写入为0
 lcden=0;
 write_com(0x38);//开显示
 write_com(0x0c);//不显示光标
 write_com(0x06);
 write_com(0x01);//清屏
 write_com(0x80);
 for(num=0;num<11;num++)
  {
   write_data(table3[num]);
   delay(5);
  }
 while(1)
 {
  for(i=0;i<32;i++)//点阵显示DGXT
  {   
   for(j=0;j<8;j++)
   {
    P3=table[j];//红
    P1=table1[j+i];//绿
    delay(5);
   }
   delay(5);
  }
 } 
}
void keyscan1()//音乐A键
{
   display_YJ_A();//液晶显示音乐A和时间计数点阵
//   display_FMQ_MMH();//放音乐A世上只有妈妈好
}
void keyscan2()//音乐B键
{
   display_YJ_B();//液晶显示音乐B和时间计数点阵
//   display_FMQ_SB();//放音乐B送别
}
void keyscan3()//开机键
{
   display_YJ_WELCOME();//显示欢迎
}
void init()
{
 s1=1;//初始化s1
 s5=1;//初始化s5
 s9=1;//初始化s9 
}
void main()
{
 p2_0=0;//行列键盘变成独立键盘
 init();
 EA=1;
 EX0=1;
 TCON=0x01;

 TMOD=0x01;//定时器0的方式1
 TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;//初值   //遇到问题时间累加 没有清零
 EA=1;
 ET0=1;
 TR0=1;//启动定时器

 if(s9==0)
 {
  delay(5);
  if(s9==0)
  {
  keyscan3(); 
  delay(5);
  }
 delay(10);//延时10ms去后面抖动
 }
}
void tiner_s1() interrupt 0//按键s1所用中断外部中断0
{

 if(s1==0)
 {
  delay(5);
  if(s1==0)
  {
  keyscan1(); 
  delay(5);
  }
 delay(10);//延时10ms去后面抖动
 }
}
void tiner_s5() interrupt 1//按键s5所用中断定时器0
{
 TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;//初值
 if(s5==0)
 {
  delay(5);
  if(s5==0)
  {
  keyscan2(); 
  delay(5);
  }
 delay(10);//延时10ms去后面抖动
 }

此帖出自51单片机论坛
 
 
 

回复

535

帖子

0

TA的资源

五彩晶圆(初级)

18
 

回复 17楼 51学习者 的帖子

大哥,首先我说你感谢错了人了。。。你要感谢的是孤獨の快樂,他帮你了好多,我是打酱油的 ,看到你做一个东西这么执着我真的很感动,但是我给你提一个小建议就是程序最好能够模块化,要不然很看起来很累啊,所谓的模块化就是你把实现比如唱歌的所有的函数写在一个.c文件里面,实现1602的写在一个。c文件里面,然后写出对应的。h文件,接着你就做文件包含就好了,我给你传一个教程吧,说的是多文件组织的。。。你多学习下啊!要不然看起来累,你找错不方便。。。
此帖出自51单片机论坛
 
 
 

回复

192

帖子

0

TA的资源

纯净的硅(初级)

19
 

回复 18楼 小小白 的帖子

谢谢孤獨の快樂,我的中断有点明白了,也改进了很多!
也感谢小白的提示!
昨天把中断改了改基本可以实现了,时间清零解决了,现在的问题就是把音乐加进去,还有就是然后让音乐停止时,延时一会液晶复位,基本就这2个问题了。
我同学的意见是把音乐放在主函数中,复位功能用for语句,次数就是音乐时间。正在想如何实现,不知道思路对不
还有关于模块化的这个在天狼星的视频里有,但是没看懂.....也没具体实践过,小白把教程给我吧。QQ526844809,在线...或者附件我下载
此帖出自51单片机论坛
 
 
 

回复

192

帖子

0

TA的资源

纯净的硅(初级)

20
 

回复 18楼 小小白 的帖子

资料看见了 谢谢
此帖出自51单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表