|
相信大家剛學(xué)習(xí)單片機(jī)的時(shí)候都用過(guò)數(shù)碼管,那時(shí)候的數(shù)碼管都是用單片機(jī)的IO口直接驅(qū)動(dòng)的,用軟件進(jìn)行動(dòng)態(tài)刷新,但是這樣控制數(shù)碼管是很占用單片機(jī)外部資源的,單片機(jī)的外部資源也是有限的,不能全部IO口來(lái)進(jìn)行數(shù)碼管的驅(qū)動(dòng)吧。∧怯袥](méi)有專門(mén)的驅(qū)動(dòng)芯片驅(qū)動(dòng)呢?答案是有的,他就是LED驅(qū)動(dòng)芯片,這里就以天微電子TM1650來(lái)做講解吧!
首先TM1650是IIC通訊協(xié)議的,沒(méi)錯(cuò)他只要兩個(gè)單片機(jī)IO口就能控制4位數(shù)碼管的顯示,分別是SCL(時(shí)鐘線)和SDA(數(shù)據(jù)線)進(jìn)行數(shù)據(jù)的傳輸
屏幕截圖 2021-07-24 190227.png (71.96 KB, 下載次數(shù): 135)
下載附件
2021-7-24 19:13 上傳
IIC串口協(xié)議
開(kāi)始信號(hào):保持 SCL 為“1”電平,SDA 從“1”跳“0” ,認(rèn)為是開(kāi)始信號(hào)
結(jié)束信號(hào):保持 SCL 為“1”電平,SDA 從“0”跳“1” ,認(rèn)為是結(jié)束信號(hào)
應(yīng)答:如果本次通訊正常,芯片在串行通訊的第 8 個(gè)時(shí)鐘下降沿后,TM1650 主動(dòng)把 SDA 拉低。直到檢
測(cè)到 SCL 來(lái)了上升沿,SDA 釋放為輸入狀態(tài)
我這里用的是單片機(jī)硬件IIC時(shí)序,你也可以用軟件來(lái)進(jìn)行模擬時(shí)序
以下是驅(qū)動(dòng)程序:- #include "main.h"
- uint8_t code Num_Buff[16]={ //數(shù)碼管共陰真值表0-F
- 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
- };
- extern void Dis_IIC_Init(void);
- extern void Dis_Write_NumData(uint16_t NumDat);
- extern void DisPlay_ON(void);
- extern void DisPlay_OFF(void);
- extern void Dis_Write(uint8_t ADD,uint8_t Dat);
- extern void Dis_Write_ERRData(uint8_t ERR_Num);
- DisPlay_t DisPlay =
- {
- 0,
- 0,
- Dis_IIC_Init,
- Dis_Write_NumData,
- DisPlay_ON,
- DisPlay_OFF,
- Dis_Write,
- Dis_Write_ERRData
- };
- //硬件IIC初始化
- static void Dis_IIC_Init()
- {
- P_SW2 = 0xB0; //IIC引腳切換至P32,P33引腳及使能特殊功能寄存器(XFR)
- IP2 = 0x40; //設(shè)置優(yōu)先級(jí)為較低級(jí)優(yōu)先級(jí),定時(shí)器0為最低級(jí)優(yōu)先級(jí),IIC優(yōu)先級(jí)高于定時(shí)器0優(yōu)先級(jí)
- IP2H = 0x00; //設(shè)置優(yōu)先級(jí)為較低級(jí)優(yōu)先級(jí),定時(shí)器0為最低級(jí)優(yōu)先級(jí),IIC優(yōu)先級(jí)高于定時(shí)器0優(yōu)先級(jí)
- I2CCFG &= 0x00; //清零
- I2CCFG |= 0xC2; //使能IIC功能,主機(jī)模式,8分頻,總線速度=FOSC/2/(分頻系數(shù)*2+4)
- I2CMSCR &= 0x00; //清零
- I2CMSCR |= 0x80; //使能IIC主機(jī)模式中斷
- }
- //起始信號(hào)
- static void IIC_Start()
- {
- DisPlay.IIC_Send_Time = TRUE;
- I2CMSCR |= 0x81;
- while(DisPlay.IIC_Send_Time);
- }
- //發(fā)送停止
- static void IIC_Stop()
- {
- DisPlay.IIC_Send_Time = TRUE;
- I2CMSCR |= 0x86;
- while(DisPlay.IIC_Send_Time);
- }
- //發(fā)送應(yīng)答
- static void IIC_ACk()
- {
- DisPlay.IIC_Send_Time = TRUE;
- I2CMSCR |= 0x83;
- while(DisPlay.IIC_Send_Time);
- }
- //發(fā)送一個(gè)字節(jié)
- static void IIC_Write_Byt(uint8_t d)
- {
- I2CTXD = d;
- DisPlay.IIC_Send_Time = TRUE;
- I2CMSCR |= 0x82;
- while(DisPlay.IIC_Send_Time);
- }
- //發(fā)送數(shù)據(jù)操作
- static void Dis_Write(uint8_t ADD,uint8_t Dat)
- {
- IIC_Start();
- IIC_Write_Byt(ADD);
- IIC_ACk();
- IIC_Write_Byt(Dat);
- IIC_ACk();
- IIC_Stop();
- }
- static void DisPlay_ON()
- {
- Dis_Write(0x48,0x41); //0x41為四級(jí)亮度,8段碼顯示方式,開(kāi)顯示
- }
- static void DisPlay_OFF()
- {
- Dis_Write(0x48,0x40); //關(guān)顯示
- }
- //數(shù)據(jù)顯示處理函數(shù)
- static void Dis_Write_NumData(uint16_t NumDat)
- {
- // Dis_Write(0x48,0x41); //0x41為四級(jí)亮度,8段碼顯示方式,開(kāi)顯示
- Dis_Write(0x68,Num_Buff[NumDat/100%10]); //取出顯示百位
- if(DisPlay.Therm_Fa == 0)
- {
- Dis_Write(0x6A,Num_Buff[NumDat/10%10]+0x80); //取出顯示十位
- Dis_Write(0x6C,Num_Buff[NumDat%10]&0x7F); //取出顯示個(gè)位
- }
- else
- {
- Dis_Write(0x6A,Num_Buff[NumDat/10%10]&0x7F); //取出顯示十位
- Dis_Write(0x6C,Num_Buff[NumDat%10]+0x80); //取出顯示個(gè)位
- }
- }
- static void Dis_Write_ERRData(uint8_t ERR_Num)
- {
- Dis_Write(0x68,Num_Buff[14]);
- Dis_Write(0x6A,Num_Buff[ERR_Num]&0x7F);
- Dis_Write(0x6C,0x00);
- }
- //I2C中斷服務(wù)函數(shù)
- void IIC_interrupt() interrupt 24
- {
- if(I2CMSST & 0x40)
- {
- I2CMSST &= 0xBF; //清除中斷標(biāo)志位
- DisPlay.IIC_Send_Time = FALSE;
- I2CMSCR &= 0x80; //除了最高不變,其他位清零,為下次發(fā)送做準(zhǔn)備
- }
- }
復(fù)制代碼
|
評(píng)分
-
查看全部評(píng)分
|