⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file8.c

📁 单片机学习系统附的实验源代码
💻 C
字号:
// 音乐编程
//通过蜂鸣器发出讯响
//只要通过修改 后面的音乐程序里面的码
//表就可以自己谱曲唱歌!
//前一个参数为按照编码表给定,第二个参数为节拍数

#include <8051.h>

#define uchar unsigned char

#define key1  P3_4    //键盘定义
#define key2  P3_5
#define key3  P3_6

#define beep  P3_7   //蜂鸣器定义

uchar timer_h;
uchar timer_l;

//****************************************************************************
void reset();       
void delay(uchar times);
void dems();             //休止符延时
void display(uchar disseg,uchar disdata);
uchar keyb();

// 这里定义的是数码管对应的字符字根
code uchar  disbuf_u[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
                        0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
                        0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
                        0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
// 这里定义音乐音符表
code uchar musictabl[]={0xf0,0xf0,
                        
           0xf8,0x8b,0xf9,0x5b,0xfa,0x14,0xfa,0x0c,0xfb,0x03,0xfb,0x8f,0xfc,0x0b,

           0xfc,0x43,0xfc,0xab,0xfd,0x08,0xfd,0x33,0xfd,0x81,0xfd,0xc7,0xfe,0x05,

           0xfe,0x32,0xfe,0x55,0xfe,0x84,0xfe,0x99,0xfe,0xc0,0xfe,0xe3,0xff,0x02};


//这里定义音乐曲谱表格
code uchar musicdata[]={6,4, 8,4,10,4, 1,4, 9,8, 8,4, 7,4,10,8,9,8,6,16,
                        8,4,10,4,12,4,12,4,13,8,12,4,11,4,10,16,0};

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

void ClockIrqHandler (void) interrupt 1 using 3;   //定义定时器T0中断服务程序

//下面是定时器T0的中断服务程序
void ClockIrqHandler (void) interrupt 1 using 3 {
  TR0 = 0;          //关闭定时器
  TL0 = timer_l;
  TH0 = timer_h;
  beep = ~beep;
  TR0 = 1;          //打开定时器
}
// *****************   定时器程序  **********************************

uchar keybuf;

void main()
{
    uchar counts,mustmp,tmp,keym =  0;   //键盘返回结果的缓冲区
    
    reset();           //调用初始化程序 

  while(1)             //设置一个无限制循环
 {  
   for(counts=0;musicdata[counts]!=0;counts+=2)
    {
        mustmp = musicdata[counts];
        TR0 = 0;

        tmp = musictabl[mustmp];
        timer_h = tmp;

        tmp = musictabl[mustmp+1];
        timer_l = tmp;

        TR0 = 1; 
        display(0,musicdata[counts+1]);      
        delay(musicdata[counts+1]);
        TR0 = 0;
        dems();
     }
 //       display(250,0); 
  //      delay(255); 
  //      delay(255);
     
//      display(keybuf-1,keybuf);   //在相应的位置显示返回的结果
  }
}

void reset()
{

    keybuf = 0;
    P1 = 255;          //关闭LED显示
    P0 = 0;            //关闭数码显示
    P2 = 255;          //
    P3_7 = 0;          //关闭蜂鸣器
//*********  上面是一些基础定义   **************

   TL0 = 0xff;   //初值
   TH0 = 0xff;     //初值
   ET0=1;    // 允许定时器T0中断
   EA =1;    // 中断总允许
}
//*****************************************************************************
//下面是延时程序。具体的延时时间不能通过表面程序看出,(为什么?)
//如果我们需要一个精密的延时程序,那么我们可以采用内嵌汇编代码的方式
void delay(uchar times)
{
    int t=24000;           //延时倍数
    uchar i=times;   
    for(;i!=0;i--)
    {for(;t!=0;t--){}}
}

void dems()             //休止符延时
{
_asm 
         mov R0,#0
   llp:  mov R1,#100
   llk:  djnz R1,llk
         djnz R0,llp
_endasm; 
}

//这里是显示子程序,入口参数为
// disseg  -> 位选 可选范围 0-7 一共8个数码管
// disdata -> 段选 可选范围 0-31 一个32个字符
//  段选 0-15  16个字符 为 "0"->"F"
//  段选 16-31 16个字符 为 "0."->"F."

void display(uchar disseg,uchar disdata)
{
    uchar dataf;
   if(disseg < 8)          //只有当要显示的位数有效,才显示.否则,不显示
  {
     dataf = 1;
     while(disseg)
     {
         dataf <<= 1;
         disseg--;
      }
	       P0 = dataf;
         P2 = disbuf_u[disdata];
   }
   else{P0=0,P2=255;}  //关闭数码管显示
}

uchar keyb()
{
    uchar key,keytmp;

    key1 = 1;   //将输出线拉高
    key2 = 1;
    key3 = 1;

    key = P3 ;  //读回来
    key = key & 0xf0;           //获得键盘结果
    if(key == 112 ) return 0;   //如果用户没有按键返回 0  
    else
     { 
       keytmp = key;    
       delay(1);              //判断是不是干扰
       key = P3 & 0xf0;
       if (key != keytmp ) return 0;  //是干扰,返回 0
          else                        //不是干扰,等待用户释放按键
            {                
                  do{ 
                      key1 = 1;       //输出拉高
                      key2 = 1;
                      key3 = 1;
                    key = P3 & 0xf0;  //读回来
                    P1_0 = ~P1_0;     //如果用户不释放,闪烁 p1.0 
                   }while(key != 112 );   //等待用户释放 
                    P1_0 = 1;             //用户释放以后,清除p1.0指示灯
                   switch(keytmp)
                      {
                         case 96: return 3;//返回用户按键结果
                         case 80: return 2;
                         case 48: return 1;
                       }         
                  
             }

   
      }
    
    
}
//*******************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -