zoukankan      html  css  js  c++  java
  • C51 原创电子琴 (蜂鸣器/计时器/中断/矩阵按键)

    需求分析

    用C51的16个矩阵按键当作两个八度的琴键
    按下时发出相应音调的声音,静态数码管显示相应音符的数字。
    为了解锁更多曲目,两个多的琴键设计成#4,显示时加上小数点
    下图分别为1和#4的显示,其中图一上标明了各按键的对应的音符:

    思路

    每当按键按下,判断是那个按键,
    在按键尚未松开时循环以下内容:启动定时器,计时的时长为“该音调频率的一半“,每过这段时间,蜂鸣器所在引脚电平取反

    各音符的频率

    参考:https://blog.csdn.net/weixin_34724366/article/details/80642207

    Highs 和 Lows 的计算方法:

    1/(2f) s = 1000/(2f) ms = 500 / f ms
    然后带入这个小程序即可

    接线图

    完整代码

    #include <reg51.h>
    typedef unsigned int u16;		 
    typedef unsigned char u8;
    
    #define GPIO_KEY P1
    #define GPIO_DIG P0
    sbit beep = P3^0;
    
    /*******************************全局变量******* *******************/    
     
    u8 code Highs[24] = {
    0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfe,0xfd,
    0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff ,0xff };
    
    u8 code Lows[24] = {
    0x44,0xfac,0x09,0x34,0x82,0xc7,0x05,0x5c,
    0x22,0x56,0x84,0x9a,0xc1,0xe3,0x02,0x11  };
    
    //共阴的表
    u8 code ledSegment  [24] = { 0x06,   0x5b,   0x4f,   0x66,   0x6d, 0x7d,   0x07,0xe6, 
                                 0x06,   0x5b,   0x4f,   0x66,   0x6d, 0x7d,   0x07,0xe6,
                                 0x06,   0x5b,   0x4f,   0x66,   0x6d, 0x7d,   0x07,0xe6};
    
    u8 KeyValue;
    
    /***************************************************************/
    
    void delay(u16 i)
    {
        while(i--);
    }
    void keyDown()
    {
        //char a = 0;
        GPIO_KEY = 0x0f;  //高四位低电平,低四位高电平
        if(GPIO_KEY!= 0x0f)           //如果有按键按下
        {
            delay(1000);                    //延时防抖
            if(GPIO_KEY!= 0x0f)
            {
                //--------------------求被按下的按键在第几列----------------------------//
                switch(GPIO_KEY)
                {
                    case(0x07):  KeyValue = 0; break;       //0000 0111  : 第一列
                    case(0x0b):  KeyValue = 1; break;       //0000 1011  : 第二列
                    case(0x0d):  KeyValue = 2; break;       //0000 1101  : 第三列
                    case(0x0e):  KeyValue = 3; break;       //0000 1110  : 第四列
                }
                //--------------------求被按下的按键在第几行----------------------------//
                GPIO_KEY = 0xf0;  //高四位高电平,低四位低电平   
                switch(GPIO_KEY)
                {
                    case(0x70):  KeyValue += 0; break;    //第一行 
                    case(0xb0):  KeyValue += 4; break;      
                    case(0xd0):  KeyValue += 8; break;       
                    case(0xe0):  KeyValue += 12; break;     //第四行
                }
    
                //--------------------------开始计时----------------------------------//
                    GPIO_DIG = ~ledSegment[KeyValue];  //共阳数码管,共阴的表,所以要取反
                    //赋初值
                    TH0 =  Highs[KeyValue];
                    TL0 = Lows[KeyValue];
                    //开始计时
                    TR0=1;
                //退出条件:按键松开
                while(GPIO_KEY!= 0xf0)         //   GPIO_KEY!= 0xf0 说明按键还没松,此时CPU始终在此循环中
                {
    
                }
            }
        }   
    }
    
    void T0Init()
    {   
        TMOD |= 0x01;       //选择工作方式,给TMOD 赋值   ,这里选T0,方式一  
        ET0 = 1 ;           //中断允许:总允许和T0允许
        EA = 1;
    }
    
    void main(void)
    {
        T0Init();   
        while(1)
        {
            keyDown();
            
        }
    }
    //计时器0的调用程序
    void Timer0() interrupt 1             //    T0溢出时引用
    {   
        //退出条件:按键松开 
        if(!(GPIO_KEY== 0xf0 || GPIO_KEY== 0x0f))       //如果按键还没松开,进入下一个计时
        {
            TH0 =  Highs[KeyValue];
            TL0 = Lows[KeyValue];
            beep = ~beep;
        }           
    }
    
  • 相关阅读:
    php中的md5()的安全问题
    爆破之中文转换成字母脚本
    MYSQL数据库封装类
    SQL执行结果操作
    原生和jquery 的 ajax
    Ajax实例OR技术原理 转自 (http://blog.csdn.net/evankaka )
    JQuery常用事件
    分页原理
    JQuery中$.ajax()方法参数
    session和cookie的作用和原理
  • 原文地址:https://www.cnblogs.com/YuQiao0303/p/9910425.html
Copyright © 2011-2022 走看看