求用C語言編寫壹個單片機89C51電子時鐘程序,有時,分,秒,還有電路圖
#include <task.h>
/******************************************************************/
sbit T_CLK=P3^5;? //DS1302引腳連接
sbit T_IO =P3^6;
sbit T_RST=P3^7;
sbit ACC0=ACC^0;? //1bit數據存儲位
sbit ACC7=ACC^7;
uchar starts_time[7]={0x00,0x10,0x22,0x20,0x05,0x04,0x10};? //初始化後設置
uchar Sec;
uchar Cent;
uchar Hour;
uchar Year;
uchar Day;
uchar Week;
uchar Month;
/******************************************************************/
//根據選擇調整相應項目
void Set(uchar sel,uchar sel_1)
{
uchar address,time; uchar max,min; if(sel==1)? {address=0x84; max=23;min=0;} //小時 if(sel==2)? {address=0x82; max=59;min=0;} //分鐘 if(sel==3)? {address=0x88; max=12;min=1;} //月 if(sel==4)? {address=0x86; max=31;min=1;} //日 if(sel==5)? {address=0x8a; max=7;min=1;} //星期 time=R1302(address+1)/16*10+R1302(address+1)%16; //變成BCD碼 if (sel_1==1) time++;? else time--; if(time>max) time=min;? if(time<min) time=max; W1302(0x8e,0x00); W1302(address,time/10*16+time%10);? W1302(0x8e,0x80);?}
//********DS1302讀寫程序***************///********************************************************************
函 數 名:RTInputByte()
功 能:實時時鐘寫入壹字節
說 明:往DS1302寫入1Byte數據 (內部函數)
入口參數:d 寫入的數據
返 回 值:無?
***********************************************************************/
void RTInputByte(uchar d)
{
uchar h;
ACC = d;
for(h=8; h>0; h--)
{
T_IO = ACC0;? /*相當於匯編中的 RRC */
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
uchar RTOutputByte(void)
{
uchar h;
for(h=8; h>0; h--)
{
ACC = ACC >>1; /*相當於匯編中的 RRC */
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/***************************************************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr);? /* 地址,命令 */
RTInputByte(ucDa);? /* 寫1Byte數據*/
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
函 數 名:R1302()
功 能:讀取DS1302某地址的數據
說 明:先寫地址,後讀命令/數據 (內部函數)
調 用:RTInputByte() , RTOutputByte()
入口參數:ucAddr: DS1302地址
返 回 值:ucData :讀取的數據
***********************************************************************/
uchar R1302(uchar ucAddr)
{
uchar ucData;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
ucData = RTOutputByte(); /* 讀1Byte數據 */
T_CLK = 1;
T_RST = 0;
return(ucData);
}
/********************************************************************
函 數 名:Set1302()
功 能:設置初始時間
說 明:先寫地址,後讀命令/數據(寄存器多字節方式)
調 用:W1302()
入口參數:pClock: 設置時鐘數據地址 格式為: 秒 分 時 日 月 星期 年
7Byte (BCD碼)1B 1B 1B 1B 1B? 1B? 1B返 回 值:無
***********************************************************************/
void Set1302(uchar *pClock)
{
uchar h;
uchar ucAddr = 0x80;
W1302(0x8e,0x00);? /* 控制命令,WP=0,寫操作?*/
for(h =7; h>0; h--)
{
W1302(ucAddr,*pClock);? /* 秒 分 時 日 月 星期 年 */
pClock++;
ucAddr +=2;
}
W1302(0xc0,0x01); W1302(0XC2,0X03);//初始自動轉換顯示時間為3秒。W1302(0x8e,0x80);? /* 控制命令,WP=1,寫保護?*/
}
void Auto_Set1302(uchar *pClock)
{
uchar h;
uchar ucAddr = 0x80;
if(((R1302(0x81))&0x80)==0x80) {W1302(0x8e,0x00);? /* 控制命令,WP=0,寫操作?*/
for(h =7; h>0; h--)
{
W1302(ucAddr,*pClock);? /* 秒 分 時 日 月 星期 年 */
pClock++;
ucAddr +=2;
}
W1302(ucNumRows_adder,0);
W1302(ucNumRows_p_adder,0);
W1302(DISP_TIME_adder,170);
W1302(0xc0,0x01); W1302(0XC2,0X03);//初始自動轉換顯示時間為3秒。W1302(0x8e,0x80);? /* 控制命令,WP=1,寫保護?*/
?}
}
/******************讀取DS1302中的時間****************/
void du1302()
{
Sec=R1302(0x81);? //對取 秒 分 時 日 月 星期 年 Cent=R1302(0x83); Hour=R1302(0x85); Day=R1302(0x87); Month=R1302(0x89); Week=R1302(0x8b); Year=R1302(0x8d); //b=R1302(0xc1); //a=R1302(0xc3); //a=a/16*10+a%16;}
void? write_1302Data (uchar? ucAddr,uchar? Value)
{?
W1302(0x8e,0x00);? /* 控制命令,WP=0,寫操作?*/W1302(ucAddr,Value); //地址和數據
W1302(0x8e,0x80);? /* 控制命令,WP=1,寫保護?*/
}