Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
0.png (49.35 KB, 下載次數: 88)
下載附件
2017-8-7 00:09 上傳
0.png (28.03 KB, 下載次數: 65)
下載附件
2017-8-7 00:10 上傳
全部資料下載地址:
時鐘電路圖及PCB工程.zip
(6.91 MB, 下載次數: 106)
2017-8-6 20:41 上傳
點擊文件名下載附件
電子時鐘,能顯示時間,星期,日期 下載積分: 黑幣 -5
單片機源代碼為
- #include<reg52.h>
- #include<intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit lcdrs=P2^4;
- sbit lcdrw=P2^5;
- sbit lcden=P2^6;
- sbit key1=P2^2;
- sbit key2=P2^1;
- sbit key3=P2^0;
- sbit FM=P1^0;
- uchar counter,cycle;
- uchar key_counter = 0; //定義光標閃爍以及修改操作數的標記
- uchar second0,second1,minute0,minute1,hour0,hour1;
- uchar table[][3]={"SUN","MON","TUE","WEN","THU","FRI","SAT"};
- uchar year[4],day[2],month[2],date; //日期變量
- uchar small_mon,leap_year;
- uchar k;
- void state() //檢查日期狀態函數(即判斷是否閏年,是否小月的函數)
- {
- switch(month[0]) //2,4,6,9,11月是小月
- {
- case 1:
- if(month[1] == 1) //若是11月,則是小月
- small_mon = 1;
- else //若是1月,則不是小月
- small_mon = 0; break;
- case 2:
- case 4:
- case 6:
- case 9: small_mon = 1; break;
- default:small_mon = 0;break;
- }
-
- k=year[3]*1000+year[2]*100+year[1]*10+year[0];
- if(k%4==0&&k%100!=0||k%400==0)
- leap_year=1;
- else
- leap_year=0;
- }
- void Dater() //日期函數
- {
- state();
- day[0]++;
- date=(date+1)%7;
- switch(day[0]) //日變化
- {
- case 10:
- {
- if(day[1] == 2 && month[0] == 2 && month[1] == 0) //20日的個位能到10,說明是閏年,把2月30號轉變為3月1號
- {
- day[0] = 1;
- day[1] = 0;
- month[0]++;
- }
- else //日期個位滿10進1
- {
- day[0] = 0;
- day[1]++;
- }
- } break;
- case 1:
- {
- if(day[1] == 3 && small_mon) //小月31號時把日期置為1號,月份+1
- {
- day[0] = 1;
- day[1] = 0;
- month[0]++;
- }
- } break;
- case 2:
- {
- if(day[1] == 3)
- {
- day[0] = 1;
- day[1] = 0;
- month[0]++;
- }
- }break;
- case 9:
- {
- if(day[1] == 2 && !leap_year && month[0] == 2 && month[1] == 0) //平年時,把2月29號變為3月1號
- {
- day[0] = 1;
- day[1] = 0;
- month[0]++;
- }
- } break;
- default: break;
- }
- switch(month[0]) //月變化
- {
- case 10: //個位逢10進1
- {
- month[0] = 0;
- month[1]++;
- } break;
- case 3: //當十位是1,個位逢3則年進1
- {
- if(month[1] == 1)
- {
- month[0] = 1;
- month[1] = 0;
- year[0]++;
- }
- } break;
- }
- if(year[0] > 9) //相應年變化
- {
- year[0] = 0;
- year[1]++;
- if(year[1] > 9)
- {
- year[1] = 0;
- year[2]++;
- if(year[2] > 9)
- {
- year[2] = 0;
- year[3]++;
- if(year[3] > 9)
- year[3] = 0;
- }
- }
- }
- }
- void clock() //時鐘函數
- {
- second0++;
- if(second0 > 9)
- {
- second0 = 0;
- second1++;
- if(second1 > 5)
- {
- second1 = 0;
- minute0++;
- if(minute0 > 9)
- {
- minute0 = 0;
- minute1++;
- if(minute1 > 5)
- {
- minute1 = 0;
- hour0++;
- if(hour0 == 4 && hour1 == 2)
- {
- hour0 = hour1 = 0;
- Dater();
- }
- else if(hour0 > 9)
- {
- hour0 = 0;
- hour1++;
- }
- }
- }
- }
- }
- }
- void delay(uint z) //延時函數ms
- {
- uint x,y;
- for(x = z;x > 0;x--)
- for(y = 110;y > 0;y--) ;
- }
- void write_com(uchar com) //寫指令到LCD液晶顯示
- {
- lcdrs = 0; //選擇指令寄存器
- lcdrw = 0; //選擇寫
- P0 = com; //把命令字送入P0口
- delay(1); //延時,讓1602準備接收數據
- lcden = 1; //使能線電平變化,命令送入1602的8位數據口
- delay(1); //等待接收
- lcden = 0;
- }
- void write_data(uchar data0) //寫數據到LCD液晶顯示
- {
- lcdrs = 1; //選擇數據寄存器
- lcdrw = 0; //選擇寫
- P0 = data0; //把數據送入P0口
- delay(1); //延時,讓1602準備接收數據
- lcden = 1; //使能線電平變化,數據送入8位數據口
- delay(1); //等待接收
- lcden = 0;
- }
- void disp_time() //顯示時間
- {
- write_com(0xc4); //設定顯示地址為下排第5位
- write_data(hour1 + 0x30); //小時
- write_data(hour0 + 0x30);
- write_data(0x3a); //顯示冒號
- write_data(minute1 + 0x30); //分鐘
- write_data(minute0 + 0x30);
- write_data(0x3a); //冒號
- write_data(second1 + 0x30);//秒
- write_data(second0 + 0x30);
- if(key_counter != 0 ) //按功能鍵key1次數不為0
- {
- switch(key_counter)
- {
- case 1:
- write_com(0x80+0x4b); //定位回光標閃爍位置,第二行第12位
- break;
- case 2:
- write_com(0x80+0x48); //第二行第9位
- break;
- case 3:
- write_com(0x80+0x45); //第二行第6位
- break;
- case 4:
- write_com(0x80+0x0e); //第一行第15位
- break;
- case 5:
- write_com(0x80+0x0b); //第一行第12位
- break;
- case 6:
- write_com(0x80+0x08); //第一行第9位
- break;
- case 7:
- write_com(0x80+0x03); //第一行第4位
- break;
- }
- write_com(0x0f); //關光標
- delay(150);
- }
- }
- void disp_date() //顯示日期
- {
- write_com(0x81); //定義回第一行第2位
- for(cycle = 0; cycle < 3;cycle++)// 顯示星期
- write_data(table[date][cycle]);
- write_data(0x20); //顯示空格
- for(cycle = 0;cycle < 4;cycle++) //顯示年
- write_data(year[3 - cycle]+0x30);
- write_data(0x2d); //顯示'/'
- write_data(month[1]+0x30); //顯示月
- write_data(month[0]+0x30);
- write_data(0x2d); //顯示'/'
- write_data(day[1]+0x30); //顯示日
- write_data(day[0]+0x30);
- }
- void di() //蜂鳴器發聲函數
- {
- FM=0;
- delay(100);
- FM=1;
- }
- void setting_detect() //按鍵掃描函數
- {
- if(key1==0)
- {
- delay(5);
- if(key1==0) //消除抖動
- {
- while(!key1); //等待松手
- TR0=0; //TRO==0
- di(); //蜂鳴器滴
- key_counter++; //功能鍵按下次數加一
- do
- {
- disp_date(); //顯示星期+日期
- disp_time(); //顯示時間
- if(key1==0) //按鍵“切換”
- {
- delay(5);
- if(key1==0)
- {
- while(!key1);
- di();
- key_counter++;
- }
- }
- if(key2==0) //按鍵“加”
- {
- delay(5);
- if(key2==0)
- {
- while(!key2);
- di();
- switch(key_counter) //判斷功能鍵按下次數
- {
- case 1: //一次則秒加一
- second0++;
- if(second0 > 9)
- {
- second0 = 0;
- second1++;
- if(second1 == 6)
- second1 = 0;
- } break;
- case 2: //兩次則分加一
- minute0++;
- if(minute0 > 9)
- {
- minute0 = 0;
- minute1++;
- if(minute1 == 6)
- minute1 = 0;
- } break;
- case 3: //三次則時加一
- hour0++;
- if(hour1 == 2 && hour0 > 3)
- {
- hour0 = 0;
- hour1 = 0;
- }
- else if(hour0 > 9)
- {
- hour0 = 0;
- hour1++;
- }
- break;
- case 4: //四次則日加一
- day[0]++;
- if(day[0] == 2 && day[1] == 3)
- {
- day[0] = 1;
- day[1] = 0;
- }
- if(day[0] == 10)
- {
- day[0] = 0;
- day[1]++;
- }
- break;
- case 5: //五次則月加一
- month[0]++;
- if(month[0] == 3 && month[1] == 1)
- {
- month[0] = 1;
- month[1] = 0;
- }
- if(month[0] == 10)
- {
- month[0] = 0;
- month[1] = 1;
- }
- break;
- case 6: //六次則年加一
- year[0]++;
- if(year[0] > 9)
- {
- year[0] = 0;
- year[1]++;
- if(year[1] > 9)
- {
- year[1] = 0;
- year[2]++;
- if(year[2] > 9)
- {
- year[2] = 0;
- year[3]++;
- if(year[3] > 9)
- year[3] = 0;
- }
- }
- }
- break;
- case 7: //七次則星期加一
- date=(date+1)%7;
- break;
- }
- }
- }
- if(key3==0) //按鍵“減”
- {
- delay(5);
- if(key3==0)
- {
- while(!key3);
- di();
- switch(key_counter)
- {
- case 1:
- if(second0 == 0)
- {
- second0 = 9;
- if(second1 == 0)
- second1 = 5;
- else
- second1--;
- }
- else
- second0--;
- break;
- case 2:
- if(minute0 == 0)
- {
- minute0 = 9;
- if(minute1 == 0)
- minute1 = 5;
- else
- minute1--;
- }
- else
- minute0--;
- break;
- case 3:
- if(hour0 == 0)
- {
- if(hour1 == 0)
- {
- hour0 = 3;
- hour1 = 2;
- }
- else
- {
- hour0 = 9;
- hour1--;
- }
- }
- else
- hour0--;
- break;
- case 4:
- if(day[0] == 1 && day[1] == 0)
- day[1] = 3;
- if(day[0] == 0)
- {
- day[0] = 9;
- day[1]--;
- }
- else
- day[0]--;
- break;
- case 5:
- if(month[0] == 1 && month[1] == 0)
- {
- month[0] = 2;
- month[1] = 1;
- }
- else if(month[0] == 0)
- {
- month[0] = 9;
- month[1]--;
- }
- else
- month[0]--;
- break;
- case 6:
- if(year[0] == 0)
- {
- year[0] = 9;
- if(year[1] == 0)
- {
- year[1] = 9;
- if(year[2] == 0)
- {
- year[2] = 9;
- if(year[3] == 0)
- year[3] = 9;
- else
- year[3]--;
- }
- else
- year[2]--;
- }
- else
- year[1]--;
- }
- else
- year[0]--;
- break;
- case 7:
- date=(date+6)%7;
- break;
- }
- }
- }
- }
- while(key_counter != 8);
- key_counter = 0; //退出設置時關掉光標顯示
- TR0=1;
- }
- }
- }
- void Lcd_init() //顯示屏初始化
- {
- lcden = 0;
- write_com(0x01); //清屏
- write_com(0x02); //位置復位為左上方
- write_com(0x06); //光標右移
- write_com(0x0e); //顯示開,有光標,閃爍
- write_com(0x38); //兩行,每行16字符,5*7點陣
- }
- void timer0() interrupt 1 //定時器
- {
- TH0 = (65536-39970)/256;
- TL0 = (65536-39970)%6;
- counter++;
- if(counter == 25)
- {
- counter = 0;
- clock();
- }
- }
- void Timer_init() //定時器初始化
- {
- TMOD = 0x01;
- TH0 = (65536-29995)/256;
- TL0 = (65536-29995)%6;
- EA = 1;
- ET0 = 1;
- TR0 = 1;
- }
- void Date_init() //日期初始化
- {
- date = 4;
- day[0] = 0;
- day[1] = 2;
- month[0] = 4;
- month[1] = 0;
- year[0] = 7;
- year[1] = 1;
- year[2] = 0;
- year[3] = 2;
- }
- void Time_init() //時間初始化
- {
- second0 = 0;
- second1 = 3;
-
- minute0 = 0;
- minute1 = 3;
-
- hour0 = 2;
- hour1 = 1;
-
- counter = 0;
- }
- void main() //主函數
- {
- Lcd_init();
- Time_init();
- Date_init();
- Timer_init();
- while(1)
- {
- disp_date();
- disp_time();
- setting_detect();
- }
- }
復制代碼
|