久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 14428|回復: 10
打印 上一主題 下一主題
收起左側

LED驅動芯片(TM1650)的C51單片機程序例程

  [復制鏈接]
跳轉到指定樓層
樓主
相信大家剛學習單片機的時候都用過數碼管,那時候的數碼管都是用單片機的IO口直接驅動的,用軟件進行動態刷新,但是這樣控制數碼管是很占用單片機外部資源的,單片機的外部資源也是有限的,不能全部IO口來進行數碼管的驅動吧。∧怯袥]有專門的驅動芯片驅動呢?答案是有的,他就是LED驅動芯片,這里就以天微電子TM1650來做講解吧!

首先TM1650是IIC通訊協議的,沒錯他只要兩個單片機IO口就能控制4位數碼管的顯示,分別是SCL(時鐘線)和SDA(數據線)進行數據的傳輸


IIC串口協議
開始信號:保持 SCL 為“1”電平,SDA 從“1”跳“0” ,認為是開始信號
結束信號:保持 SCL 為“1”電平,SDA 從“0”跳“1” ,認為是結束信號
應答:如果本次通訊正常,芯片在串行通訊的第 8 個時鐘下降沿后,TM1650 主動把 SDA 拉低。直到檢
測到 SCL 來了上升沿,SDA 釋放為輸入狀態


我這里用的是單片機硬件IIC時序,你也可以用軟件來進行模擬時序
以下是驅動程序:
  1. #include "main.h"

  2. uint8_t code Num_Buff[16]={ //數碼管共陰真值表0-F
  3.         0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
  4. };

  5. extern void Dis_IIC_Init(void);
  6. extern void Dis_Write_NumData(uint16_t NumDat);
  7. extern void DisPlay_ON(void);
  8. extern void DisPlay_OFF(void);
  9. extern void Dis_Write(uint8_t ADD,uint8_t Dat);
  10. extern void Dis_Write_ERRData(uint8_t ERR_Num);

  11. DisPlay_t DisPlay =
  12. {
  13.         0,
  14.         0,
  15.         Dis_IIC_Init,
  16.         Dis_Write_NumData,
  17.         DisPlay_ON,
  18.         DisPlay_OFF,
  19.         Dis_Write,
  20.         Dis_Write_ERRData
  21. };

  22. //硬件IIC初始化
  23. static void Dis_IIC_Init()
  24. {
  25.         P_SW2 = 0xB0;     //IIC引腳切換至P32,P33引腳及使能特殊功能寄存器(XFR)
  26.         IP2 = 0x40;              //設置優先級為較低級優先級,定時器0為最低級優先級,IIC優先級高于定時器0優先級
  27.         IP2H = 0x00;      //設置優先級為較低級優先級,定時器0為最低級優先級,IIC優先級高于定時器0優先級
  28.         I2CCFG &= 0x00;   //清零
  29.         I2CCFG |= 0xC2;   //使能IIC功能,主機模式,8分頻,總線速度=FOSC/2/(分頻系數*2+4)
  30.         I2CMSCR &= 0x00;  //清零
  31.         I2CMSCR |= 0x80;  //使能IIC主機模式中斷               
  32. }

  33. //起始信號
  34. static void IIC_Start()   
  35. {
  36.         DisPlay.IIC_Send_Time = TRUE;
  37.         I2CMSCR |= 0x81;
  38.         while(DisPlay.IIC_Send_Time);
  39. }

  40. //發送停止
  41. static void IIC_Stop()     
  42. {
  43.         DisPlay.IIC_Send_Time = TRUE;
  44.         I2CMSCR |= 0x86;
  45.         while(DisPlay.IIC_Send_Time);
  46. }

  47. //發送應答
  48. static void IIC_ACk()
  49. {
  50.         DisPlay.IIC_Send_Time = TRUE;
  51.         I2CMSCR |= 0x83;
  52.         while(DisPlay.IIC_Send_Time);
  53. }

  54. //發送一個字節
  55. static void IIC_Write_Byt(uint8_t d)
  56. {
  57.         I2CTXD = d;
  58.         DisPlay.IIC_Send_Time = TRUE;
  59.         I2CMSCR |= 0x82;
  60.         while(DisPlay.IIC_Send_Time);
  61. }

  62. //發送數據操作
  63. static void Dis_Write(uint8_t ADD,uint8_t Dat)
  64. {
  65.         IIC_Start();
  66.         IIC_Write_Byt(ADD);
  67.         IIC_ACk();
  68.         IIC_Write_Byt(Dat);
  69.         IIC_ACk();
  70.         IIC_Stop();
  71. }

  72. static void DisPlay_ON()
  73. {
  74.         Dis_Write(0x48,0x41);  //0x41為四級亮度,8段碼顯示方式,開顯示
  75. }

  76. static void DisPlay_OFF()
  77. {
  78.         Dis_Write(0x48,0x40);  //關顯示
  79. }

  80. //數據顯示處理函數
  81. static void Dis_Write_NumData(uint16_t NumDat)
  82. {
  83. //        Dis_Write(0x48,0x41);  //0x41為四級亮度,8段碼顯示方式,開顯示
  84.         Dis_Write(0x68,Num_Buff[NumDat/100%10]);   //取出顯示百位
  85.         if(DisPlay.Therm_Fa == 0)
  86.         {
  87.                 Dis_Write(0x6A,Num_Buff[NumDat/10%10]+0x80);    //取出顯示十位
  88.                 Dis_Write(0x6C,Num_Buff[NumDat%10]&0x7F);       //取出顯示個位
  89.         }
  90.         else
  91.         {
  92.                 Dis_Write(0x6A,Num_Buff[NumDat/10%10]&0x7F);    //取出顯示十位
  93.                 Dis_Write(0x6C,Num_Buff[NumDat%10]+0x80);       //取出顯示個位
  94.         }
  95. }

  96. static void Dis_Write_ERRData(uint8_t ERR_Num)
  97. {
  98.         Dis_Write(0x68,Num_Buff[14]);   
  99.         Dis_Write(0x6A,Num_Buff[ERR_Num]&0x7F);
  100.         Dis_Write(0x6C,0x00);
  101. }

  102. //I2C中斷服務函數
  103. void IIC_interrupt() interrupt 24
  104. {
  105.         if(I2CMSST & 0x40)
  106.         {
  107.                 I2CMSST &= 0xBF;  //清除中斷標志位
  108.                 DisPlay.IIC_Send_Time = FALSE;
  109.                 I2CMSCR &= 0x80;  //除了最高不變,其他位清零,為下次發送做準備
  110.         }
  111. }
