* +---------------------------------------------------+ *
* | 7X25點陣顯示顯示實時移動時鐘 | *
* +---------------------------------------------------+ *
* *
* 此源碼版權屬 小牛 全權享有,如欲引用,敬請署名並告知 *
* 嚴禁隨意用於商業目的,違者必究,後果自負 *
* Q Q:513696765 *
* *
* 運行環境:STC89C52單片機 12M晶振 *
* 程序說明: *
**************************************************************/
#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
char a,b,c,sec=56,min=34,
hour=12,sec1,sec2,min1,min2,hour1,hour2,
sec11,sec22,min11,min22,hour11,hour22,temp;
int k,n,m; //定義K用於計算移動字符的位數(如果移動的位數比較多請把K定義為int型否則可能有亂碼)
uchar taxe[94]; //定義壹個變量數組載入,sec1,sec2,min1,min2,hour1,hour2的字模
sbit sclk=P3^4; //定義74HC595的時鐘口上升沿寫入數據
sbit rclk=P3^5; //定義74HC595的輸出時鐘口
sbit ser=P3^6; //定義74HC595的數據輸入口上升沿輸出數據
/********數字0—9,年,月,日 的字模數組*********/
char code table[14][8]=
{
{0x7c,0x8a,0x92,0xa2,0x7c,0x00,0x00,0x00,},//0
{0x00,0x42,0xfe,0x02,0x00,0x00,0x00,0x00,},//1
{0x42,0x86,0x8a,0x92,0x62,0x00,0x00,0x00,},//2
{0x84,0x82,0xa2,0xd2,0x8c,0x00,0x00,0x00,},//3
{0x18,0x28,0x48,0xfe,0x08,0x00,0x00,0x00,},//4
{0xe4,0xa2,0xa2,0xa2,0x9c,0x00,0x00,0x00,},//5
{0x3c,0x52,0x92,0x92,0x0c,0x00,0x00,0x00,},//6
{0x80,0x8e,0x90,0xa0,0xc0,0x00,0x00,0x00,},//7
{0x6c,0x92,0x92,0x92,0x6c,0x00,0x00,0x00,},//8
{0x60,0x92,0x92,0x94,0x78,0x00,0x00,0x00,},//9
{0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x24,0x5c,0xd4,0x7e,0x54,0x00,0x00,0x00,},//年
{0x02,0xfc,0xa8,0xaa,0xfe,0x00,0x00,0x00,},//月
{0xfe,0x92,0x92,0x92,0xfe,0x00,0x00,0x00,},//日
};
/*定義每次掃描行的數組兼用於每次模擬串口發送的字模的行值*/
char code yu[]=
{
0x80,0x40,0x20,0x10,
0x08,0x04,0x02,0x01,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
};
void delay(char xms)
{
char i,j;
for(i=0;i<xms;i++)
for(j=0;j<110;j++);
}
/***********取數函數********/
/*把sec1,sec2,min1,min2,hour1,hour2的字模依次放到taxe[]的變量數組中*/
void qushu()
{
hour1=hour / 10;
hour2=hour % 10;
min1=min / 10;
min2=min % 10;
sec1=sec / 10;
sec2=sec % 10;
for(temp=0;temp<24;temp++) //用於清屏
{
taxe[temp]=0x00;
}
for(hour11=0;hour11<5;hour11++)
{
taxe[hour11+25]=table[hour1][hour11]; //把時的第壹位的7個字模放到taxe[]的0-6位
}
for(hour22=0;hour22<5;hour22++)
{
taxe[hour22+31]=table[hour2][hour22]; //把時的第二位的7個字模放到taxe[]的7-13位
}
for(temp=0;temp<3;temp++)
{
taxe[temp+37]=table[10][temp];
}
for(min11=0;min11<5;min11++)
{
taxe[min11+41]=table[min1][min11]; //把分的第壹位的7個字模放到taxe[]的14-20位
}
for(min22=0;min22<5;min22++)
{
taxe[min22+47]=table[min2][min22]; //把時的第二位的7個字模放到taxe[]的21-27位
}
for(temp=0;temp<3;temp++)
{
taxe[temp+53]=table[10][temp];
}
for(sec11=0;sec11<5;sec11++)
{
taxe[sec11+57]=table[sec1][sec11]; //把秒的第壹位的7個字模放到taxe[]的28-34位
}
for(sec22=0;sec22<5;sec22++)
{
taxe[sec22+63]=table[sec2][sec22]; //把時的第二位的7個字模放到taxe[]的35-41位
}
for(temp=0;temp<24;temp++) //用於清屏
{
taxe[temp+69]=0x00;
}
}
void shizhong()
{
sec++;
if(sec>=60)
{
sec=0;
min++;
if(min>=60)
{
min=0;
hour++;
if(hour>=24)
{
hour=0;
}
}
}
}
void main()
{
TMOD=0X01;
TH0=0X3C;
TL0=0XB0;
EA=1;
ET0=1;
TR0=1;
while(1)
{
for(c=0;c<60;c++) //用於調節字符流動快慢
{
P1=0xff; //點陣消影
for(b=24;b>0;b--) //因為用了3塊74HC595級聯所以每壹行要用模擬串口發送24位數據
{
sclk=0; //74HC595的上升沿才能寫入數據所以先拉低電平
_nop_();
_nop_();
if(taxe[b+k]&yu[a]) //發送某壹行的數據
ser=1; //如果字模中的某壹個這壹行為1就寫1入數據否則寫入0
else
ser=0; //寫0入數據
sclk=1; //拉高電平產生上升沿寫入數據
_nop_();
_nop_();
}
rclk=0; //拉低74HC595的數據輸入口的電平等待上升沿把數據輸出
_nop_();
_nop_();
rclk=1; //拉高74HC595的數據輸入口的電平產生上升沿
_nop_();
_nop_();
rclk=0; //拉低74HC595的數據輸入口的電平鎖存數據
P1=~yu[a+1]; //行選(低電平有效)
delay(5);
a++;
if(a>6)
a=0;
}
a=0;
k++; //定義K用於計算移動字符的位數
if(k>=70) //如果字符移完了賦0重新開始
{
k=0;
}
}
}
void T0_TIME()interrupt 1
{
TH0=0X3C;
TL0=0XB0;
n++;
if(n>=10)
{
n=0;
qushu();
m++;
{
if(m>=2)
{
m=0;
shizhong();
}
}
}
}