標(biāo)題: 51單片機(jī)+AT24C02+按鍵+Proteus仿真時(shí)鐘源程序 [打印本頁]
作者: hufei 時(shí)間: 2013-6-17 03:17
標(biāo)題: 51單片機(jī)+AT24C02+按鍵+Proteus仿真時(shí)鐘源程序
時(shí)間很準(zhǔn)確,跑了2個(gè)小時(shí)才慢1S,這可是用Proteus仿真軟件仿真哦!而且里面有詳細(xì)的說明,具體到每一步。還有AT24C02的中文資料,希望對(duì)新手有用。不過在調(diào)試程序的過程中發(fā)現(xiàn)了一點(diǎn)小問題,一直沒有找到解決的辦法,就是在調(diào)節(jié)時(shí)間時(shí)光標(biāo)移動(dòng)有時(shí)出現(xiàn)問題,但是又并不影響調(diào)節(jié),具體在程序中有說明,希望有高手能夠指點(diǎn)一下!在此先感謝!
0.png (39.43 KB, 下載次數(shù): 151)
下載附件
2016-1-22 16:57 上傳
單片機(jī)定時(shí)器時(shí)鐘.zip
(63.28 KB, 下載次數(shù): 548)
2013-6-17 03:16 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者: admin 時(shí)間: 2013-6-17 03:50
下面是主程序:
/**************************************
名稱:89c52+at24c02+鍵盤時(shí)鐘程序
工具:protues仿真軟件
作者:kwx618
時(shí)間:2011-09-10
**************************************/
#include <reg52.h>
#include <intrins.h>
#include"at24c02.h"
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS=P0^0;
sbit LCD_RW=P0^1;
sbit LCD_EN=P0^2;
sbit S1=P1^2;
sbit S2=P1^3;
sbit S3=P1^4;
sbit S4=P1^5;
char year,mounth,day,hour,minute,second;
uchar num,count;
bit write=0; //寫2402標(biāo)志
uchar code nyr_table[]=" 20 - - ";
uchar code sfm_table[]=" : : ";
/************延時(shí)1ms函數(shù)***************/
void delay1ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=112;y>0;y--);
}
/**************LCD1602程序***********/
void LCD_BUSY()
{
P2=0x00;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
while(P2&0x80);
LCD_EN=0;
}
void writeLCD_command(uchar cmd)
{
LCD_BUSY();
LCD_RS=0;
LCD_RW=0;
P2=cmd;
_nop_();
LCD_EN=1;
_nop_();
LCD_EN=0;
}
void writeLCD_data(uchar date)
{
LCD_BUSY();
LCD_RS=1;
LCD_RW=0;
P2=date;
_nop_();
LCD_EN=1;
_nop_();
LCD_EN=0;
}
void write_nyrsfm(char add,char date)
{
char shiwei,gewei;
shiwei=date/10;
gewei=date%10;
writeLCD_command(0x80|add);
delay1ms(1);
writeLCD_data(0x30+shiwei);
delay1ms(1);
writeLCD_data(0x30+gewei);
delay1ms(1);
}
void LCD_init()
{
uchar num1,num2;
year=0;mounth=1;day=1;
hour=23;minute=59;second=59;
LCD_BUSY();
writeLCD_command(0x38);//設(shè)置16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
delay1ms(5); //此處必須加延時(shí),否則LCD不顯示
writeLCD_command(0x0c);//開顯示,光標(biāo)不顯示
delay1ms(5); //此處必須加延時(shí),否則光標(biāo)不會(huì)移動(dòng)
writeLCD_command(0x06);//讀或?qū)懽址螅鈽?biāo)自動(dòng)加1,整屏不移動(dòng)
delay1ms(5);
writeLCD_command(0x02);//數(shù)據(jù)指針清0
delay1ms(5);
writeLCD_command(0x80|0x02);
for(num1=0;num1<11;num1++)
{
writeLCD_data(nyr_table[num1]);
}
writeLCD_command(0x80|0x43);
for(num2=0;num2<9;num2++)
{
writeLCD_data(sfm_table[num2]);
}
write_nyrsfm(0x80|0x05,year);
_nop_();
write_nyrsfm(0x80|0x08,mounth);
_nop_();
write_nyrsfm(0x80|0x0b,day);
_nop_();
write_nyrsfm(0x80|0x44,hour);
_nop_();
write_nyrsfm(0x80|0x47,minute);
_nop_();
write_nyrsfm(0x80|0x4a,second);
_nop_();
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
/**************************************************
名稱:按鍵程序
S1: 設(shè)置鍵
S2:時(shí)間加
S3:時(shí)間減
**************************************************/
void keyscan()
{
if(S1==0)
{
delay1ms(10);
if(S1==0)
num++;
while(!S1);
switch(num)
{
case 1: TR0=0;
writeLCD_command(0x80|0x4b);
delay1ms(1);
writeLCD_command(0x0f);
delay1ms(1);
break;
case 2: TR0=0;
writeLCD_command(0x80|0x48);
writeLCD_command(0x0f);
break;
case 3: TR0=0;
writeLCD_command(0x80|0x45);
writeLCD_command(0x0f);
break;
case 4: TR0=0;
writeLCD_command(0x80|0x0c);
writeLCD_command(0x0f);
break;
case 5: TR0=0;
writeLCD_command(0x80|0x09);
writeLCD_command(0x0f);
break;
case 6: TR0=0;
writeLCD_command(0x80|0x06);
writeLCD_command(0x0f);
break;
case 7: num=0;
writeLCD_command(0x0c);
TR0=1;
break;
default:break;
}
}
}
void up_downsetkey()
{
//keyscan();
if(num!=0)
{
if(S2==0)
{
delay1ms(10);
if(S2==0)
while(!S2);
switch(num)
{
case 1: second++;
if(second==60)
second=0;
write_nyrsfm(0x80|0x4a,second);
delay1ms(5);
write2402_data(1,second);
delay1ms(5);
break;
case 2: minute++;
if(minute==60)
minute=0;
write_nyrsfm(0x80|0x47,minute);
delay1ms(5);
write2402_data(2,minute);
delay1ms(5);
break;
case 3: hour++;
if(hour==24)
hour=0;
write_nyrsfm(0x80|0x44,hour);
delay1ms(5);
write2402_data(3,hour);
delay1ms(5);
break;
case 4: day++;
if(day==30)
day=0;
write_nyrsfm(0x80|0x0b,day);
delay1ms(5);
write2402_data(4,day);
delay1ms(5);
break;
case 5: mounth++;
if(mounth==12)
mounth=0;
write_nyrsfm(0x80|0x08,mounth);
delay1ms(5);
write2402_data(5,mounth);
delay1ms(5);
break;
case 6: year++;
if(year==99)
year=0;
write_nyrsfm(0x80|0x05,year);
delay1ms(5);
write2402_data(6,year);
delay1ms(5);
break;
default:break;
}
}
if(S3==0)
{
delay1ms(10);
if(S3==0)
while(!S3);
switch(num)
{
case 1: second--;
if(second==-1)
second=59;
write_nyrsfm(0x80|0x4a,second);
delay1ms(1);
write2402_data(1,second);
break;
case 2: minute--;
if(minute==-1)
minute=59;
write_nyrsfm(0x80|0x47,minute);
write2402_data(2,minute);
break;
case 3: hour--;
if(hour==-1)
hour=23;
write_nyrsfm(0x80|0x44,hour);
write2402_data(3,hour);
break;
case 4: day--;
if(day==-1)
day=30;
write_nyrsfm(0x80|0x0b,day);
write2402_data(4,day);
break;
case 5: mounth--;
if(mounth==-1)
mounth=12;
write_nyrsfm(0x80|0x08,mounth);
write2402_data(5,mounth);
break;
case 6: year--;
if(year==-1)
year=99;
write_nyrsfm(0x80|0x05,year);
write2402_data(6,year);
break;
default:break;
}
}
}
}
/*void display() //開始的時(shí)候采用這種邊顯示邊寫2402的方式,但是程序?qū)懖坏?402,
{ //很郁悶。不過調(diào)整時(shí)間時(shí)光標(biāo)很正常,一直想找個(gè)方法讓光標(biāo)正常而且能寫進(jìn)
if(count==20) // 2402的方法,但是沒有想出來
{
second++;
count=0;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
{
hour=0;
day++;
if(day==31)
{
day=0;
mounth++;
if(mounth==13)
{
mounth=0;
year++;
write_nyrsfm(0x80|0x05,year);
delay1ms(1);
write2402_data(6,year);
delay1ms(1);
}
write_nyrsfm(0x80|0x08,mounth);
delay1ms(1);
write2402_data(5,mounth);
delay1ms(1);
}
write_nyrsfm(0x80|0x0b,day);
delay1ms(1);
write2402_data(4,day);
delay1ms(1);
}
write_nyrsfm(0x80|0x44,hour);
delay1ms(1);
write2402_data(3,hour);
delay1ms(1);
}
write_nyrsfm(0x80|0x47,minute);
delay1ms(1);
write2402_data(2,minute);
delay1ms(1);
}
write_nyrsfm(0x80|0x4a,second);
delay1ms(1);
write2402_data(1,second);
delay1ms(1);
}
} */
/************顯示程序****************/
void display()
{
//year=0;mounth=1;day=0; // 開始的時(shí)候不寫這兩句,顯示的結(jié)果就是2000-0/-0/ 23-0/-0/ ,
//hour=23;minute=59;second=59; // 解決辦法是先在加上這兩句,然后把初始化里的那兩句屏蔽掉,然后編譯顯示,
write_nyrsfm(0x80|0x05,year); // 在回過頭來去掉初始化里的屏蔽,把這兩句刪掉編譯就顯示正常了,具體為什么會(huì)
delay1ms(1); //這樣,我也不清楚,有待解決。
write_nyrsfm(0x80|0x08,mounth);
delay1ms(1);
write_nyrsfm(0x80|0x0b,day);
delay1ms(1);
write_nyrsfm(0x80|0x44,hour);
delay1ms(1);
write_nyrsfm(0x80|0x47,minute);
delay1ms(1);
write_nyrsfm(0x80|0x4a,second);
delay1ms(1);
}
void main()
{
init_2402();
delay1ms(5);
LCD_init();
delay1ms(5); //此處也必須加延時(shí),否則不會(huì)在指定的位置顯示
second =read_data(0); //讀出24c02保存的值賦于sec
if(second>60) //防止首次讀出錯(cuò)誤數(shù)據(jù)
second=0;
delay1ms(5);
minute=read_data(1); //讀出24c02保存的值賦于sec
if(minute>60) //防止首次讀出錯(cuò)誤數(shù)據(jù)
minute=0;
delay1ms(5);
hour=read_data(2); //讀出24c02保存的值賦于sec
if(hour>24) //防止首次讀出錯(cuò)誤數(shù)據(jù)
hour=0;
delay1ms(5);
day=read_data(3); //讀出24c02保存的值賦于sec
if(day>30) //防止首次讀出錯(cuò)誤數(shù)據(jù)
day=0;
delay1ms(5);
mounth=read_data(4); //讀出24c02保存的值賦于sec
if(mounth>12) //防止首次讀出錯(cuò)誤數(shù)據(jù)
mounth=0;
delay1ms(5);
year=read_data(5); //讀出24c02保存的值賦于sec
if(year>12) //防止首次讀出錯(cuò)誤數(shù)據(jù)
year=0;
delay1ms(5);
while(1)
{
display();
delay1ms(1);
keyscan();
delay1ms(1);
up_downsetkey();
delay1ms(1);
if(write==1)
{
write2402_data(0,second);
delay1ms(1);
write2402_data(1,minute);
delay1ms(1);
write2402_data(2,hour);
delay1ms(1);
write2402_data(3,day);
delay1ms(1);
write2402_data(4,mounth);
delay1ms(1);
write2402_data(5,year);
delay1ms(1);
write=0; //清0
}
}
}
void intputtime0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==16)//此處應(yīng)該是20,但是用protues仿真時(shí)會(huì)發(fā)現(xiàn)誤差很大,所以我調(diào)到了16,時(shí)間剛好。
{
second++;
count=0;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
{
hour=0;
day++;
if(day==31)
{
day=0;
mounth++;
if(mounth==13)
{
mounth=0;
year++;
}
}
}
}
}
write=1;
}
}
作者: 左左右右 時(shí)間: 2013-7-1 16:06
51Hei(51黑)論壇有你更精彩
作者: HUFUHA 時(shí)間: 2013-10-9 03:10
看看學(xué)習(xí)學(xué)習(xí)
作者: 13620819446 時(shí)間: 2013-10-13 23:27
不錯(cuò)過來看看
作者: 游俠(單片機(jī)開 時(shí)間: 2013-10-23 14:16
很好 學(xué)習(xí) 謝謝
作者: wanshaojun 時(shí)間: 2014-1-18 22:55
學(xué)習(xí)學(xué)習(xí)
作者: fbzsn 時(shí)間: 2014-8-31 23:03
好像proteus仿真通不過,檢測到?jīng)]有聲明write2402_data子函數(shù),程序中也沒有寫這個(gè)子函數(shù)。
作者: test66878114 時(shí)間: 2014-9-2 10:19
謝謝分享,贊一個(gè)
作者: 游俠(單片機(jī)開 時(shí)間: 2014-9-2 11:30
謝謝 很好
作者: heam 時(shí)間: 2014-9-15 12:33
謝謝分享
作者: xing3198 時(shí)間: 2014-9-18 16:18
很好 學(xué)習(xí) 謝謝
作者: shc95 時(shí)間: 2014-10-8 10:18
感謝樓主分享
作者: finalex 時(shí)間: 2014-10-8 10:29
有圖嗎
作者: shushikuan 時(shí)間: 2014-10-8 11:02
很好,學(xué)習(xí)了哈。
作者: tianxing 時(shí)間: 2014-10-14 17:51
馬虎了。
作者: 綠源學(xué)習(xí)者 時(shí)間: 2015-1-30 13:49
沒有仿真圖唉
作者: seeking1005 時(shí)間: 2015-2-2 01:11
51Hei(51黑)論壇有你更精彩
作者: fontex 時(shí)間: 2015-2-2 13:21
又學(xué)到新東西。
作者: 啊大蘇打似的 時(shí)間: 2015-7-9 09:49
不知道有沒有電路原理圖




作者: 11223 時(shí)間: 2015-9-14 21:12
時(shí)鐘的時(shí)間如何修改?
作者: zxcvbnm1 時(shí)間: 2015-10-28 17:23
有圖么
作者: wangxiaomi 時(shí)間: 2015-11-1 19:14
非常好
作者: ruzongqing 時(shí)間: 2016-1-14 14:10
我要認(rèn)真的好好學(xué)習(xí)學(xué)習(xí)!
作者: linnyshow 時(shí)間: 2016-3-22 22:32
不錯(cuò),有電路圖就更好了。
作者: 瓦爾登 時(shí)間: 2016-3-23 19:04
好東西呀,正在學(xué)習(xí),多謝了
作者: lqm 時(shí)間: 2016-3-27 23:19
很不錯(cuò),值得大家學(xué)習(xí)
作者: 炳文 時(shí)間: 2016-12-3 09:36
到底有沒有仿真
作者: hei_cmh 時(shí)間: 2016-12-11 18:06
很好 學(xué)習(xí)
作者: 784721214 時(shí)間: 2016-12-12 14:22
學(xué)習(xí)下,很不錯(cuò)!
作者: chjx0131 時(shí)間: 2017-1-2 14:47
學(xué)習(xí)了。
作者: darm 時(shí)間: 2017-3-16 11:26
借鑒了一下,對(duì)我學(xué)習(xí)單片機(jī)很有作用,多謝
作者: yanjingshe 時(shí)間: 2017-4-5 14:37
24c02是干什么用的
作者: yuanyuanyuaan 時(shí)間: 2017-10-31 09:06
謝謝樓主的教程,回去好好研究一下~~
作者: xd_q 時(shí)間: 2018-1-19 15:45
學(xué)習(xí)一下
作者: 70599 時(shí)間: 2018-5-21 10:37
謝謝樓主的教程,正研究2402
作者: echos2000 時(shí)間: 2019-10-29 19:37
很好,收藏了
作者: q2855159156 時(shí)間: 2020-12-18 13:52
向大佬學(xué)習(xí)學(xué)習(xí)
作者: 大山兒子20@ 時(shí)間: 2023-11-25 10:13
謝謝壇主的無私分享,都是干貨的。
作者: dyx811 時(shí)間: 2023-11-25 22:35
學(xué)習(xí)了,依然在學(xué)習(xí)的路上!感謝版主和樓主的無私奉獻(xiàn)!
作者: anjianguo 時(shí)間: 2024-11-23 23:20
(65536-50000)/256; 把50000定義為時(shí)基,再增加一層時(shí)基設(shè)置(并存儲(chǔ)),這樣時(shí)鐘可以調(diào)的很準(zhǔn)!
我正在為STC15W408外加AT24C02存儲(chǔ)時(shí)基頭疼!我用的是STC89C52外加AT24C02存儲(chǔ)器的程序!嘿嘿!
歡迎光臨 (http://www.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |