|
50黑幣
最近師傅交給實(shí)時(shí)時(shí)鐘學(xué)習(xí),不講解不提示總之自己搞定,IIC協(xié)議早期學(xué)過(guò),可是DS1307實(shí)在是頭疼得很,不知是什么原因無(wú)法在數(shù)碼管顯示正確的時(shí)間,資料也查了很多還是沒(méi)有頭緒,已陷入死胡同無(wú)法走出,已經(jīng)第3天了還是束手無(wú)策,實(shí)屬無(wú)奈,望各位大師給予幫助不勝感激!!
P0數(shù)碼管顯示,74HC595控制數(shù)碼管位碼。年,月,日,時(shí),分,秒,星期。
單片機(jī)源程序如下:
#include <reg52.h>
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit sda=P2^0;//;模擬I2C 數(shù)據(jù)傳送位
sbit scl=P2^1;//;模擬I2C 時(shí)鐘控制狀態(tài)標(biāo)志
sbit SER = P1^2; //數(shù)據(jù)輸入
sbit SCK = P1^0; //串行移位時(shí)鐘
sbit RCK = P1^1; //鎖存器時(shí)鐘
sbit tiao=P1^3; //調(diào)節(jié)鍵
sbit jia =P1^4; //按鍵+
sbit jian=P1^5; //按鍵-
uchar Hours,Minutes,Seconds,Year,Month,Date,Weeks;
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar data dis_buf[]={0,0,0xbf,0,0,0xbf,0,0};//顯示緩存
void hc595(uchar Data)//74HC595的數(shù)據(jù)串入并出子程序
{
uchar i;
for(i=0;i<8;i++) //由高位到低位發(fā)送一個(gè)字節(jié)
{
Data<<=1; //左移一位,最高位溢出到位寄存器CY
SER=CY; //從位寄存器的進(jìn)位標(biāo)志位CY讀取
SCK = 0; //串行移位
SCK = 1;
}
RCK = 0; //鎖存
RCK = 1;
}
uchar Decimal_to_BCD(uchar temp)//十進(jìn)制轉(zhuǎn)換成BCD碼
{
uchar a,b,c;
a=temp;
b=0;
while(a>=10)
{
a=a-10;
b=b+16;
c=a+b;
temp=c;
}
return temp;
}
uchar BCD_to_Decimal(uchar temp)//BCD碼轉(zhuǎn)換成十進(jìn)制
{
uchar a,b,c;
a=temp;
b=0;
while(a>=16)
{
a=a-16;
b=b+10;
c=a+b;
temp=c;
}
return temp;
}
void delay_5us()//5us延時(shí)
{
_nop_();
_nop_();
_nop_();
}
void star_1307()//開(kāi)始
{
sda=1;
delay_5us();//5us延時(shí)
scl=1;
delay_5us();//5us延時(shí)
sda=0;
delay_5us();//5us延時(shí)
}
void stop_1307()//停止
{
sda=0;
delay_5us();//5us延時(shí)
scl=1;
delay_5us();//5us延時(shí)
sda=1;
delay_5us();//5us延時(shí)
}
void ack_1307()//應(yīng)答
{
uchar z=0;
while((sda==1)&&(z<50))z++;//條件判斷, sda=1,則沒(méi)有應(yīng)答。如果沒(méi)有應(yīng)答則延時(shí):z<50,z++;后返回
scl=0;
delay_5us();//5us延時(shí)
}
void write_1307(uchar slave_write_address,uchar byte_address,uchar data_data)//寫一個(gè)數(shù)據(jù)
{
uchar temp,temp1,i,ii;
star_1307(); //開(kāi)始
for(ii=0;ii<3;ii++)//根據(jù) 24CXX文檔資料,和時(shí)序圖,按順序送:器件寫地址,字節(jié)地址,數(shù)據(jù)
{
if(ii==0)
{
temp=slave_write_address;//送 器件寫地址
temp1=slave_write_address;
}
else if(ii==1)
{
temp=byte_address;//送 字節(jié)地址
temp1=byte_address;
}
else if(ii==2)
{
temp=data_data;//送 數(shù)據(jù)
temp1=data_data;
}
for(i=0;i<8;i++)
{
scl=0;
delay_5us();//5us延時(shí)
temp=temp1;
temp=temp&0x80;//相 與 后,把不相關(guān)的位清零
if(temp==0x80)//根據(jù)前面 相 與 后,判斷 temp是否等于0x80,是則該位為 1
sda=1;
else
sda=0;
delay_5us();//5us延時(shí)
scl=1;
delay_5us();//5us延時(shí)
scl=0;
delay_5us();//5us延時(shí)
temp1=temp1<<1;//向左移出1位
}
sda=1;
delay_5us();//5us延時(shí)
scl=1;
delay_5us();//5us延時(shí)
ack_1307();
}
stop_1307();//停止
}
uchar read_1307(uchar slave_write_address,uchar byte_address,uchar slave_read_address) //讀一個(gè)數(shù)據(jù)
{
uchar temp,temp1,i,ii,x,data_data;
star_1307(); //開(kāi)始
for(ii=0;ii<3;ii++) //根據(jù) 24CXX文檔資料,和時(shí)序圖,按順序送:器件寫地址,字節(jié)地址,器件讀地址
{
if(ii==0)
{
temp=slave_write_address; //送 器件寫地址
temp1=slave_write_address;
}
else if(ii==1)
{
temp=byte_address; //送 字節(jié)地址
temp1=byte_address;
}
else if(ii==2)
{
star_1307(); //開(kāi)始
temp=slave_read_address; //送 器件讀地址
temp1=slave_read_address;
}
for(i=0;i<8;i++) //開(kāi)始讀數(shù)據(jù)
{
scl=0;
delay_5us(); //5us延時(shí)
temp=temp1;
temp=temp&0x80; // 相 與 后,把不相關(guān)的位清零
if(temp==0x80) //根據(jù)前面 相 與 后,判斷 temp是否等于0x80,是則該位為 1
sda=1;
else
sda=0;
delay_5us(); //5us延時(shí)
scl=1;
delay_5us(); //5us延時(shí)
scl=0;
delay_5us(); //5us延時(shí)
temp1=temp1<<1; //向左移出1位
}
sda=1;
delay_5us(); //5us延時(shí)
scl=1;
delay_5us(); //5us延時(shí)
ack_1307(); //應(yīng)答
}
for(x=0;x<8;x++)
{
data_data=data_data<<1; //向左移入1位
sda=1;
delay_5us(); //5us延時(shí)
scl=0;
delay_5us(); //5us延時(shí)
scl=1;
delay_5us(); //5us延時(shí)
if(sda==1) //判斷 數(shù)據(jù)線是否是高電平
data_data|=0x01; //把讀到的數(shù)據(jù) 或 0X01
}
ack_1307(); //應(yīng)答
stop_1307(); //停止
return data_data; //返回讀到的數(shù)據(jù)
}
void init_1307() //初始化
{
Hours=23;
Minutes=14;
Seconds=11;
Year=17;
Month=11;
Date=24;
Weeks=5;
Seconds=Decimal_to_BCD(Seconds); //十進(jìn)制轉(zhuǎn)換成BCD碼
Minutes=Decimal_to_BCD(Minutes); //十進(jìn)制轉(zhuǎn)換成BCD碼
Hours=Decimal_to_BCD(Hours); //十進(jìn)制轉(zhuǎn)換成BCD碼
Date=Decimal_to_BCD(Date); //十進(jìn)制轉(zhuǎn)換成BCD碼
Year=Decimal_to_BCD(Year); //十進(jìn)制轉(zhuǎn)換成BCD碼
Month=Decimal_to_BCD(Month); //十進(jìn)制轉(zhuǎn)換成BCD碼
write_1307(0xd0,0x00,Seconds); //寫入秒
write_1307(0xd0,0x01,Minutes); //寫入分
write_1307(0xd0,0x02,Hours); //寫入時(shí)
write_1307(0xd0,0x03,Weeks); //寫入星期
write_1307(0xd0,0x04,Date); //寫入日期
write_1307(0xd0,0x05,Month); //寫入月
write_1307(0xd0,0x06,Year); //寫入年
}
void read_time_1307()
{
Seconds=read_1307(0xd0,0x00,0xd1); //讀秒
Seconds=BCD_to_Decimal(Seconds); //BCD碼轉(zhuǎn)換成十進(jìn)制
Minutes=read_1307(0xd0,0x01,0xd1); //讀分
Minutes=BCD_to_Decimal(Minutes); //BCD碼轉(zhuǎn)換成十進(jìn)制
Hours=read_1307(0xd0,0x02,0xd1); //讀時(shí)
Hours=BCD_to_Decimal(Hours); //BCD碼轉(zhuǎn)換成十進(jìn)制
Year=read_1307(0xd0,0x06,0xd1); //讀年
Year=BCD_to_Decimal(Year); //BCD碼轉(zhuǎn)換成十進(jìn)制
Date=read_1307(0xd0,0x04,0xd1); //讀日
Date=BCD_to_Decimal(Date); //BCD碼轉(zhuǎn)換成十進(jìn)制
Month=read_1307(0xd0,0x05,0xd1); //讀月
Month=BCD_to_Decimal(Month); //BCD碼轉(zhuǎn)換成十進(jìn)制
Weeks=read_1307(0xd0,0x03,0xd1); //讀周
}
|
|