當前位置:編程學習大全網 - 編程語言 - 如何讀出DS1302裏面的時鐘數據?

如何讀出DS1302裏面的時鐘數據?

#include <REG51.H>

#include <intrins.h>

//#include "LCD1602.h"

//#include "DS1302.h"

#define uint unsigned int

#define uchar unsigned char

sbit DS1302_CLK = P1^7; //實時時鐘時鐘線引腳

sbit DS1302_IO = P1^6; //實時時鐘數據線引腳

sbit DS1302_RST = P1^5; //實時時鐘復位線引腳

sbit wireless_1 = P3^0;

sbit wireless_2 = P3^1;

sbit wireless_3 = P3^2;

sbit wireless_4 = P3^3;

sbit ACC0 = ACC^0;

sbit ACC7 = ACC^7;

char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,時到日,月,年位閃的計數

sbit Set = P2^0; //模式切換鍵

sbit Up = P2^1; //加法按鈕

sbit Down = P2^2; //減法按鈕

sbit out = P2^3; //立刻跳出調整模式按鈕

char done,count,temp,flag,up_flag,down_flag;

uchar TempBuffer[5],week_value[2];

/***********DS1302時鐘部分子程序******************/

typedef struct __SYSTEMTIME__

{

unsigned char Second;

unsigned char Minute;

unsigned char Hour;

unsigned char Week;

unsigned char Day;

unsigned char Month;

unsigned char Year;

unsigned char DateString[11];

unsigned char TimeString[9];

}SYSTEMTIME; //定義的時間類型

SYSTEMTIME CurrentTime;

#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

void DS1302InputByte(unsigned char d) //實時時鐘寫入壹字節(內部函數)

{

unsigned char i;

ACC = d;

for(i=8; i>0; i--)

{

DS1302_IO = ACC0; //相當於匯編中的 RRC

DS1302_CLK = 1;

DS1302_CLK = 0;

ACC = ACC >> 1;

}

}

unsigned char DS1302OutputByte(void) //實時時鐘讀取壹字節(內部函數)

{

unsigned char i;

for(i=8; i>0; i--)

{

ACC = ACC >>1; //相當於匯編中的 RRC

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_GetTime(SYSTEMTIME *Time) //獲取時鐘芯片的時鐘數據到自定義的結構型數組

{

unsigned char ReadValue;

ReadValue = Read1302(DS1302_SECOND);

Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);

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);

}

void DateToStr(SYSTEMTIME *Time) //將時間年,月,日,星期數據轉換成液晶顯示字符串,放到數組裏DateString[]

{ if(hide_year<2) //這裏的if,else語句都是判斷位閃爍,<2顯示數據,>2就不顯示,輸出字符串為 2007/07/22

{

Time->DateString[0] = '2';

Time->DateString[1] = '0';

Time->DateString[2] = Time->Year/10 + '0';

Time->DateString[3] = Time->Year%10 + '0';

}

else

{

Time->DateString[0] = ' ';

Time->DateString[1] = ' ';

Time->DateString[2] = ' ';

Time->DateString[3] = ' ';

}

Time->DateString[4] = '/';

if(hide_month<2)

{

Time->DateString[5] = Time->Month/10 + '0';

Time->DateString[6] = Time->Month%10 + '0';

}

else

{

Time->DateString[5] = ' ';

Time->DateString[6] = ' ';

}

Time->DateString[7] = '/';

if(hide_day<2)

{

Time->DateString[8] = Time->Day/10 + '0';

Time->DateString[9] = Time->Day%10 + '0';

}

else

{

Time->DateString[8] = ' ';

Time->DateString[9] = ' ';

}

if(hide_week<2)

{

week_value[0] = Time->Week%10 + '0'; //星期的數據另外放到 week_value[]數組裏,跟年,月,日的分開存放,因為等壹下要在最後顯示

}

else

{

week_value[0] = ' ';

}

week_value[1] = '\0';

Time->DateString[10] = '\0'; //字符串末尾加 '\0' ,判斷結束字符

}

void TimeToStr(SYSTEMTIME *Time) //將時,分,秒數據轉換成液晶顯示字符放到數組 TimeString[];

