找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6986|回复: 6
打印 上一主题 下一主题
收起左侧

单片机驱动LED数码管,按键TM1638芯片学习心得

[复制链接]
跳转到指定楼层
楼主
TM1638是带键盘扫描接口的LED(发光二极管显示器)驱动控制专用电路,内部集成有MCU 数字接口、数据锁存器、LED 高压驱动、键盘扫描等电路。主要应用于冰箱、空调 、家庭影院等产品的高段位显示屏驱动。
因为步进电机实验需要用到按键,但家有婴儿,没用松香铬铁之类的(技术早就还给老师了,也没有条件),只好在网上找,找到一个由TM1638做成的成品,感觉做工还不错,就买了一个,但其带的程序一时没看懂,花了些时间进行学习,觉得好精妙,就想分享一下。
绝不是给别人打广告,这程序确实我理解了很久。
附件是它完整的程序。

调用实现程序主要是显示与按键值获取。
1.显示:
为什么是0xc0|add呢?
因为芯片说明有:高位都是11, 就是C了。

void Write_DATA(unsigned char add,unsigned char DATA)                //指定地址写入数据
{
        Write_COM(0x44);
        STB=0;
        TM1638_Write(0xc0|add);
        TM1638_Write(DATA);
        STB=1;
}
2.按键获取:
注意这儿是从低位开始读的, 理解 的时候把B0~B7反过来理解就更好理解下面这个按键程序。在这儿花了很多时间来想这个。得到的 i 值就是按的第几个键。这儿真的这个程序写得太妙了,这个大神绝对的高手。


单片机程序
  1. unsigned char Read_key(void)
  2. {
  3.         unsigned char c[4],i,key_value=0;
  4.         STB=0;
  5.         TM1638_Write(0x42);                           //读键扫数据 命令
  6.         for(i=0;i<4;i++)               
  7.                 c[i][i]=TM1638_Read();
  8.         STB=1;                                                   //4个字节数据合成一个字节
  9.         for(i=0;i<4;i++)
  10.                 key_value|=c[i][i]<<i;
  11.         for(i=0;i<8;i++)
  12.                 if((0x01<<i)==key_value)
  13.                         break;
  14.         return i;
  15. }
复制代码

TM1638测试程序C51.rar

27.17 KB, 下载次数: 113, 下载积分: 黑币 -5

tm1638芯片数据手册.pdf

873.68 KB, 下载次数: 42, 下载积分: 黑币 -5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:626079 发表于 2020-2-18 21:24 | 只看该作者
今晚上做了实验,再对比程序。。

1.jpg (187.44 KB, 下载次数: 63)

1.jpg

press1.jpg (177.72 KB, 下载次数: 52)

press1.jpg

press2.jpg (180.37 KB, 下载次数: 59)

press2.jpg

press3.jpg (179.35 KB, 下载次数: 64)

press3.jpg

press4.jpg (183.43 KB, 下载次数: 63)

press4.jpg

实物.jpg (130.01 KB, 下载次数: 58)

实物.jpg
回复

使用道具 举报

板凳
ID:626079 发表于 2020-2-18 21:31 | 只看该作者
但是这样的显示执行结果不是我想要的。明天再研究改一下程序。我只需要按一个键做开关,显示1或0就可以了,别的键都不需要改变。或者有哪个大神帮我改一下。
回复

使用道具 举报

地板
ID:626079 发表于 2020-2-18 22:54 | 只看该作者
最简单的改动,现在实现了只显示1或0状态。只是这样的话理论上所有的按键都可以控制电机开启了。。。。
                        while(Read_key()==i);                       //等待按键释放
//                        if(num[i]>15)                                           //原程序是按一下键,自动计数加1.可以加到15
                       
                        if(num[i]>1)                                           //改为实现了只显示1与0(加到1,就值改为0),1电机启动,0电机断开
                        num[i]=0;
                        Write_DATA(i*2,tab[num[i]]);
                        Write_allLED(1<<i);
                }
               
               
                if(num[i]==1)
                        {
                          //电机开启程序
                        }
回复

使用道具 举报

5#
ID:626079 发表于 2020-2-19 22:43 | 只看该作者
    今晚把TM1368.H加入步进电机程序中,测试通过了对步进电机开启与停止的控制,这儿取的num[0]=1来控制,测试发现是左边第一个键,
对这个模块的整个测试过程就我这儿就结束了。