復制代碼

評分

參與人數 1黑幣 +60 收起 理由
admin + 60 回帖助人的獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏21 分享淘帖 頂3 踩
回復

使用道具 舉報

沙發
ID:319585 發表于 2021-7-25 12:38 來自手機 | 只看該作者
這個1650不錯的,還可以做按鍵輸入,用起來非常方便。我用這個做過一個數碼管顯示+按鍵輸入的程序。
回復

使用道具 舉報

板凳
ID:88023 發表于 2021-7-25 16:24 | 只看該作者
liesnake 發表于 2021-7-25 12:38
這個1650不錯的,還可以做按鍵輸入,用起來非常方便。我用這個做過一個數碼管顯示+按鍵輸入的程序。

是的,他還有按鍵輸入的功能,但是我很少用,我們的產品用觸摸的比較多,用按鍵的比較少,基本上就是用來驅動數碼管用的多一點
回復

使用道具 舉報

地板
ID:884711 發表于 2022-8-30 10:22 | 只看該作者
這個1650不錯,按鍵+數顯,用起來非常方便。
回復

使用道具 舉報

5#
ID:337139 發表于 2022-9-12 16:57 | 只看該作者
TM1650在數碼管的驅動是很有優勢的。
回復

使用道具 舉報

6#
ID:472504 發表于 2022-9-20 08:38 | 只看該作者
請問結構體前兩個0是干嘛的啊
回復

使用道具 舉報

7#
ID:16255 發表于 2022-9-20 10:56 | 只看該作者
我也曾經用TM1650做過一個小時鐘
http://www.zg4o1577.cn/bbs/dpj-121550-1.html
回復

使用道具 舉報

8#
ID:16255 發表于 2022-9-20 11:17 | 只看該作者
請注意!

TM1650并不是完完全全的I2C器件,只是指令與I2C類同而已,也不能與I2C器件裝在同一線路上的。
回復

使用道具 舉報

9#
ID:16255 發表于 2022-9-20 11:21 | 只看該作者
本帖最后由 mengsiu 于 2022-9-20 11:25 編輯