{ if(hide_hour<2)

{

Time->TimeString[0] = Time->Hour/10 + '0';

Time->TimeString[1] = Time->Hour%10 + '0';

}

else

{

Time->TimeString[0] = ' ';

Time->TimeString[1] = ' ';

}

Time->TimeString[2] = ':';

if(hide_min<2)

{

Time->TimeString[3] = Time->Minute/10 + '0';

Time->TimeString[4] = Time->Minute%10 + '0';

}

else

{

Time->TimeString[3] = ' ';

Time->TimeString[4] = ' ';

}

Time->TimeString[5] = ':';

if(hide_sec<2)

{

Time->TimeString[6] = Time->Second/10 + '0';

Time->TimeString[7] = Time->Second%10 + '0';

}

else

{

Time->TimeString[6] = ' ';

Time->TimeString[7] = ' ';

}

Time->DateString[8] = '\0';

}

void Initial_DS1302(void) //時鐘芯片初始化

{

unsigned char Second="Read1302"(DS1302_SECOND);

if(Second&0x80) //判斷時鐘芯片是否關閉

{

Write1302(0x8e,0x00); //寫入允許

Write1302(0x8c,0x07); //以下寫入初始化時間 日期:07/07/25.星期: 3. 時間: 23:59:55

Write1302(0x88,0x07);

Write1302(0x86,0x25);

Write1302(0x8a,0x07);

Write1302(0x84,0x23);

Write1302(0x82,0x59);

Write1302(0x80,0x55);

Write1302(0x8e,0x80); //禁止寫入

}

}

void Upkey()//升序按鍵