但是后来又看了这个Read_key()程序, 我把key_value|=c[ i]<<i; 这句改为key_value|=c[ i](我的理解是应该这样才科学)[,发现结果显示就不一样了:按下左边4个键中任何一个,都是只有左边那个LED的最高位进行0或1的变化,后面的LED都是显示0无变化;按下右边4个键中任何一个,都是中间那个LED(就是右边4位数码管的高位)进行0或1的变化,其它的LED都是显示0无变化。 求哪位大侠解惑啊。

  1. void main()
  2. {
  3.         unsigned char i;
  4.         DIANJICLK=0;
  5.         ENA=1;                                 //ENA-接的控制口,但一样的,如果ENA=0,步进电机卡起
  6.         DIR=1;                                 //DIR-接的控制口。初始化电机        低电平有效,测试,DIR=1,是正转, DIR=0反转。

  7.         
  8.         /******调用TM1638按键显示模块********/
  9.         init_TM1638();                                   //初始化TM1638
  10.         for(i=0;i<8;i++)
  11.         Write_DATA(i<<1,tab[0]);                       //初始化寄存器
  12.         /******调用TM1638按键显示模块********/
  13.         

  14.         P2=0X00;
  15.         delay(2000);                            //延时等待系统稳定。
  16.         P2=0XFF;
  17.         
  18.         Init_time();                 //初始化定时器        
  19.         
  20.         while(1)
  21.         {
  22.         /******调用TM1638按键显示模块得到返回值********/
  23.            
  24.                    i=Read_key();                          //读按键值


  25.                 if(i<8)
  26.                 {
  27.                         num[i]++;
  28.                         while(Read_key()==i);                       //等待按键释放
  29. //                        if(num[i]>15)                                           //原程序是按一下键,自动计数加1.
  30.                         
  31.                         if(num[i]>1)                                           //改为只显示1与0,1电机启动,0电机断开
  32.                         num[i]=0;
  33.                         Write_DATA(i*2,tab[num[i]]);
  34.                         Write_allLED(1<<i);
  35.                 }
  36.                
  37.                
  38.                 if(num[0]==1)
  39.                         {
  40.                           //电机开启程序
  41.                         Run_Status=~Run_Status;
  42.                         if(Run_Status)
  43.                         {
  44.                                 count=counttemp;
  45.                                 TR0=1;                       //开启中断产生脉冲信号
  46.                                  EA=1;
  47.                                 
  48.                         }
  49.                         else
  50.                         {
  51.                                 counttemp=count;
  52.                                     TR0=0;                       //关闭中断停止脉冲信号
  53.                                    EA=0;
  54.                         }
  55.                         }

  56. //                Key_scan();
  57.          
  58.          }        
  59. }
复制代码


控制步进电机开关.jpg (165.27 KB, 下载次数: 75)

控制步进电机开关.jpg
回复

使用道具 举报

6#
ID:292876 发表于 2020-3-19 16:53 | 只看该作者

   //------------下面是读按键和键值分离程序------------

unsigned char Read_key(void)
{
        unsigned char c[4],i,key_value=0;
        STB=0;
        TM1638_Write(0x42);
        Delay10us();
        for(i=0;i<4;i++)
                c[i]=TM1638_Read();
        STB=1;                                       

            //K1组合8键
        if(c[0]==0x04) key_value=1;           //KS1K1
        if(c[0]==0x40) key_value=2;           //KS2K1
        if(c[1]==0x04) key_value=3;           //KS3K1
        if(c[1]==0x40) key_value=4;           //KS4K1
        if(c[2]==0x04) key_value=5;           //KS5K1
        if(c[2]==0x40) key_value=6;           //KS6K1
        if(c[3]==0x04) key_value=7;           //KS7K1
        if(c[3]==0x40) key_value=8;           //KS8K1
          //K2组合8键
        if(c[0]==0x02) key_value=9;           //KS1K2
        if(c[0]==0x20) key_value=10;   //KS2K2
        if(c[1]==0x02) key_value=11;   //KS3K2
        if(c[1]==0x20) key_value=12;   //KS4K2
        if(c[2]==0x02) key_value=13;   //KS5K2
        if(c[2]==0x20) key_value=14;   //KS6K2
        if(c[3]==0x02) key_value=15;   //KS7K2
        if(c[3]==0x20) key_value=16;   //KS8K2
          //K3组合8键
        if(c[0]==0x01) key_value=17;   //KS1K3
        if(c[0]==0x10) key_value=18;   //KS2K3
        if(c[1]==0x01) key_value=19;   //KS3K3
        if(c[1]==0x10) key_value=20;   //KS4K3
        if(c[2]==0x01) key_value=21;   //KS5K3
        if(c[2]==0x10) key_value=22;   //KS6K3
        if(c[3]==0x01) key_value=23;   //KS7K3
        if(c[3]==0x10) key_value=24;   //KS8K3

        return key_value;
}


回复

使用道具 举报

7#
ID:292876 发表于 2020-3-19 16:54 | 只看该作者
这个模块自带程序实际使用不方便,可以按照上面的改,主程序按键如何操作很简单了!判断键值就行
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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