發一段我以前寫的TM1650的驅動程序:
  1. /*--------------------------------------------------------------------------
  2. TM1650.H
  3. 四位數碼管驅動 TM1650 讀寫程序
  4. --------------------------------------------------------------------------*/
  5. #ifndef __TM1650_H__
  6. #define __TM1650_H__

  7. sbit CLK = P3^7;
  8. sbit DIO = P3^6;

  9. void Set1650(uchar add,uchar dat);
  10. uchar Scan_Key(void);

  11. uchar BL = 1;          //亮度等級
  12. uchar CODE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //0~9顯示代碼
  13.                                 // 0    1    2    3    4    5    6    7    8    9

  14. void Init1650(){
  15.         Set1650(0x48,(BL*16+0x01));//設定亮度,開顯示八段顯示方式,后一個字節中高位用于亮度,低位用于七段或八段顯示方式和開關顯
  16.                                                                 //如:0x71為七級亮度,八段顯示方式,開顯示;0x79為為七級亮度,七段顯示方式,開顯示
  17. }

  18. void Delay_us(uint i){ //us延時
  19.         for(;i>0;i--){
  20.                 _nop_();
  21.                 _nop_();
  22.                 _nop_();
  23.                 _nop_();
  24.                 _nop_();
  25.         }
  26. }

  27. void Start1650(void){//開始信號
  28.         CLK = 1;
  29.         DIO = 1;
  30.         Delay_us(5);
  31.         DIO = 0;
  32. }

  33. void Ask1650(void){ //ACK信號
  34.         uchar timeout = 1;
  35.         CLK = 1;
  36.         Delay_us(5);
  37.         CLK = 0;
  38.         while((DIO)&&(timeout<=100)){
  39.                 timeout++;
  40.         }
  41.         Delay_us(5);
  42.         CLK = 0;
  43. }

  44. void Stop1650(void){ //停止信號
  45.         CLK = 1;
  46.         DIO = 0;
  47.         Delay_us(5);
  48.         DIO = 1;
  49. }

  50. void WrByte1650(uchar oneByte){//寫一個字節高位在前,低位在后
  51.         uchar i;
  52.         CLK = 0;
  53.         Delay_us(1);
  54.         for(i=0;i<8;i++){
  55.                 oneByte = oneByte<<1;
  56.                 DIO = CY;
  57.                 CLK = 0;
  58.                 Delay_us(5);
  59.                 CLK = 1;
  60.                 Delay_us(5);
  61.                 CLK = 0;
  62.         }
  63. }

  64. uchar Scan_Key(void){  // 按鍵掃描
  65.         uchar i;
  66.         uchar rekey;
  67.         Start1650();
  68.         WrByte1650(0x49);//讀按鍵命令
  69.         Ask1650();
  70.         //DIO = 1;
  71.         for(i=0;i<8;i++){
  72.                 CLK = 1;
  73.                 rekey = rekey<<1;
  74.                 if(DIO){
  75.                 rekey++;
  76.                 }
  77.                 Delay_us(5);
  78.                 CLK = 0;
  79.         }
  80.         Ask1650();
  81.         Stop1650();
  82.         return(rekey);
  83. }

  84. void Set1650(uchar add,uchar dat){ //數碼管顯示
  85.                                                                 //寫顯存必須從高地址開始寫
  86.         Start1650();
  87.         WrByte1650(add); //第一個顯存地址
  88.         Ask1650();
  89.         WrByte1650(dat);
  90.         Ask1650();
  91.         Stop1650();
  92. }

  93. #endif
復制代碼


回復

使用道具 舉報

10#
ID:388361 發表于 2022-11-9 11:10 | 只看該作者
目前在用TM1650設計案子,學習中
回復

使用道具 舉報

11#
ID:59884 發表于 2023-8-17 13:41 | 只看該作者
請問樓主程序中DisPlay_t是什么?C++的關鍵字嗎?keil編譯不了。其實我一直很想吐槽國內編程論壇環境,放程序,基本都只放一段,或者根本沒法運行的程序,或者編譯好的固件。這樣下來,編程技術好的人,根本不屑看。而基礎差想學習的人看了,也很難弄得明白。而像Git Hub這樣的論壇,基本上放的開源源程序都是完整的,能編譯運行的,而且基本上注釋也都比較詳細。但也有很多國人,放上去的程序,大部分是無法直接編譯運行的,或只有編譯出的固件。這樣干是想說明自己水平高嗎?說實在的,如果實在怕別人學去了,可以不分享。也許只有他們明白,很多東西只有互相學習才會快速提升。我在此聲明,我此番話,不是針對樓主。只是表達對目前編程論壇,共享學習環境現狀的不滿!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: av一级 | 中文字幕国产高清 | 日韩伦理电影免费在线观看 | 亚洲国产精品99久久久久久久久 | 日韩成人免费av | 日韩中文字幕在线播放 | 亚洲国产精品久久久 | 免费一级黄色录像 | 亚洲精品粉嫩美女一区 | 天天色av | 久久久爽爽爽美女图片 | japanhdxxxx裸体 | 欧美一区二区三区的 | 亚洲视频免费观看 | 成人做爰9片免费看网站 | jizz在线免费观看 | 亚洲午夜av | 亚洲一区二区三区视频 | 成年视频在线观看福利资源 | 自拍 亚洲 欧美 老师 丝袜 | 日本视频一区二区三区 | 97超在线视频 | 国产精品高 | 亚洲视频免费一区 | 国产精品久久久久久久久久久久久 | 中文字幕高清一区 | 无码一区二区三区视频 | 国产精品久久久久久久午夜片 | 免费国产一区二区视频 | 女同久久另类99精品国产 | аⅴ资源新版在线天堂 | 亚洲+变态+欧美+另类+精品 | 一二三四av | 国产精品中文字幕在线 | 日韩午夜激情 | 99在线精品视频 | 国产欧美精品一区 | 99久久精品一区二区毛片吞精 | 99re热精品视频 | 91久久精品一区 | 国产激情亚洲 |