本帖最后由 WL0123 于 2026-3-30 22:07 編輯
極簡的單排5腳188數碼管的驅動方法試探
在一些低檔消費電子產品中常見一種單排5腳188和單排6腳1888數碼管。由于這種數碼管內部結構異于常見的數碼管。商家提供的內部LED與引腳關系圖看上去也感覺雜亂無章。仔細研究一番其實就是一種矩陣連接關系,以單排5腳188為例,將原圖重新排列一下就可以明顯看出來就是一種共陰關系。一次最多可以點亮4個筆段。如果單片機引腳直接連接數碼管有過流損壞單片機端口的風險,如果數碼管每個腳接限流電阻,由于需要點亮的筆段不確定,隨亮點多少不同亮度會不均勻,為此利用新型單片機端口的高阻模式和內置上拉電阻,按需要點亮的筆段使能上拉電阻提供驅動電流。作為當前用作共陰的端口設準雙向模式低電平,不論需要點亮的筆段多少,各筆段亮度一致。5腳188數碼管共16個筆段,需要分4次才能完成全部筆段掃描。由此制作一個表格,將8位標準段碼拆解為5位驅動碼。實踐證明:數碼管亮度能夠滿足大多數應用場景,并且無鬼影。還有其他更簡潔的驅動方式,歡迎壇友探討。
無標題1.jpg (113.35 KB, 下載次數: 0)
下載附件
2026-3-30 21:51 上傳
無標題2.jpg (65.74 KB, 下載次數: 0)
下載附件
2026-3-30 21:52 上傳
無標題3.jpg (109.48 KB, 下載次數: 0)
下載附件
2026-3-30 21:52 上傳
- //5腳188數碼管驅動程序示例
- //使用STC8H1K08單片機
- #include <STC8H.H>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar code table[]={ //數碼管段碼0~f
- 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- uint count; //計數
- uchar num; //計數
- uchar w1,w2,w3; //數碼管位
- bit flag; //中斷標志
- void Timer0_Init(); //初始化定時器0
- void display(); //顯示函數
- //主函數
- void main()
- {//端口模式初始化
- P1M0 = 0x00;P1M1 = 0x00;//準雙向
- P3M0 = 0x00;P3M1 = 0x00;//準雙向
- P5M0 = 0x00;P5M1 = 0x00;//準雙向
- P_SW2 |= 0x80; //打開擴展存儲器
- Timer0_Init(); //初始化定時器0
- while(1)
- {
- if(flag)
- {
- flag=0; //周期5ms
- display(); //顯示函數
- if(++count>=100) //0.5s
- {
- count=0;
- if(++num>188)num=0;
- if(num>=100)w1=table[1];
- else w1=0x00;
- w2=table[num/10%10];
- w3=table[num%10];
- }
- }
- }
- }
- void Timer0_Isr(void) interrupt 1
- {
- flag=1;
- }
- void Timer0_Init(void) //5毫秒@11.0592MHz
- {
- AUXR |= 0x80; //定時器時鐘1T模式
- TMOD &= 0xF0; //設置定時器模式
- TL0 = 0x00; //設置定時初始值
- TH0 = 0x28; //設置定時初始值
- TF0 = 0; //清除TF0標志
- TR0 = 1; //定時器0開始計時
- ET0 = 1; //使能定時器0中斷
- EA = 1; //使能總中斷
- }
- //數碼管顯示函數
- void display()
- {
- static uchar i=0;
- uchar a[4];
- switch(i)
- {/******************5位***********4位**********3位**********2位**********1位***********/
- case 0: a[0]=(w3>>2&0x10)|(w3>>2&0x08)|(w3>>1&0x04)|(w3<<0&0x02)|(0 /*COM1*/); break;
- case 1: a[1]=(w2>>0&0x10)|(w2<<0&0x08)|(w2<<1&0x04)|(0 /*COM2*/)|(w3>>0&0x01); break;
- case 2: a[2]=(w2>>1&0x10)|(w2<<1&0x08)|(0 /*COM3*/)|(w2<<1&0x02)|(w3>>2&0x01); break;
- case 3: a[3]=(w2>>2&0x10)|(0 /*COM4*/)|(w1<<1&0x04)|(w1>>1&0x02)|(w3>>4&0x01); break;
- }
- P1M1=~(0x01<<i)&0x1f; //P1.0~1.3輪流高阻轉準雙向
- P1PU=a[i]; //按位使能上拉電阻提供高電平驅動電流,代替端口寄存器高電平
- P1=a[i]; //按COM位提供低電平共地驅動電流,其它位為高阻模式,高低電平無關
- i=++i%4; //循環計數
- }
復制代碼
|