{

Up=1;

if(Up==0||wireless_2==1)

{

mdelay(8);

switch(count)

{case 1:

temp="Read1302"(DS1302_SECOND); //讀取秒數

temp="temp"+1; //秒數加1

up_flag=1; //數據調整後更新標誌

if((temp&0x7f)>0x59) //超過59秒,清零

temp="0";

break;

case 2:

temp="Read1302"(DS1302_MINUTE); //讀取分數

temp="temp"+1; //分數加1

up_flag=1;

if(temp>0x59) //超過59分,清零

temp="0";

break;

case 3:

temp="Read1302"(DS1302_HOUR); //讀取小時數

temp="temp"+1; //小時數加1

up_flag=1;

if(temp>0x23) //超過23小時,清零

temp="0";

break;

case 4:

temp="Read1302"(DS1302_WEEK); //讀取星期數

temp="temp"+1; //星期數加1

up_flag=1;

if(temp>0x7)

temp="1";

break;

case 5:

temp="Read1302"(DS1302_DAY); //讀取日數

temp="temp"+1; //日數加1

up_flag=1;

if(temp>0x31)

temp="1";

break;

case 6:

temp="Read1302"(DS1302_MONTH); //讀取月數

temp="temp"+1; //月數加1

up_flag=1;

if(temp>0x12)

temp="1";

break;

case 7:

temp="Read1302"(DS1302_YEAR); //讀取年數

temp="temp"+1; //年數加1

up_flag=1;

if(temp>0x85)

temp="0";

break;

default:break;

}

while(Up==0);

while(wireless_2==1);

}

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Downkey()//降序按鍵

{

Down=1;

if(Down==0||wireless_3==1)

{

mdelay(8);

switch(count)

{case 1:

temp="Read1302"(DS1302_SECOND); //讀取秒數

temp="temp-1"; //秒數減1

down_flag=1; //數據調整後更新標誌

if(temp==0x7f) //小於0秒,返回59秒

temp="0x59";

break;

case 2:

temp="Read1302"(DS1302_MINUTE); //讀取分數

temp="temp-1"; //分數減1

down_flag=1;

if(temp==-1)

temp="0x59"; //小於0秒,返回59秒

break;

case 3:

temp="Read1302"(DS1302_HOUR); //讀取小時數

temp="temp-1"; //小時數減1

down_flag=1;

if(temp==-1)

temp="0x23";

break;

case 4:

temp="Read1302"(DS1302_WEEK); //讀取星期數

temp="temp-1"; //星期數減1

down_flag=1;

if(temp==0)

temp="0x7";;

break;

case 5:

temp="Read1302"(DS1302_DAY); //讀取日數

temp="temp-1"; //日數減1

down_flag=1;

if(temp==0)

temp="31";

break;

case 6:

temp="Read1302"(DS1302_MONTH); //讀取月數

temp="temp-1"; //月數減1

down_flag=1;

if(temp==0)

temp="12";

break;

case 7:

temp="Read1302"(DS1302_YEAR); //讀取年數

temp="temp-1"; //年數減1

down_flag=1;

if(temp==-1)

temp="0x85";

break;

default:break;

}

while(Down==0);

while(wireless_3==1);

}

}

void Setkey()//模式選擇按鍵

{

Set=1;

if(Set==0||wireless_4==1)

{

mdelay(8);

count="count"+1; //Setkey按壹次,count就加1

done="1"; //進入調整模式

while(Set==0);

while(wireless_4==1);

}

}

void keydone()//按鍵功能執行

{ uchar Second;

if(flag==0) //關閉時鐘,停止計時

{ Write1302(0x8e,0x00); //寫入允許

temp="Read1302"(0x80);

Write1302(0x80,temp|0x80);

Write1302(0x8e,0x80); //禁止寫入

flag="1";

}

Setkey(); //掃描模式切換按鍵

switch(count)

{case 1:do //count=1,調整秒

{

outkey(); //掃描跳出按鈕

Upkey(); //掃描加按鈕

Downkey(); //掃描減按鈕

if(up_flag==1||down_flag==1) //數據更新,重新寫入新的數據

{

Write1302(0x8e,0x00); //寫入允許

Write1302(0x80,temp|0x80); //寫入新的秒數

Write1302(0x8e,0x80); //禁止寫入

up_flag=0;

down_flag=0;

}

hide_sec++; //位閃計數

if(hide_sec>3)

hide_sec=0;

show_time(); //液晶顯示數據

}while(count==2);break;

case 2:do //count=2,調整分

{

hide_sec=0;

outkey();

Upkey();

Downkey();

if(temp>0x60)

temp="0";

if(up_flag==1||down_flag==1)

{

Write1302(0x8e,0x00); //寫入允許

Write1302(0x82,temp); //寫入新的分數

Write1302(0x8e,0x80); //禁止寫入

up_flag=0;

down_flag=0;

}

hide_min++;

if(hide_min>3)

hide_min=0;

show_time();

}while(count==3);break;

case 3:do //count=3,調整小時

{

hide_min=0;

outkey();

Upkey();

Downkey();

if(up_flag==1||down_flag==1)

{

Write1302(0x8e,0x00); //寫入允許

Write1302(0x84,temp); //寫入新的小時數

Write1302(0x8e,0x80); //禁止寫入

up_flag=0;

down_flag=0;

}

hide_hour++;

if(hide_hour>3)

hide_hour=0;

show_time();

}while(count==4);break;

case 4:do //count=4,調整星期

{

hide_hour=0;

outkey();

Upkey();

Downkey();

if(up_flag==1||down_flag==1)

{

Write1302(0x8e,0x00); //寫入允許

Write1302(0x8a,temp); //寫入新的星期數

Write1302(0x8e,0x80); //禁止寫入

up_flag=0;

down_flag=0;

}

hide_week++;

if(hide_week>3)

hide_week=0;

show_time();

}while(count==5);break;

case 5:do //count=5,調整日

{

hide_week=0;

outkey();

Upkey();

Downkey();

if(up_flag==1||down_flag==1)

{

Write1302(0x8e,0x00); //寫入允許

Write1302(0x86,temp); //寫入新的日數

Write1302(0x8e,0x80); //禁止寫入

up_flag=0;

down_flag=0;

}

hide_day++;

if(hide_day>3)

hide_day=0;

show_time();

}while(count==6);break;

case 6:do //count=6,調整月

{

hide_day=0;

outkey();

Upkey();

Downkey();

if(up_flag==1||down_flag==1)

{

Write1302(0x8e,0x00); //寫入允許

Write1302(0x88,temp); //寫入新的月數

Write1302(0x8e,0x80); //禁止寫入

up_flag=0;

down_flag=0;

}

hide_month++;

if(hide_month>3)

hide_month=0;

show_time();

}while(count==7);break;

case 7:do //count=7,調整年

{

hide_month=0;

outkey();

Upkey();

Downkey();

if(up_flag==1||down_flag==1)

{

Write1302(0x8e,0x00); //寫入允許

Write1302(0x8c,temp); //寫入新的年數

Write1302(0x8e,0x80); //禁止寫入

up_flag=0;

down_flag=0;

}

hide_year++;

if(hide_year>3)

hide_year=0;

show_time();

}while(count==8);break;

case 8: count="0";hide_year=0; //count8, 跳出調整模式,返回默認顯示狀態

Second="Read1302"(DS1302_SECOND);

Write1302(0x8e,0x00); //寫入允許

Write1302(0x80,Second&0x7f);

Write1302(0x8E,0x80); //禁止寫入

done="0";

break; //count=7,開啟中斷,標誌位置0並退出

default:break;

}

}

  • 上一篇:壁紙顏色對心情的影響有多大?
  • 下一篇:急求:用匯編語言編寫壹個多字節非壓縮BCD加法程序,要求有註釋哦,萬分感謝!!!十萬火急!!!
  • copyright 2024編程學習大全網