#include <reg52.h> #define uint unsigned int #define uchar unsigned char sbit DIO = P1^4; sbit R_CLK = P1^3; sbit S_CLK = P1^2; //uint num; uchar code smgduan[] = {0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0xfd,0xff,0xfe}; uchar code smgwei[] = {0x10,0x20,0x40,0x80}; void display(uint num) { uchar i, duan, wei; static uchar WEI; switch(WEI){ case 0 : duan = smgduan[num / 1000 % 10]; break; //千位 case 1 : duan = smgduan[num / 100 % 10]; break; case 2 : duan = smgduan[num / 10 % 10]; break; case 3 : duan = smgduan[num % 10]; break; //个位 } for(i = 0; i < 8; i ++){ S_CLK = 0; R_CLK = 0; if(duan & 0x01) DIO = 1; else DIO = 0; S_CLK = 1; duan >>= 1; //从最低位读入 } wei = smgwei[WEI]; for(i = 0; i < 8; i ++){ S_CLK = 0; R_CLK = 0; if(wei & 0x01) DIO = 1; else DIO = 0; S_CLK = 1; wei >>= 1; } R_CLK = 1; WEI ++; if(WEI == 4) WEI = 0; } void timer0Init() //定时器0初始化 { EA = 1; //打开总中断 ET0 = 1;//打开定时器0中断 TR0 = 1; //启动定时器0 TMOD |= 0X01; //定时器工作模式1,16位定时模式 TH0 = 0xED; TL0 = 0xFF; //定时5ms } void main() { timer0Init(); while(1); } void timer0() interrupt 1 //定时器中断服务函数 { TH0 = 0xED; TL0 = 0xFF; //定时5ms display(6666); }
采用定时器中断0扫描4位数码管。
用到了static的定义。
通过对74HC595的写入控制数码管,
只用3个IO口即可实现控制。
如果需要8位数码管只要把两个4位数码管级联起来就行了。
但是仍然只需要3个IO口即可实现。
这个程序将靠近接线端的数码管作为最高位。
远离接线端的是最低位。
经过测试,我手中的数码管第一个595是控制位选的。第二个是控制段的。
所以先传入位段数据。
/*第一个传入的dat管理段选(级联的第二片595)
第二个传入的dat管理位选(第一片595)
当第二个dat传入0xff时全部点亮
传入0xe0(1110 0000)接线端的灭
传入0xd0(1101 0000)接线端向右数第二个灭
总结位选:0x10(0001 0000)最左边(接线端)的亮
0x20(0010 0000)
0x40(0100 0000)
0x80(1000 0000)最右边的亮
总结段选:0x00(0000 0000)全亮 0电表亮
0x01(0000 0001)dp不亮
0x03(0000 0011)db,g不亮
0x70(0000 0111)dp,g,f不亮
0000 0011 0
1001 1111 1
0010 0101 2
0000 1101 3
1001 1001 4
0100 1001 5
0100 0001 6
0001 1111 7
0000 0001 8
0000 1001 9
1111 1101 -
1111 1111 息屏
1111 1110 .
0 0 0 0 0 0 0 0
a b c d e f g dp
*/
uchar code smgduan[] = {0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0xfd,0xff,0xfe}; uchar code smgwei[] = {0x10,0x20,0x40,0x80};
原文:https://www.cnblogs.com/Brimon-zZY/p/13994540.html