點陣時鐘的視頻效果:
用16X64LED點陣實現翻頁的電子時鐘實物圖:

16X64點陣翻頁時鐘的原理圖(附件里面有清晰版的pdf文件)
0.png (143.21 KB, 下載次數: 132)
下載附件
2017-3-4 03:29 上傳



16*64點陣的單片機源程序:
- /***********************************************************
- 名稱:16*64點陣單紅翻頁時鐘
- 單片機: STC89C52
- 晶振:22.1184M
- 顯示屏: 16*64點陣,標準的08接口,OE高電平有效
- ***********************************************************/
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- #include <REGX52.H>
- #include "DS1302.h"
- #include "DS18B20.h"
- #include "font.h"
- #include "lunar.h"
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- #define ORANGE 0
- #define GREEN 1
- #define RED 2
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- #define H_PORT P0 //ABCD P0
- sbit RData = P0^4;
- sbit OE=P0^5;
- sbit L_STB = P0^6;
- sbit L_CLK = P0^7;
- sbit GData = P3^4;
- sbit key_adj=P3^0;
- sbit key_add=P3^1;
- sbit key_dec=P3^6;
- sbit key_esc=P3^7;
- #include "port.h"
- #define FESTIVAL_MAX 9 //定義農歷節日數
- #define KEY_VAL 5 //定義按鍵手感
- #define set_row(row) {H_PORT=(row&0x0f);}
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- SYSTEMTIME CurrentTime;
- unsigned char status=0; //按鍵狀態
- unsigned char disp_mode=0; //顯示狀態
- unsigned char offset=0; //移動顯示用的變量
- unsigned char disrow=0; //當前掃描行
- unsigned char k=0; //往buff中填的字
- unsigned int t_counter=0,stop_counter=0,stop_time=0;
- unsigned char f1=18,f2=18,f3=18,f4=18,f5=18,f6=18; //18就不會出現剛開始全部翻頁的情況了.
- bit switch_flag=0,stop_bit=0;
- bit one_sec_flag=0,half_sec_flag;
- bit nongli_flag=0,nongli_change_flag=0,festival_flag=0;
- unsigned char temp_time[6]; //翻頁鐘用到
- unsigned char color = 0;
- bit add_flag=0;
- bit dec_flag=0;
- bit adj_flag=0;
- bit esc_flag=0;
- unsigned char ka=0,kb=0,kc=0,kd=0; //按鍵用
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- unsigned char date[]=
- {
- 10,10,10,10,10,10,10,10, //開頭8個空格
- 2,0, //21世紀
- 1,2, //年數據 No.10,11
- 49,50, //“年”
- 0,1, //月數據 No.14,15
- 51,52, //“月”
- 0,1, //日數據 No.18,19
- 53,54, //“日”
-
- 10, //空格
-
- 55,56,57,58, //“星期”
- 53,54, //星期幾 No.27,28
-
- 10, //空格
-
- 0,0, //小時數據 No.30,31
- 11, // : No.32
- 0,0, //分鐘數據 No.33,34
- 11, // : No.35
- 0,0, //秒數據 No.36,37
-
- 10, //空格
-
- 10,10,10,12,10,13,14, //溫度 No.39,40,41,43
-
- 10,10,10,10,10,10,10,10, //MAX No.53
- };
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- unsigned char code mode[4]={0,1,7,8}; //幾種顯示模式的排列,依次為
- //0:流動顯示年月日+固定一段時間翻頁鐘
- //1:翻頁鐘
- //7:全部流動顯示
- //8:溫度
- unsigned char code moon_date[48]=
- {
- 10,10,10,10,10,10,10,10, //開頭8個空格
- 10,10, //No.8,9
- 10,10, //No.10,11
- 49,50, //“年”
- 10,10, //No.14,15
- 10,10, //No.16,17
- 51,52, //“月”
- 10,10, //No.20,21
- 10,10, //No.22,23
- 10,10,10,10,10,10,10,10, //開頭8個空格
- 10,10,10,10,10,10,10,10, //開頭8個空格
- 10,10,10,10,10,10,10,10, //MAX No.47
- };
- unsigned char code init_date[]=
- {
- 10,10,10,10,10,10,10,10, //開頭8個空格
- 2,0, //21世紀
- 1,2, //年數據 No.10,11
- 49,50, //“年”
- 0,1, //月數據 No.14,15
- 51,52, //“月”
- 0,1, //日數據 No.18,19
- 53,54, //“日”
-
- 10, //空格
-
- 55,56,57,58, //“星期”
- 53,54, //星期幾 No.27,28
-
- 10, //空格
-
- 0,0, //小時數據 No.30,31
- 11, // : No.32
- 0,0, //分鐘數據 No.33,34
- 11, // : No.35
- 0,0, //秒數據 No.36,37
-
- 10, //空格
-
- 10,10,10,12,10,13,14, //溫度 No.39,40,41,43
-
- 10,10,10,10,10,10,10,10, //MAX No.53
- };
- unsigned char code week_data[]={0,25,27,29,31,33,35,53}; //一二三四五六日
- unsigned char code moon_data1[]={45,43,47,29}; //初十廿卅
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- void delay_nms(unsigned int count);
- void Timer_init(void);
- void time_to_buff_all(void);
- void update_buff(void);
- void key_scan(void);
- void display(unsigned char mode);
- void shutter_clock(void);
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- void main(void)
- {
- Initial_DS1302();
- time_to_buff_all();
- ReadTemperature(&date,39);
- Timer_init();
-
- while(1)
- {
- update_buff();
-
- for(disrow=0;disrow<16;disrow++) //disrow,當前掃描的行
- {
- //////////////////////////////////////////
- display(disp_mode);
- OE=0; //關顯示屏
- L_STB=1;
- L_STB=0;
- set_row(disrow);//行138的輸出.依次點亮1~16行.
- OE=1; //開顯示屏
- delay_nms(1); //此處延時,可以省略,
- //////////////////////////////////////////////////////////
- }
- if(stop_counter>stop_time)
- {
- disp_mode=0;
- offset++;
- stop_counter=0;
- stop_bit=0;
- }
- if(stop_bit==0) offset++;
- if(disp_mode==1)
- {
- if(f1<200) f1++;
- if(f2<200) f2++;
- if(f3<200) f3++;
- if(f4<200) f4++;
- if(f5<200) f5++;
- if(f6<200) f6++;
- }
- if(nongli_flag==0) key_scan(); //顯示農歷時調整會出現錯誤,圖省力屏蔽了
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- void Timer_init(void)
- {
- EA=0;
- ET0=1; //開定時器中斷
- TMOD=0x01; //定時器0模式1
- // TH0=0x3c; //24M晶振 25ms中斷
- // TL0=0xb0;
- TH0=0x4c; //22.1148M晶振 25ms中斷
- TL0=0x07;
- TR0=1; //開定時器運行
- EA=1;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- void T0_ISR(void) interrupt 1 using 3 //定時器中斷
- {
- // TH0=0x3c; //24M晶振 25ms中斷
- // TL0=0xb0;
- TH0=0x4c; //22.1148M晶振 25ms中斷
- TL0=0x07;
- t_counter++;
- if(t_counter==20) half_sec_flag=1;
- if(t_counter==40) {t_counter=0;one_sec_flag=1;}
- if(stop_bit==1) stop_counter++;
-
- if(ka!=0)
- {
- ka--;
- if(ka==0 && key_add==0) add_flag=1;
- }
- else if(key_add==0)ka=KEY_VAL;
-
- if(kb!=0)
- {
- kb--;
- if(kb==0 && key_dec==0) dec_flag=1;
- }
- else if(key_dec==0)kb=KEY_VAL;
-
- if(kc!=0)
- {
- kc--;
- if(kc==0 && key_adj==0) adj_flag=1;
- }
- else if(key_adj==0)kc=KEY_VAL;
-
- if(kd!=0)
- {
- kd--;
- if(kd==0 && key_esc==0) esc_flag=1;
- }
- else if(key_esc==0)kd=KEY_VAL;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- void update_buff(void)
- {
- unsigned char i;
- if(nongli_change_flag==1)
- {
- if(nongli_flag==1)
- {
- for(i=0;i<46;i++)
- date[i]=moon_date[i];
-
- DS1302_GetTime_ALL(&CurrentTime);
- festival_flag = GetSolar(CurrentTime.Year,CurrentTime.Month,CurrentTime.Day,&date,26);
- DS1302_GetTime_ALL(&CurrentTime);
- Color(&color,CurrentTime.Hour);
- getLunar(&CurrentTime);
-
- date[8]= (CurrentTime.Year+100-84)%10*2+61; //從"甲"開始
- date[9]= (CurrentTime.Year+100-84)%10*2+62;
- date[10]=(CurrentTime.Year+100-84)%12*2+81; //從"子"開始
- date[11]=(CurrentTime.Year+100-84)%12*2+82;
-
- if(CurrentTime.Month<11) //不顯示為“零一月”
- {
- if(CurrentTime.Month==1)
- {
- date[14]=59; //"正"
- date[15]=60;
- }
- else if(CurrentTime.Month==10)
- {
- date[14]=43; //"十"
- date[15]=44;
- }
- else
- {
- date[14]=CurrentTime.Month%10*2+23; //月個位
- date[15]=CurrentTime.Month%10*2+24; //
- }
- date[16]=51;
- date[17]=52; //"月"
-
- switch(CurrentTime.Day)
- {
- case 10:
- date[18]=45; //"初"
- date[19]=46;
- date[20]=43; //"十"
- date[21]=44;
- break;
-
- case 20:
- date[18]=27; //"廿"
- date[19]=28;
- date[20]=43; //"十"
- date[21]=44;
- break;
-
- case 30:
- date[18]=29; //"卅"
- date[19]=30;
- date[20]=43; //"十"
- date[21]=44;
- break;
-
- default:
- date[18]=moon_data1[CurrentTime.Day/10]; //日十位
- date[19]=moon_data1[CurrentTime.Day/10]+1; //
- date[20]=CurrentTime.Day%10*2+23; //日個位
- date[21]=CurrentTime.Day%10*2+24; //
- break;
- }
- date[22]=10;
- date[23]=10;
- }
- else
- {
- date[14]=43; //"十"
- date[15]=44; //
- date[16]=CurrentTime.Month%10*2+23; //月個位
- date[17]=CurrentTime.Month%10*2+24; //
- switch(CurrentTime.Day)
- {
- case 10:
- date[20]=45; //"初"
- date[21]=46;
- date[22]=43; //"十"
- date[23]=44;
- break;
-
- case 20:
- date[20]=27; //"廿"
- date[21]=28;
- date[22]=43; //"十"
- date[23]=44;
- break;
-
- case 30:
- date[20]=29; //"卅"
- date[21]=30;
- date[22]=43; //"十"
- date[23]=44;
- break;
-
- default:
- date[20]=moon_data1[CurrentTime.Day/10]; //日十位
- date[21]=moon_data1[CurrentTime.Day/10]+1; //
- date[22]=CurrentTime.Day%10*2+23; //日個位
- date[23]=CurrentTime.Day%10*2+24; //
- break;
- }
- }
- nongli_change_flag=0;
- }
- else
- {
- for(i=0;i<48;i++)
- date[i]=init_date[i];
-
- time_to_buff_all();
- nongli_change_flag=0;
- }
- }
-
- if(half_sec_flag==1&&nongli_flag==0) //0.5S
- {
- half_sec_flag=0;
- time_to_buff_all();
- switch(status)
- {
- case 0:
- break;
- case 1:
- date[10]=15,date[11]=15;
- break;
- case 2:
- date[14]=15,date[15]=15;
- break;
- case 3:
- date[18]=15,date[19]=15;
- break;
- case 4:
- date[27]=15,date[28]=15;
- break;
- case 5:
- date[30]=15,date[31]=15;
- break;
- case 6:
- date[33]=15,date[34]=15;
- break;
- case 7:
- date[36]=15,date[37]=15;
- break;
- default:
- break;
- }
- }
- if(one_sec_flag==1&&nongli_flag==0) //1.0S
- {
- one_sec_flag=0;
-
- if((disp_mode==8||k==0)&&nongli_flag==0) ReadTemperature(&date,39);
- date[32]=11;
- date[35]=11;
- time_to_buff_all();
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- void display(unsigned char mode) //送顯示數據
- {
- unsigned char i;
- switch(mode)
- {
- case 0: //流動暫停顯示
- if(switch_flag==1) {k=0;switch_flag=0;}
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[k+i]][disrow]);
- Send2Byte(color,a[date[k+8]][disrow],offset);
- if(offset==8)
- {
- offset=0;k++;
- if(k==30&&nongli_flag==0) {stop_bit=1,stop_time=900,disp_mode=1;} //到了時間的時候停一下。
- if(k==39&&nongli_flag==0) {stop_bit=1,stop_time=100;} //溫度也停一下下。
- if(k>45&&nongli_flag==0)
- {
- k=0;
- nongli_flag=~nongli_flag;
- nongli_change_flag=1;
- }
- if(k>24&&festival_flag==0&&nongli_flag==1)
- {
- k=0;
- nongli_flag=~nongli_flag;
- nongli_change_flag=1;
- }
- else if(k>30&&festival_flag==1&&nongli_flag==1)
- {
- k=0;
- nongli_flag=~nongli_flag;
- nongli_change_flag=1;
- }
- }
- break;
-
- case 7: //全部流動顯示
- if(switch_flag==1) {k=0;switch_flag=0;}
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[k+i]][disrow]);
- Send2Byte(color,a[date[k+8]][disrow],offset);
- if(offset==8)
- {
- offset=0;k++;
- if(nongli_flag==0&&k>45)
- {
- k=0;
- nongli_flag=~nongli_flag;
- nongli_change_flag=1;
- }
- if(k>24&&festival_flag==0&&nongli_flag==1)
- {
- k=0;
- nongli_flag=~nongli_flag;
- nongli_change_flag=1;
- }
- else if(k>30&&festival_flag==1&&nongli_flag==1)
- {
- k=0;
- nongli_flag=~nongli_flag;
- nongli_change_flag=1;
- }
- }
- break;
-
- case 8: //固定顯示溫度
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[39+i]][disrow]);
- break;
-
- case 1: //翻頁鐘顯示
- shutter_clock();
- break;
-
- case 2: //顯示時間
- if(switch_flag==1) {/*k=23;*/switch_flag=0;}
- if(k<30)
- {
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[k+i]][disrow]);
- Send2Byte(color,a[date[k+8]][disrow],offset);
- if(offset==8)
- {
- offset=0;k++;
- }
- }
- if(k==30)
- {
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[30+i]][disrow]);
- }
- break;
-
- case 3: //顯示年
- if(switch_flag==1) {k=0;switch_flag=0;}
- if(k<10)
- {
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[k+i]][disrow]);
- Send2Byte(color,a[date[k+8]][disrow],offset);
- if(offset==8)
- {
- offset=0;k++;
- }
- }
- if(k==10)
- {
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[10+i]][disrow]);
- }
- break;
-
- case 4: //顯示月
- if(switch_flag==1) {k=10;switch_flag=0;}
- if(k<14)
- {
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[k+i]][disrow]);
- Send2Byte(color,a[date[k+8]][disrow],offset);
- if(offset==8)
- {
- offset=0;k++;
- }
- }
- if(k==14)
- {
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[14+i]][disrow]);
- }
- break;
-
- case 5: //顯示日
- if(switch_flag==1) {k=14;switch_flag=0;}
- if(k<18)
- {
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[k+i]][disrow]);
- Send2Byte(color,a[date[k+8]][disrow],offset);
- if(offset==8)
- {
- offset=0;k++;
- }
- }
- if(k==18)
- {
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[18+i]][disrow]);
- }
- break;
- case 6: //顯示星期
- if(switch_flag==1) {k=18;switch_flag=0;}
- if(k<23)
- {
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[k+i]][disrow]);
- Send2Byte(color,a[date[k+8]][disrow],offset);
- if(offset==8)
- {
- offset=0;k++;
- }
- }
- if(k==23)
- {
- for(i=0;i<8;i++) //送往8個4094的數據.
- SendByte(color,a[date[23+i]][disrow]);
- }
- break;
- default:
- break;
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- void shutter_clock(void) //翻頁鐘
- {
- if(date[30]!=temp_time[0]) f1=0; //時十位
- if(f1<17)
- {
- if(date[30]==0) SendByte(color,a[17][disrow+f1]);
- else SendByte(color,a[date[30]-1][disrow+f1]);
- }
- else SendByte(color,a[date[30]][disrow]);
-
- if(date[31]!=temp_time[1]) f2=0; //時個位
- if(f2<17)
- {
- if(date[31]==0) SendByte(color,a[19][disrow+f2]);
- else SendByte(color,a[date[31]-1][disrow+f2]);
- }
- else SendByte(color,a[date[31]][disrow]);
-
- SendByte(color,a[date[32]][disrow]); //冒號
-
- if(date[33]!=temp_time[2]) f3=0; //分十位
- if(f3<17)
- {
- if(date[33]==0) SendByte(color,a[21][disrow+f3]);
- else SendByte(color,a[date[33]-1][disrow+f3]);
- }
- else SendByte(color,a[date[33]][disrow]);
-
- if(date[34]!=temp_time[3]) f4=0; //分個位
- if(f4<17)
- {
- if(date[34]==0) SendByte(color,a[23][disrow+f4]);
- else SendByte(color,a[date[34]-1][disrow+f4]);
- }
- else SendByte(color,a[date[34]][disrow]);
-
- SendByte(color,a[date[35]][disrow]); //冒號
-
- if(date[36]!=temp_time[4]) f5=0; //秒十位
- if(f5<17)
- {
- if(date[36]==0) SendByte(color,a[21][disrow+f5]);
- else SendByte(color,a[date[36]-1][disrow+f5]);
- }
- else SendByte(color,a[date[36]][disrow]);
-
- if(date[37]!=temp_time[5]) f6=0; //秒個位
- if(f6<17)
- {
- if(date[37]==0) SendByte(color,a[23][disrow+f6]);
- else SendByte(color,a[date[37]-1][disrow+f6]);
- }
- else SendByte(color,a[date[37]][disrow]);
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- void delay_nms(unsigned int count) //軟件延時
- {
- unsigned int i,j;
- for(i=0;i<count;i++)
- for(j=0;j<45;j++); //120 改成45看看
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- void time_to_buff_all(void) //讀取全部時間
- {
- DS1302_GetTime_ALL(&CurrentTime);
-
-
- temp_time[0]=date[30];
- temp_time[1]=date[31];
- temp_time[2]=date[33];
- temp_time[3]=date[34];
- temp_time[4]=date[36];
- temp_time[5]=date[37];
- Color(&color,CurrentTime.Hour);
-
- date[30]=CurrentTime.Hour/10; //小時
- date[31]=CurrentTime.Hour%10; //小時
- date[33]=CurrentTime.Minute/10; //分鐘
- date[34]=CurrentTime.Minute%10; //分鐘
- date[36]=CurrentTime.Second/10; //秒
- date[37]=CurrentTime.Second%10; //秒
-
- date[10]=CurrentTime.Year/10; //年
- date[11]=CurrentTime.Year%10; //年
- date[14]=CurrentTime.Month/10; //月
- date[15]=CurrentTime.Month%10; //月
- date[18]=CurrentTime.Day/10; //日
- date[19]=CurrentTime.Day%10; //日
- date[27]=week_data[CurrentTime.Week]; //星期
- date[28]=week_data[CurrentTime.Week]+1;//星期
-
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- void key_scan(void) //掃描按鍵
- {
- static unsigned char mode_counter=0;
- if(adj_flag==1)
- {
- adj_flag=0;
- stop_bit=0;
- offset=0;
- switch_flag=1;
- status++;
- if(status>7) status=1;
- time_to_buff_all();
- }
- if(esc_flag==1)
- {
- esc_flag=0;
- stop_bit=0;
- disp_mode=0; //退出時方式為流動顯示
- k=0;
- offset=0;
- status=0;
- time_to_buff_all();
- }
-
- switch(status)
- {
- case 0: //顯示模式調整
- if(add_flag==1)
- {
- add_flag=0;
- stop_bit=0;
- offset=0;
- switch_flag=1;
- mode_counter++;
- if(mode_counter>3) mode_counter=0;
- disp_mode=mode[mode_counter];
- }
- if(dec_flag==1)
- {
- dec_flag=0;
- offset=0;
- stop_bit=0;
- switch_flag=1;
- if(mode_counter==0) mode_counter=3;
- else mode_counter--;
- disp_mode=mode[mode_counter];
- }
- break;
-
- case 1: //年調整
- disp_mode=3;
- if(add_flag==1)
- {
- add_flag=0;
- CurrentTime.Year++;
- if(CurrentTime.Year>99) CurrentTime.Year=0;
- DS1302_SetTime(DS1302_YEAR,(CurrentTime.Year));
- }
- if(dec_flag==1)
- {
- dec_flag=0;
- if(CurrentTime.Year>0) CurrentTime.Year--;
- if(CurrentTime.Year==0) CurrentTime.Year=99;
- DS1302_SetTime(DS1302_YEAR,(CurrentTime.Year));
- }
- break;
- case 2: //月調整
- …………余下代碼請下載附件…………
復制代碼
|