1. 51單片機控制DS1302,時間顯示在數碼管上。
1302.c
#include<DS1302.h>
#include<key.h>
ucharbit_ser[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
ucharseven_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/***********************時間顯示*****************/
voidtimer0_init(void) //T0初始化函數,用於時間的動態顯示
{
TMOD=0x21;
TL0=(65536-5000)%256;
TH0=(65536-5000)/256;
EA=1;
ET0=1;
TR0=1;
}
voidtimer0_isr(void)interrupt1 //T0中斷處理函數
{
charflag; //flag用於表示調整時閃爍的亮或滅
TR0=0;
TL0=(65536-5000)%256;
TH0=(65536-5000)/256;
TR0=1;
flag=x/100*0xff; //設置閃爍標志,如果x大於100則flag為0xff,小於100則為0x00
x++;
if(x>200)
x=0;
switch(i)
{
case0:
P2=bit_ser[0];
if(setflag==3) //根據setflag的值判斷當前位是否需要閃爍
P0=flag|seven_seg[dis_buffer[0]];
else
P0=seven_seg[dis_buffer[0]];
break;
case1:
P2=bit_ser[1];
if(setflag==3)
P0=flag|seven_seg[dis_buffer[1]];
else
P0=seven_seg[dis_buffer[1]];
break;
case2:
P2=bit_ser[2];
if(setflag==2)
P0=flag|seven_seg[dis_buffer[2]];
else
P0=seven_seg[dis_buffer[2]];
break;
case3:
P2=bit_ser[3];
if(setflag==2)
P0=flag|seven_seg[dis_buffer[3]];
else
P0=seven_seg[dis_buffer[3]];
break;
case4:
P2=bit_ser[4];
if(setflag==1)
P0=flag|seven_seg[dis_buffer[4]];
else
P0=seven_seg[dis_buffer[4]];
break;
case5:
P2=bit_ser[5];
if(setflag==1)
P0=flag|seven_seg[dis_buffer[5]];
else
P0=seven_seg[dis_buffer[5]];
break;
}
i++;
if(i>=6)
{
i=0;
if(j==10)
{
j=0;
if(setflag==0)
DS1302_GetTime(&Time); //如果setflag是0,就從1302中讀出時間,因為setflag不是0時,說明處於調整狀態,不需要讀時間
dis_buffer[5]=Time.Second%10; //把當前時間放入顯示緩沖區
dis_buffer[4]=Time.Second/10;
dis_buffer[3]=Time.Minute%10;
dis_buffer[2]=Time.Minute/10;
dis_buffer[1]=Time.Hour%10;
dis_buffer[0]=Time.Hour/10;
}
j++;
}
}
voidmain()
{
Initial_DS1302(Time);
timer0_init();
while(1)
{
set_down();
timer_down();
up_down();
down_down();
beepflag_down();
if(setflag==0&&Time.Hour==romhour&&Time.Minute==romminute&&Beepflag==1) //判斷蜂鳴器是否要響
Beep=!Beep;
}
}
//key.c
#include<reg51.h>
#defineucharunsignedchar
#defineuintunsignedint
uchari=0,j=0,x=0,setflag,flag_set,flag_timer;//setflag用來表示調整的位置,flag_set和flag_timer分別表示當前處於調整狀態還是定時狀態
SYSTEMTIMETime={0,20,15,3,30,6,10}; //系統時間的初始值2010年6月30日星期三,15時20分0秒
chardis_buffer[6]; //存放顯示數據的緩沖區
sbitBeep_flag=P3^2; //蜂鳴器的介面
sbitkey_timer=P3^4; //定時按鈕
sbitkey_set=P3^5; //調整按鈕
sbitkey_up=P3^6; //增加按鈕
sbitkey_down=P3^7; //減小按鈕
charromhour,romminute,romsec; //分別存放定時的時,分,秒
bitBeepflag; //標記鬧鍾是否開啟
//延時函數
voiddelays(ucharx)
{
while(x)x--;
}
//設置鍵的處理函數
voidset()
{
setflag++;
flag_set=1;
if(setflag>=4)
{
setflag=0;
flag_set=0;
Initial_DS1302(Time);
}
}
//定時間的處理函數
voidtimer()
{
setflag++;
flag_timer=1;
if(setflag==1)
{
Time.Hour=romhour;
Time.Minute=romminute;
Time.Second=romsec;
}
elseif(setflag>=4)
{
setflag=0;
flag_timer=0;
romhour=Time.Hour;
romminute=Time.Minute;
romsec=Time.Second;
}
}
//增加鍵的處理函數
voip()
{
switch(setflag)
{
case0:
break;
case1:
Time.Second++;
if(Time.Second>=60)
Time.Second=0;
break;
case2:
Time.Minute++;
if(Time.Minute>=60)
Time.Minute=0;
break;
case3:
Time.Hour++;
if(Time.Hour>=24)
Time.Hour=0;
break;
}
}
//減小鍵的處理函數
voiddown()
{
switch(setflag)
{
case0:
break;
case1:
Time.Second--;
if(Time.Second<0)
Time.Second=59;
break;
case2:
Time.Minute--;
if(Time.Minute<0)
Time.Minute=59;
break;
case3:
Time.Hour--;
if(Time.Hour<0)
Time.Hour=23;
break;
}
}
//設置鍵的掃描函數
voidset_down()
{
if(key_set==0&&flag_timer==0)
{
delays(100);
if(key_set==0)
{
set();
}
while(!key_set);
}
}
//定時鍵的掃描函數
voidtimer_down()
{
if(key_timer==0&&flag_set==0)
{
delays(100);
if(key_timer==0)
{
timer();
}
while(!key_timer);
}
}
//增加鍵的掃描函數
voip_down()
{
if(key_up==0&&setflag!=0)
{
delays(100);
if(key_up==0)
{
up();
while(!key_up);
}
}
}
//減少鍵的處理函數
voiddown_down()
{
if(key_down==0&&setflag!=0)
{
delays(100);
if(key_down==0)
{
down();
while(!key_down);
}
}
}
//定時開關的掃描處理函數
voidbeepflag_down()
{
if(Beep_flag==0)
{
delays(100);
{
Beepflag=!Beepflag;
while(!Beep_flag);
}
}
}
//ds1302.h
#ifndef_REAL_TIMER_DS1302
#define_REAL_TIMER_DS1302
#include<REG51.h>
sbitDS1302_CLK=P1^1;//實時時鍾時鍾線引腳
sbitDS1302_IO=P1^2;//實時時鍾數據線引腳
sbitDS1302_RST=P1^3;//實時時鍾復位線引腳
sbitACC0=ACC^0;
sbitACC7=ACC^7;
sbitBeep=P2^7;
typedefstruct__SYSTEMTIME__
{ charSecond;
charMinute;
charHour;
charWeek;
charDay;
charMonth;
charYear;
}SYSTEMTIME; //定義的時間類型
#defineAM(X) X
#definePM(X) (X+12) //轉成24小時制
#defineDS1302_SECOND 0x80//秒寄存器
#defineDS1302_MINUTE 0x82//分寄存器
#defineDS1302_HOUR 0x84
#defineDS1302_WEEK 0x8A
#defineDS1302_DAY 0x86
#defineDS1302_MONTH 0x88
#defineDS1302_YEAR 0x8C
#defineDS1302_RAM(X) (0xC0+(X)*2) //用於計算DS1302_RAM地址的宏
voidDS1302InputByte(unsignedchard) //實時時鍾寫入一位元組(內部函數)
{unsignedchari;
ACC=d;
for(i=8;i>0;i--)
{ DS1302_IO=ACC0; //相當於匯編中的RRC
DS1302_CLK=1;
DS1302_CLK=0;//發一個高跳變到低的脈沖
ACC=ACC>>1;
}
}
unsignedcharDS1302OutputByte(void) //實時時鍾讀取一位元組(內部函數)
{ unsignedchari;
for(i=8;i>0;i--)
{ ACC=ACC>>1; //相當於匯編中的RRC
ACC7=DS1302_IO;
DS1302_CLK=1;
DS1302_CLK=0;//發一個高跳變到低的脈沖
}
return(ACC);
}
voidWrite1302(unsignedcharucAddr,unsignedcharucDa)//ucAddr:DS1302地址,ucData:要寫的數據
{ DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr); //地址,命令
DS1302InputByte(ucDa); //寫1Byte數據
DS1302_CLK=1;
DS1302_RST=0;//RST0->1->0,CLK0->1
}
unsignedcharRead1302(unsignedcharucAddr) //讀取DS1302某地址的數據
{ unsignedcharucData;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;//enable
DS1302InputByte(ucAddr|0x01);//地址,命令
ucData=DS1302OutputByte();//讀1Byte數據
DS1302_CLK=1;//RST0->1->0,CLK0->1
DS1302_RST=0;
return(ucData);
}
voidDS1302_SetProtect(bitflag)//是否防寫
{ if(flag)
Write1302(0x8E,0x80);//WP=1,不能寫入
else
Write1302(0x8E,0x00);//WP=0,可以寫入
}
voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//設置時間函數
{ DS1302_SetProtect(0);
Write1302(Address,((Value/10)<<4|(Value%10)));//高4位為十位,低4位為個位
DS1302_SetProtect(1);
}
//獲取時間函數,從DS1302內讀取時間然後存入Time內
voidDS1302_GetTime(SYSTEMTIME*Time)
{ unsignedcharReadValue;
ReadValue=Read1302(DS1302_SECOND);
Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//轉換成10進制的秒
ReadValue=Read1302(DS1302_MINUTE);
Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_HOUR);
Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_DAY);
Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_WEEK);
Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MONTH);
Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_YEAR);
Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
}
//利用STime初始化DS1302
voidInitial_DS1302(SYSTEMTIMESTime)
{ unsignedcharSecond=Read1302(DS1302_SECOND);
if(Second&0x80) DS1302_SetTime(DS1302_SECOND,0);//如果第七為1(表明沒有啟動),則啟動時鍾
DS1302_SetTime(DS1302_SECOND,STime.Second); //設定起始時間
DS1302_SetTime(DS1302_MINUTE,STime.Minute);
DS1302_SetTime(DS1302_HOUR,STime.Hour);
DS1302_SetTime(DS1302_DAY,STime.Day);
DS1302_SetTime(DS1302_MONTH,STime.Month);
DS1302_SetTime(DS1302_YEAR,STime.Year);
DS1302_SetTime(DS1302_WEEK,STime.Week);
}
#endif
2. 跪求 51單片機+12864液晶+1302時鍾製成的萬年歷c程序
頂層文件 萬年歷.C
#include<reg51.h>
#include "LCD1602.h"
#include "DS1302.h"
#define uchar unsigned char
#define uint unsigned int
sbit speaker=P2^4;
bit key_flag1=0,key_flag2=0;
SYSTEMTIME adjusted;
uchar sec_add=0,min_add=0,hou_add=0,day_add=0,mon_add=0,yea_add=0;
uchar data_alarm[7]={0};
/************鍵盤控制******************************/
int key_scan() //掃描是否有鍵按下
{ int i=0;
uint temp;
P1=0xf0;
temp=P1;
if(temp!=0xf0)
i=1;
else
i=0;
return i;
}
uchar key_value() //確定按鍵的值
{
uint m=0,n=0,temp;
uchar value;
uchar v[4][3]={'2','1','0','5','4','3','8','7','6','b','a','9'} ;
P1=0xfe; temp=P1; if(temp!=0xfe)m=0;
P1=0xfd;temp=P1 ;if(temp!=0xfd)m=1;
P1=0xfb;temp=P1 ;if(temp!=0xfb)m=2;
P1=0xf7;temp=P1 ;if(temp!=0xf7)m=3;
P1=0xef;temp=P1 ;if(temp!=0xef)n=0;
P1=0xdf;temp=P1 ;if(temp!=0xdf)n=1;
P1=0xbf;temp=P1 ;if(temp!=0xbf)n=2;
value=v[m][n];
return value;
}
/***************************設置鬧鈴函數*******************************/
void naoling(void)
{
uchar i=0,l=0,j;
init1602();
while(key_flag2&&i<12)
if(key_scan()){j=key_value();write_data(j);if(i%2==0)data_alarm[l]=(j-'0')*10;else {data_alarm[l]+=(j-'0');l++;}i++;delay(600);}
write_com(0x01);
}
uchar according(void)
{ uchar k;
if(data_alarm[0]==adjusted.Year&&data_alarm[1]==adjusted.Month&&data_alarm[2]==adjusted.Day&&data_alarm[3]==adjusted.Hour&&data_alarm[4]==adjusted.Minute&&data_alarm[5]==adjusted.Second)
k=1;
else k=0;
return k;
}
void speak(void)
{uint i=50;
while(i)
{speaker=0;
delay(1);
speaker=1;
delay(1);
i--;
}
}
void alarm(void)
{uint i=10;
while(i)
{
speak();
delay(10);
i--;
}
}
/**************************修改時間操作********************************/
void reset(void)
{
sec_add=0;
min_add=0;
hou_add=0;
day_add=0;
mon_add=0;
yea_add=0 ;
}
void adjust(void)
{
if(key_scan()&&key_flag1)
switch(key_value())
{case '0':sec_add++;break;
case '1':min_add++;break;
case '2':hou_add++;break;
case '3':day_add++;break;
case '4':mon_add++;break;
case '5':yea_add++;break;
case 'b':reset();break;
default: break;
}
adjusted.Second+=sec_add;
adjusted.Minute+=min_add;
adjusted.Hour+=hou_add;
adjusted.Day+=day_add;
adjusted.Month+=mon_add;
adjusted.Year+=yea_add;
if(adjusted.Second>59) adjusted.Second=adjusted.Second%60;
if(adjusted.Minute>59) adjusted.Minute=adjusted.Minute%60;
if(adjusted.Hour>23) adjusted.Hour=adjusted.Hour%24;
if(adjusted.Day>31) adjusted.Day=adjusted.Day%31;
if(adjusted.Month>12) adjusted.Month=adjusted.Month%12;
if(adjusted.Year>100) adjusted.Year=adjusted.Year%100;
}
/**************************中斷處理函數*********************************/
void changing(void) interrupt 0 using 0 //需要修改時間和日期,或者停止修改
{
if(key_flag1)key_flag1=0;
else key_flag1=1;
}
void alarming(void) interrupt 3 using 0 //需要設置鬧鈴或者停止設置
{
if(key_flag2)key_flag2=0;
else key_flag2=1;
}
/********************************主函數***********************************/
main()
{uint i;
uchar *l;
uchar p1[]="D:",p2[]="T:";
SYSTEMTIME T;
EA=1;
EX0=1;
IT0=1;
EA=1;
EX1=1;
IT1=1;
init1602();
Initial_DS1302() ;
while(1)
{ write_com(0x80);
write_string(p1,2);
write_com(0xc0);
write_string(p2,2);
DS1302_GetTime(&T) ;
adjusted.Second=T.Second;
adjusted.Minute=T.Minute;
adjusted.Hour=T.Hour;
adjusted.Week=T.Week;
adjusted.Day=T.Day;
adjusted.Month=T.Month;
adjusted.Year=T.Year;
for(i=0;i<9;i++)
{
adjusted.DateString[i]=T.DateString[i];
adjusted.TimeString[i]=T.TimeString[i];
}
adjust();
if(key_flag2)naoling();
if(according())alarm();
DateToStr(&adjusted);
TimeToStr(&adjusted);
write_com(0x82);
write_string(adjusted.DateString,8);
write_com(0xc2);
write_string(adjusted.TimeString,8);
delay(10);
}
(二)頭文件1 顯示模塊 LCD1602.H
#ifndef LCD_CHAR_1602_2009_5_9
#define LCD_CHAR_1602_2009_5_9
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs = P2^0;
sbit lcdrw = P2^1;
sbit lcden = P2^2;
void delay(uint z) // 延時
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com) // 寫入指令數據到 lcd
{
lcdrw=0;
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date) // 寫入字元顯示數據到 lcd
{
lcdrw=0;
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init1602() // 初始化設定
{
lcdrw=0;
lcden=0;
write_com(0x3C);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
void write_string(uchar *pp,uint n)
{
int i;
for(i=0;i<n;i++)
write_data(pp[i]);
}
#endif
(三)頭文件2 時鍾模塊 DS1302.H
#ifndef _REAL_TIMER_DS1302_2009_5_20_
#define _REAL_TIMER_DS1302_2003_5_20_
sbit DS1302_CLK = P2^6; //實時時鍾時鍾線引腳
sbit DS1302_IO = P2^7; //實時時鍾數據線引腳
sbit DS1302_RST = P2^5; //實時時鍾復位線引腳
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
typedef struct SYSTEM_TIME
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[9]; //用這兩個字元串來放置讀取的時間
unsigned char TimeString[9];
}SYSTEMTIME; //定義的時間類型
#define AM(X) X
#define PM(X) (X+12) // 轉成24小時制
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2) //用於計算 DS1302_RAM 地址的宏
/******內部指令**********/
void DS1302InputByte(unsigned char d) //實時時鍾寫入一位元組(內部函數)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0;
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1; //因為在前面已經定義了ACC0 = ACC^0;以便再次利用DS1302_IO = ACC0;
}
}
unsigned char DS1302OutputByte(void) //實時時鍾讀取一位元組(內部函數)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1;
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
/********************************/
void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要寫的數據
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 寫1Byte數據
DS1302_CLK = 1;
DS1302_RST = 0;
}
unsigned char Read1302(unsigned char ucAddr) //讀取DS1302某地址的數據
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 讀1Byte數據
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
void DS1302_SetProtect(bit flag) //是否防寫
{
if(flag)
Write1302(0x8E,0x10);
else
Write1302(0x8E,0x00);
}
void DS1302_SetTime(unsigned char Address, unsigned char Value) // 設置時間函數
{
DS1302_SetProtect(0);
Write1302(Address, ((Value/10)<<4 | (Value%10))); //將十進制數轉換為BCD碼
} //在DS1302中的與日歷、時鍾相關的寄存器存放的數據必須為BCD碼形式
void DS1302_GetTime(SYSTEMTIME *Time)
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將BCD碼轉換為十進制數
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
}
unsigned char *DataToBCD(SYSTEMTIME *Time)
{
unsigned char D[8];
D[0]=Time->Second/10<<4+Time->Second%10;
D[1]=Time->Minute/10<<4+Time->Minute%10;
D[2]=Time->Hour/10<<4+Time->Hour%10;
D[3]=Time->Day/10<<4+Time->Day%10;
D[4]=Time->Month/10<<4+Time->Month%10;
D[5]=Time->Week/10<<4+Time->Week%10;
D[6]=Time->Year/10<<4+Time->Year%10;
return D;
}
void DateToStr(SYSTEMTIME *Time)
{
//將十進制數轉換為液晶顯示的ASCII值
Time->DateString[0] = Time->Year/10 + '0';
Time->DateString[1] = Time->Year%10 + '0';
Time->DateString[2] = '-';
Time->DateString[3] = Time->Month/10 + '0';
Time->DateString[4] = Time->Month%10 + '0';
Time->DateString[5] = '-';
Time->DateString[6] = Time->Day/10 + '0';
Time->DateString[7] = Time->Day%10 + '0';
Time->DateString[8] = '\0';
}
void TimeToStr(SYSTEMTIME *Time)
{
//將十進制數轉換為液晶顯示的ASCII值
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
Time->DateString[8] = '\0';
}
void Initial_DS1302(void)
{
unsigned char Second;
Second=Read1302(DS1302_SECOND);
if(Second&0x80) //初始化時間
DS1302_SetTime(DS1302_SECOND,0);
}
void DS1302_TimeStop(bit flag) // 是否將時鍾停止
{
unsigned char Data;
Data=Read1302(DS1302_SECOND);
DS1302_SetProtect(0);
if(flag)
Write1302(DS1302_SECOND, Data|0x80);
else
Write1302(DS1302_SECOND, Data&0x7F);
}
#endif
3. 基於單片機51系列及DS1302時鍾晶元數字電子鍾的製作。求電路總原理圖、PCB圖、程序以及元件清單。
元件基本差不多。電路如圖
#include<intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitds1302_RST=P2^0;
sbitds1302_IO =P2^1;
sbitds1302_SCLK=P2^2;
sbitACC0=ACC^0;
sbitACC7=ACC^7;
sbitA1=P3^0;
sbitA2=P3^1;
sbitA3=P3^2;
sbitA4=P3^3;
sbitA5=P3^4;
sbitA6=P3^5;
sbitkey1=P3^6;
sbitkey2=P3^7;
ucharnow_time[3],wei,d[3]={0,0,0};
ucharcodes[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
};
voiddelay(uintx)
{
uchari;
for(x;x>0;x--)
for(i=0;i<100;i++);
}
voiddisp()
{
P1=s[now_time[2]/16];
A1=d[2];
delay(5);
A1=1;
P1=s[now_time[2]%16];
A2=d[2];
delay(5);
A2=1;
P1=s[now_time[1]/16];
A3=d[1];
delay(5);
A3=1;
P1=s[now_time[1]%16];
A4=d[1];
delay(5);
A4=1;
P1=s[now_time[0]/16];
A5=d[0];
delay(5);
A5=1;
P1=s[now_time[0]%16];
A6=d[0];
delay(5);
A6=1;
}
/***********************************************************************/
uchar read_Byte()
{
uchari;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=ds1302_IO;
ds1302_SCLK=1;
ds1302_SCLK=0;
}
return(ACC);
}
void write_Byte(uchartdata)
{
uchari;
ACC=tdata;
for(i=8;i>0;i--)
{
ds1302_IO=ACC0;
ds1302_SCLK=1;
ds1302_SCLK=0;
ACC=ACC>>1;
}
}
/***********************************************************************************/
voidwrite_data_ds1302(uchartaddr,uchartdata)
{
ds1302_RST=0;
ds1302_SCLK=0;
ds1302_RST=1;
write_Byte(taddr);
write_Byte(tdata);
ds1302_RST=0;
ds1302_SCLK=1;
}
ucharread_data_ds1302(uchartaddr)
{
uchartdata;
ds1302_RST=0;
ds1302_SCLK=0;
ds1302_RST=1;
write_Byte(taddr);
tdata=read_Byte();
ds1302_RST=0;
ds1302_SCLK=1;
return(tdata);
}
/***********************************************************************************/
voidget_ds1302()
{
uchark;
uchartaddr=0x81;
for(k=0;k<3;k++)
{
now_time[k]=read_data_ds1302(taddr);
taddr+=2;
}
}
/***********************************************************************************/
voidinit_ds1302()
{
ds1302_RST=0;
ds1302_SCLK=0;
A1=1;
A2=1;
A3=1;
A4=1;
A5=1;
A6=1;
write_data_ds1302(0x80,0x00);
}
/***********************************************************************************/
void Time();
/***********************************************************************************/
main()
{
init_ds1302();
while(1)
{
disp();
get_ds1302();
if(key1==0);
{delay(10);
if(key1==0)
Time();
}
}
}
voidtimer()interrupt3
{
uchari;i++;
TH1=(65535-50000)/256;
TL2=(65535-50000)%256;
if(i==50)
{
d[wei]=1;
}
if(i==100)
{i=0;
d[wei]=0;
}
}
/***********************************************************************************/
void Time()
{
uchartemp;
uintr=0,p=1;
wei=2;
TMOD=0x01;
EA=1;
ET1=1;
TH1=(65535-50000)/256;
TL2=(65535-50000)%256;
TR1=1;
for(r=0;r<50;r++)
disp();
while(key1)
{
wei=2;
disp();
if(key2==0)
{
disp();
if(key2==0)
{
temp=now_time[2]/16*10+now_time[2]%16;
temp++;
if(temp>=24)
temp=0;
now_time[2]=temp/10*16+temp%10;
write_data_ds1302(0x84,now_time[2]);
}
while(!key2);
}
}
wei=1;
d[2]=0;
for(r=0;r<50;r++)
disp();
while(key1)
{disp();
if(key2==0)
{
disp();
if(key2==0)
{
temp=now_time[1]/16*10+now_time[1]%16;
temp++;
if(temp>=60)
temp=0;
now_time[1]=temp/10*16+temp%10;
write_data_ds1302(0x82,now_time[1]);
}
while(!key2);
}
}
wei=0;
d[1]=0;
for(r=0;r<50;r++)
disp();
while(key1)
{
disp();
if(key2==0)
{
now_time[0]=0;
write_data_ds1302(0x80,now_time[0]);
}
} TR1=0;
d[0]=0;
for(r=0;r<30;r++)
disp();
}
按圖安裝即可,祝你成功。
4. 51單片機 製作 日歷時鍾 用匯編語言 要詳細的代碼和硬體圖示
這給圖能幫助你,不用太感激我,我很低調的。