找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1451|回复: 0
收起左侧

电子琴简单的程序

[复制链接]
ID:333870 发表于 2018-5-19 20:14 | 显示全部楼层 |阅读模式
#include <reg52.h>
#define   FOSC    12000000
#define T0FENPING  12
unsigned int code JINJIEFREQ[] =
{
  262,294,330,349,392,440,494,
  523,587,659,699,784,880,988,
  1046,1175,1319,1391,1568,1760,1976
};

bit RunFlag = 0;
sbit Beep = P3^0;
unsigned char STH0,STL0,num1,num,temp,m,jishu;
unsigned char keyscan();
void Delay10ms(unsigned int c) ;
void delay(unsigned int c);
void T0_ISR(void) interrupt 1
{
  if(1 == RunFlag)                                  //--- 在音阶播放标志为1情况下 ---
    {
      TH0 = STH0;                                   //--- 重新装初值 ---
      TL0 = STL0;
      Beep = ~Beep;                                   //--- P5.5引脚上的电平翻转 ---
    }
}
void main(void)
{
  unsigned int i;
  unsigned char j;

//  AUXR |= 0x80;                                     //--- 使能T0的计数器时钟分频值为1 ---
  TMOD = 0x01;                                      //--- 配置T0为定时模式,工作于方式2 ---
  ET0 = 1;                                          //--- 使能T0中断 ---
  TR0 = 1;
  EA = 1;                                           //--- CPU开中断 ---
  while(1)
    {
       num1 = keyscan();
           Beep = 1;
           while(m)
             {
                          m = 0;
                          STH0 = (65536 - FOSC / T0FENPING / 2 / JINJIEFREQ[num1]) / 256;
                  STL0 = (65536 - FOSC / T0FENPING / 2 / JINJIEFREQ[num1]) % 256;
                  TH0 = STH0;                       //--- 装入TH0,TL0的计数寄存器 ---
                  TL0 = STL0;
                  RunFlag = 1;           
                                  delay(500);   
                                          
                 }
                
                     
                    TH0 = 0;     
                
    }       
               
                  
}


unsigned char keyscan()         //定义子函数  键盘扫描
{
        P0=0xfe;   //第一行按键                 1111 1110
        temp=P0;//读取P2口
        temp=temp&0xf0;        //1111 0000                 即 1111 1110 & 1111 0000 =1111 0000
        while(temp!=0xf0) //  如果不等于  说明有键按下
        {                                                                                                                                 
                Delay10ms(1);
                temp=P0;//再次读一下P2口的值        1110 1110
                temp=temp&0xf0;                        //                1110 1110 &1111 0000= 1110  0000
                while(temp!=0xf0) //确认是否按下
                {
                        temp=P0; //P2口的值读回来 1110 1110
                        switch(temp)  //可以看出是哪一列    temp和case后的 0xee 相比  如果相等 执行 num
                        {
                                case 0xee:num=0,m=1;//按下第一行 第一个键 是 1110 1110 即ee
                                        break;//跳出这个语句
                                case 0xde:num=1,m=1;                         //1101 1110   de
                                        break;
                                case 0xbe:num=2,m=1;                         //1011 1110   be
                                        break;
                                case 0x7e:num=3,m=1;                         //0111 1110   7e
                                        break;
                        }
                        while(temp!=0xf0)//松手检测   按键 不松手 不等于0成立
                        {
                                temp=P0;
                                temp=temp&0xf0;                  //1110 1110& 1111 0000= 1110 0000
                        }
                        //        P0=table[num1-1];
                }
        }


        P0=0xfd;         //第二行按键        1111 1101
        temp=P0;//读取P2口
        temp=temp&0xf0;
        while(temp!=0xf0) //看是否有键按下
        {
                Delay10ms(1);
                temp=P0;//再次读一下P2口的值
                temp=temp&0xf0;
                while(temp!=0xf0)
                {
                        temp=P0; //P2口的值读回来 1111 1101
                        switch(temp)  //temp和case后的 0xed 相比  如果相等 执行 num
                        {
                                case 0xed:num=4,m=1;
                                        break;//跳出这个语句
                                case 0xdd:num=5,m=1;                         
                                        break;
                                case 0xbd:num=6,m=1;                       
                                        break;
                                case 0x7d:num=7,m=1;                         
                                        break;
                        }
                        while(temp!=0xf0)//松手检测   按键 不松手 不等于0成立
                        {
                                temp=P0;
                                temp=temp&0xf0;
                        }  //        P0=table[num1-1];
                }
        }       


        P0=0xfb;         //第三行按键  1111 1011
        temp=P0;//读取P2口
        temp=temp&0xf0;
        while(temp!=0xf0) //看是否有键按下
        {
                Delay10ms(1);
                temp=P0;//再次读一下P2口的值
                temp=temp&0xf0;
                while(temp!=0xf0)
                {
                        temp=P0; //P2口的值读回来 1111 1011
                        switch(temp)  //temp和case后的 0xeb 相比  如果相等 执行 num
                        {
                                case 0xeb:num=8,m=1;
                                        break;//跳出这个语句
                                case 0xdb:num=9,m=1;                       
                                        break;
                                case 0xbb:num=10,m=1;               
                                        break;
                                case 0x7b:num=11,m=1;               
                                        break;
                        }
                        while(temp!=0xf0)//松手检测   按键 不松手 不等于0成立
                        {
                                temp=P0;
                                temp=temp&0xf0;
                        }         //        P0=table[num1-1];
                }
        }       
       
        P0=0xf7;         //第四行按键          1111 0111
        temp=P0;//读取P2口
        temp=temp&0xf0;
        while(temp!=0xf0) //看是否有键按下
        {
                Delay10ms(1);
                temp=P0;//再次读一下P2口的值
                temp=temp&0xf0;
                while(temp!=0xf0)
                {
                        temp=P0; //P2口的值读回来 1111 0111
                        switch(temp)  //temp和case后的 0xe7 相比  如果相等 执行 num
                        {
                                case 0xe7:num=12,m=1;
                                        break;
                                case 0xd7:num=13,m=1;                         
                                        break;
                                case 0xb7:num=14,m=1;                         
                                        break;
                                case 0x77:num=15,m=1;                         
                                        break;
                        }
                        while(temp!=0xf0)//松手检测   按键 不松手 不等于0成立
                        {
                                temp=P0;
                                temp=temp&0xf0;
                        } //        P0=table[num1-1];
                }
        }       
        return num;
}


void Delay10ms(unsigned int c)   //延时  定义
{
    unsigned char a,b;

        //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
    for (;c>0;c--)
        {
                for (b=38;b>0;b--)
                {
                        for (a=130;a>0;a--);
                }

        }      
}
void delay (unsigned int c)
{
    unsigned int i,j;
          for(i=c;i>0;i--)
            for (j=110;j>0;j--);

}


回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表