找回密码
 立即注册
查看: 198|回复: 0

关于TM1650芯片数码管驱动与按钮输入信号采集的程序分享

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:288
  • 最近打卡:2026-03-12 21:55:50
已绑定手机

9

主题

56

回帖

154

积分

注册会员

积分
154
发表于 2026-1-17 18:25:46 | 显示全部楼层 |阅读模式
  1. /*
  2. * TM1652.h
  3. *
  4. *  Created on: Apr 18, 2023
  5. *      Author: Administrator
  6. */
  7. #ifndef __TM1650_H_
  8. #define __TM1650_H_
  9. #include "config.h"
  10. //#include<reg52.h>                                                                  //MCU头文件
  11. #include<intrins.h>                                                          //包含nop指令头文件
  12. #define uint unsigned int                                  //数据类型宏定义
  13. #define uchar unsigned char                          //数据类型宏定义
  14. #define nop _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();  //宏定义
  15. #define smg1 0x68
  16. #define smg2 0x6a
  17. #define smg3 0x6c
  18. #define smg4 0x6e
  19. #define L_Du01     0x11  // 亮度1级
  20. #define L_Du02     0x21  // 亮度2级  
  21. #define L_Du03     0x31  // 亮度3级
  22. #define L_Du04     0x41  // 亮度4级
  23. #define L_Du05     0x51  // 亮度5级
  24. #define L_Du06     0x61  // 亮度6级
  25. #define L_Du07     0x71  // 亮度7级
  26. #define L_Du08     0x81  // 亮度8级
  27. extern code unsigned char  DispCode[17];
  28. extern void delay(uint n);
  29. extern void TM1650_SystemCmd(uchar light,uchar segMod, uchar WorkMod, uchar Onoff);
  30. extern void TM1650Disp(uchar sdate1, uchar sdate2, uchar sdate3, uchar sdate4);
  31. extern void TM1650ReadKey(void);
  32. extern void WH_display(unsigned char DATA1,unsigned char DATA2);
  33. extern unsigned char TM1650_read();
  34. #endif /* MYBSP_TM1652_H_ */
复制代码
这个是.H文件


  1. /*
  2. * TM1652.c
  3. *
  4. *  Created on: Apr 18, 2023
  5. *      Author: Administrator
  6. */
  7. #include "TM1650.h"
  8. //每一段显示编码
  9. code unsigned  char  perseg[8]={0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
  10. //共阴驱动显示编码,0-F-灭
  11. code unsigned char  DispCode[17]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};
  12. //辉度调节指令,1-8级
  13. code unsigned char INTENS[8]={0x11,0x21,0x31,0x41,0x51,0x61,0x71,0x01};
  14. u8 code tab_run0[30] =
  15. {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0X7f,0X6f,0X77,0X7C,0X39,0X5E,0X79,0X71,0x3d,0x76,0x30,0x38,0x71,0x78,0x50,0X23,0X1C,0X00,0X40,0X63,0X73,0X37};
  16. //  0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F    G    H    I    L    F    T    R  上   下   空白 横杠  O   P   N
  17. //  0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16    17   18  19    20   21   22  23  24    25   26   27  28  29
  18. u8 code tab_run1[7]  = {0X00,0x43,0x2C,0x0F,0x23,0x1C,0x40};  //外呼方向
  19. u8 code tab_run2[21] = {0x3F,0x80,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0X7f,0X6f,0X77,0X7C,0X39,0X5E,0X79,0X71,0x3F};
  20. //通讯端口定义,客户可以根据实际平台进行相应的配置;
  21. //sbit SCL=P7^6;                       //时钟线
  22. //sbit SDA=P7^5;                       //数据线
  23. sbit SCL=P3^6;                       //时钟线
  24. sbit SDA=P3^7;
  25. ////主板数码管显示端口
  26. //sbit DIO     = P7^5;
  27. //sbit CLK     = P7^6;
  28. ////外呼显示端口
  29. //sbit DIO2    = P3^7;
  30. //sbit CLK2    = P3^6;
  31. ////数码管显示端口
  32. //sbit DIO     = P7^5;//主板数码管显示端口
  33. //sbit CLK     = P7^6;
  34. //读取按键值存储
  35. uchar keya;                             //定义读出按键返回值
  36. /*************1ms延时*晶振11.0592M********************/
  37. void delay(uint n)
  38. {
  39.   uint i;
  40.   while(n--)
  41.          for(i=0;i<550;i++);
  42. }
  43. /************ START信号*******************************/
  44. void TM1650_START()
  45. {
  46.         SCL=1;
  47.         SDA=1;
  48.         nop;
  49.         SDA=0;
  50.         nop;
  51.         SCL=0;
  52. }
  53. /******************** STOP信号************************/
  54. void TM1650_STOP()
  55. {
  56.         SDA=0;
  57.         nop;
  58.         SCL=1;
  59.         nop;
  60.         SDA=1;
  61.         nop;
  62.         SCL=0;
  63.         SDA=0;
  64. }
  65. /****************写1个字节给TM1650********************/
  66. void write_8bit( uchar dat)
  67. {
  68.         uchar i;
  69.         SCL=0;
  70.         for(i=0;i<8;i++)
  71.                 {
  72.                 if(dat&0x80)
  73.                 {
  74.                         SDA=1;
  75.                         nop;
  76.                         nop;
  77.                         SCL=1;
  78.                         nop;
  79.                         nop;
  80.                         nop;
  81.                         nop;
  82.                         nop;
  83.                         SCL=0;         
  84.                 }
  85.                 else
  86.                 {
  87.                         SDA=0;
  88.                         nop;
  89.                         nop;
  90.                         SCL=1;
  91.                         nop;
  92.                         nop;
  93.                         nop;
  94.                         nop;
  95.                         nop;
  96.                         SCL=0;
  97.                 }       
  98.                         dat<<=1;         
  99.                 }
  100.                 SDA=1;                        //ACK信号
  101.                 nop;
  102.                 nop;
  103.                 nop;
  104.                 nop;
  105.                 SCL=1;
  106.                 nop;
  107.                 nop;
  108.                 nop;
  109.                 nop;
  110.                 nop;
  111.                 SCL=0;
  112.                 nop;
  113.                 nop;         
  114. }
  115. /****读8bit
  116. 注意:本程序采用双向IO口,对于需要配置端口特性的MCU需要注意
  117. 在发送指令时配置为输出模式;
  118. 接受ACK为输入模式;
  119. 读数据位输入模式;
  120. **************************/
  121. uchar read_8bit()
  122. {
  123.         uchar dat,i;
  124.         SDA=1;
  125.         dat=0;
  126.         for(i=0;i<8;i++)
  127.         {
  128.         SCL=1;                        //时钟上沿
  129.         nop;
  130.         nop;
  131.         nop;
  132.         dat<<=1;
  133.         if(SDA)
  134.          dat++;
  135.         SCL=0;
  136.         nop;
  137.         nop;
  138.         nop;
  139.         nop;
  140.         }
  141.         SDA=0;                            //ACK信号
  142.         nop;
  143.         nop;
  144.         nop;
  145.         SCL=1;
  146.         nop;
  147.         nop;
  148.         nop;
  149.         nop;
  150.         SCL=0;
  151.         nop;
  152.        
  153.         return dat ;
  154. }
  155. /********发送显示数据*******/
  156. void TM1650_send(uchar saddr,uchar sdate)
  157. {
  158.         TM1650_START();
  159.         write_8bit(saddr);
  160.         write_8bit(sdate);
  161.         TM1650_STOP();
  162. }
  163. /**系统设置命令
  164. light -- 亮度级别(00H 8级亮度、10H为1级亮度。。。。。。70H为7级亮度)
  165. segMod -- 段模式设置(00H为8段模式,08H为7段模式)
  166. WorkMod -- 工作模式(00H为正常模式,04H为低功耗模式)
  167. Onoff -- 开关(00H为关显示,01H为开显示)
  168. 例如:1级亮度,7段模式,正常工作模式,开显示则函数为
  169. TM1650_SystemCmd(0x10, 0x08, 0x01, 0x01 );
  170. ***/
  171. void TM1650_SystemCmd(uchar light,uchar segMod, uchar WorkMod, uchar Onoff)
  172. {
  173.         TM1650_START();
  174.         write_8bit(0x48);
  175.         write_8bit(light | segMod | WorkMod | Onoff );
  176.         TM1650_STOP();
  177. }
  178. /**4位显示数据
  179. 0x68 对应DIG1
  180. 0x6A 对应DIG2
  181. 0x6C 对应DIG3
  182. 0x6E 对应DIG4
  183. 如果要DIG1-4显示0-3 则函数为TM1650Disp(DispCode[0],DispCode[1],DispCode[2],DispCode[3]);
  184. ***/
  185. void TM1650Disp(uchar sdate1, uchar sdate2, uchar sdate3, uchar sdate4)
  186. {
  187.                 TM1650_send(0X68,sdate1);  //GID1-sdate1
  188.                 TM1650_send(0X6A,sdate2);  //GID2-sdate2
  189.                 TM1650_send(0X6C,sdate3);  //GID3-sdate3
  190.                 TM1650_send(0X6E,sdate4);  //GID4-sdate4
  191. }
  192. void WH_display(unsigned char DATA1,unsigned char DATA2)
  193. {
  194.         TM1650_send(0x48,L_Du07);
  195.         switch(DATA1)  //箭头显示
  196.         {
  197.                 case 0:     TM1650_send(smg2,tab_run1[0]);break;   //
  198.                 case 1:     TM1650_send(smg2,tab_run1[1]);break;   //               
  199.                 case 2:     TM1650_send(smg2,tab_run1[2]);break;   //               
  200.                 case 3:     TM1650_send(smg2,tab_run1[3]);break;   //
  201.         }
  202.         switch(DATA2)//楼层信息显示
  203.         {
  204.                 case  0:    TM1650_send(smg1,tab_run2[0]);break;   //楼层0
  205.                 case  1:    TM1650_send(smg1,tab_run2[1]);break;   //楼层1
  206.                 case  2:    TM1650_send(smg1,tab_run2[2]);break;   //楼层2
  207.                 case  3:    TM1650_send(smg1,tab_run2[3]);break;   //楼层3
  208.                 case  4:    TM1650_send(smg1,tab_run2[4]);break;   //楼层4
  209.                 case  5:    TM1650_send(smg1,tab_run2[5]);break;   //楼层5
  210.         case  6:    TM1650_send(smg1,tab_run2[6]);break;   //楼层6
  211.                 case  7:    TM1650_send(smg1,tab_run2[7]);break;   //楼层7
  212.                 case  8:    TM1650_send(smg1,tab_run2[8]);break;   //楼层8
  213.                 case  9:    TM1650_send(smg1,tab_run2[9]);break;   //楼层9
  214. //                case 10:    tm1650_write_display2(smg1,tab_run2[7]);break;   //楼层7
  215.         }
  216. }
  217. /***TM1650上电清零操作
  218. 注意:对于关掉显示时,建议采用对所有显存进行清零操作,即4位显存发送0x00数据
  219. ***/
  220. //void TM1650Init(uchar light,uchar segMod, uchar DispMod, uchar Onoff)
  221. //{
  222. //        TM1650_SystemCmd(light, segMod,DispMod, Onoff);  //8级亮度+8段模式+正常工作模式+开显示
  223. //        //数据清零
  224. //        TM1650Disp(0x00,0x00,0x00,0x00);
  225. //}
  226. /***
  227.         逐段显示
  228.         light为亮度等级(00H\10H\...70H)
  229. ***/
  230. //void TM1650PersegDisp(uchar light)
  231. //{
  232. //        unsigned char i=0,j=0,Addr=0x68,fdate=0x01;
  233. //        TM1650_SystemCmd(light, 0x00, 0x00, 0x01);  //light亮度+8段模式+正常工作模式+开显示
  234. //        for(j=0; j<4; j++)
  235. //        {
  236. //                        for(i=0; i<9; i++)
  237. //                        {
  238. //                                        TM1650_send(Addr, fdate);
  239. //                                        fdate |= perseg[i];
  240. //                                        delay(100);
  241. //                        }
  242. //                        Addr+=2;
  243. //                        fdate=perseg[0];
  244. //        }
  245. //}
  246. /***显示1-99数据***/
  247. void TM1650Disp2Num(unsigned char snum)
  248. {
  249.        
  250.         TM1650Disp(0x00,0x00,DispCode[snum/10%10],DispCode[snum%10]);   //显示1、2、3、4
  251. }
  252. /*******************读按键命令************************/
  253. uchar TM1650_read()
  254. {
  255.         uchar key;
  256.         TM1650_START();
  257.     write_8bit(0x4F);   //读按键指令       
  258.         key=read_8bit();
  259.         TM1650_STOP();
  260.         return key;
  261. }
  262. /***按键处理函数
  263.     注意:该程序未处理按键松开时的情况
  264. ***/
  265. void TM1650ReadKey(void)
  266. {
  267.                 unsigned char KeyDate=0x00;
  268.           KeyDate = TM1650_read();
  269.                 switch(KeyDate)
  270.                 {
  271.                         /**单个按键**/
  272.             case 0x06:WH_display(1,1);break;        //KI1+DIG4 //KI3+DIG4
  273.                         case 0x0E:WH_display(1,2);break;                //KI2+DIG4 //KI4+DIG4
  274.                         case 0x26:WH_display(1,3);break;                //KI3+DIG4 //KI5+DIG4
  275.                         case 0x2E:WH_display(1,4);break;        //KI4+DIG4 //KI6+DIG4
  276.             
  277.             
  278.             case 0x47:WH_display(1,0);break;        //KI1+DIG4
  279.             case 0x4f:WH_display(1,0);break;                //KI2+DIG4
  280.             case 0x57:WH_display(1,0);break;                //KI3+DIG4
  281.             case 0x5f:WH_display(1,0);break;                //KI4+DIG4
  282.             case 0x67:WH_display(1,0);break;                //KI5+DIG4
  283.             case 0x6f:WH_display(1,0);break;                //KI6+DIG4
  284.             case 0x77:WH_display(1,0);break;                //KI7+DIG4
  285.             
  286.             
  287.                         case 0x44:WH_display(1,0);break;        //KI1+DIG1
  288.                         case 0x45:WH_display(1,0);break;                //KI1+DIG2
  289.                         case 0x46:WH_display(1,0);break;                //KI1+DIG3
  290.                        
  291.                         case 0x4C:WH_display(1,1);break;                //KI2+DIG1
  292.                         case 0x4d:WH_display(1,1);break;                //KI2+DIG2
  293.                         case 0x4e:WH_display(1,1);break;                //KI2+DIG3
  294.                        
  295.                         case 0x54:WH_display(1,2);break;                //KI3+DIG1
  296.                         case 0x55:WH_display(1,2);break;                //KI3+DIG2
  297.                         case 0x56:WH_display(1,2);break;                //KI3+DIG3
  298.                        
  299.                         case 0x5C:WH_display(1,3);break;                //KI4+DIG1
  300.                         case 0x5d:WH_display(1,3);break;                //KI4+DIG2
  301.                         case 0x5e:WH_display(1,3);break;                //KI4+DIG3
  302.                        
  303.                         case 0x64:WH_display(1,4);break;                //KI5+DIG1
  304.                         case 0x65:WH_display(1,4);break;                //KI5+DIG2
  305.                         case 0x66:WH_display(1,4);break;                //KI5+DIG3
  306.                        
  307.                         case 0x6C:WH_display(1,5);break;                //KI6+DIG1
  308.                         case 0x6d:WH_display(1,5);break;                //KI6+DIG2
  309.                         case 0x6e:WH_display(1,5);break;                //KI6+DIG3
  310.                        
  311.                         case 0x74:WH_display(1,6);break;                //KI7+DIG1
  312.                         case 0x75:WH_display(1,6);break;                //KI7+DIG2
  313.                         case 0x76:WH_display(1,6);break;                //KI7+DIG3
  314.                        
  315.                         /**组合按键**/
  316.                         case 0x7C:WH_display(1,7);break;                //KI1_KI2+DIG1
  317.                         case 0x7d:WH_display(1,7);break;                //KI1_KI2+DIG2
  318.                         case 0x7e:WH_display(1,7);break;                //KI1_KI2+DIG3
  319.                         case 0x7f:WH_display(1,7);break;          //KI1_KI2+DIG4
  320.                        
  321.                         default: break;
  322.                 }
  323. }
复制代码
这个是.C文件


  1.   key001=TM1650_read();
  2.        UART_Send_int(1,"按钮值 =  ",key001,"\r\n");  //IO_GM  elevator_weizhi
  3. //        UART_Send_byte(1,key001);
  4.         TM1650ReadKey();
  5.                  delay(50);
复制代码
这个是应用函数    其中读取按钮值的函数是为了完善应用函数中按钮的按钮值,测试发现不同的数码管数量以及布线,读出来的按钮值和说明书中的并不一致,不过这并不影响实际使用,只需要根据读取的值,更换库文件中的键值即可
但使龙城飞将在,不教胡马度阴山!
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-23 19:48 , Processed in 0.100168 second(s), 42 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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