標題:
關(guān)于DS1307時鐘芯片的讀寫問題
[打印本頁]
作者:
wolfchuang
時間:
2018-6-24 14:29
標題:
關(guān)于DS1307時鐘芯片的讀寫問題
使用STC的15W系列單片機對DS1307進行時間的讀寫,讀出來的數(shù)據(jù)全是00,求高手指點,代碼如下:
#define MAIN_Fosc 12000000L //定義主時鐘
#include "STC15Fxxxx.H"
#define Baudrate1 9600L
#define CNT_END 12000
#define DS1307_ADDR 0xD0
sbit WARNING=P3^3;
sbit I2C_SCL=P5^5; //時鐘信號引腳定義
sbit I2C_SDA=P5^4; //數(shù)據(jù)信號引腳定義
//sbit I2C_SCL=P1^6; //時鐘信號引腳定義
//sbit I2C_SDA=P1^7; //數(shù)據(jù)信號引腳定義
u8 B_TX1_Busy=0;
u8 Send_Buff[16];
u8 DS1307_Data[7]={0}; //數(shù)據(jù)讀出緩存
u8 DS1307_Buff[7]={0,57,13,7,27,5,18}; //數(shù)據(jù)寫入緩存
u8 i;
u16 cnt=0;
bit temp_flag=0;
void UART1_Config_withT2(u16 dat); // 選擇波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
void delay_ms(u8 ms);
void DelayXus(u8 n);
void Send_I2C_Byte(u8 txd);
u8 Receive_I2C(void);
u8 read_byte(u8 add);
void write_byte(u8 add,u8 dat);
void SendByte(u8 dat);
void Read_RTC(u8 *p);
void Set_RTC(u8 *p);
//========================================================================
// 函數(shù): void main(void)
// 描述: 主函數(shù)
//========================================================================
void main(void)
{
P1M1 = 0; P1M0 = 1; //設(shè)置為準雙向口
P3M1 = 0; P3M0 = 1; //設(shè)置為準雙向口
P5M1 = 0; P5M0 = 0; //設(shè)置為準雙向口
WARNING=0;
I2C_SCL=1;
I2C_SDA=1;
UART1_Config_withT2(2);
EA=1;
Set_RTC(DS1307_Buff); //設(shè)置時間
//向其他寄存器寫入數(shù)據(jù)
write_byte(0x09,0xF1);
while (1)
{
delay_ms(200);
delay_ms(200);
delay_ms(200);
delay_ms(200);
delay_ms(200);
SendByte(read_byte(0x09));
//讀取時間測試
Read_RTC(DS1307_Data); //讀取時間
for(i=0;i<7;i++) //讀取時間并用串口發(fā)送
{
SendByte(DS1307_Data[i]);
}
SendByte(read_byte(0x09));
}
}
//========================================================================
// 描述: 設(shè)置Timer2做波特率發(fā)生器。
// 參數(shù): dat: Timer2的重裝值.
//========================================================================
void UART1_Config_withT2(u16 dat) // 選擇波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
{
AUXR |= 0x01; //S1 BRT Use Timer2;
AUXR &= ~(1<<4); //Timer stop
AUXR &= ~(1<<3); //Timer2 set As Timer
AUXR |= (1<<2); //Timer2 set as 1T mode
TH2 = dat / 256;
TL2 = dat % 256;
IE2 &= ~(1<<2); //禁止中斷
AUXR |= (1<<4); //Timer run enable
SCON = (SCON & 0x3f) | 0x40; //UART1模式, 0x00: 同步移位輸出, 0x40: 8位數(shù)據(jù),可變波特率, 0x80: 9位數(shù)據(jù),固定波特率, 0xc0: 9位數(shù)據(jù),可變波特率
// PS = 1; //高優(yōu)先級中斷
ES = 1; //允許中斷
REN = 1; //允許接收
P_SW1 &= 0x3f;
P_SW1 |= 0x00; //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7 (必須使用內(nèi)部時鐘)
// PCON2 |= (1<<4); //內(nèi)部短路RXD與TXD, 做中繼, ENABLE,DISABLE
B_TX1_Busy = 0;
}
/*--------------------------------延時相關(guān)函數(shù)--------------------------------*/
void delay_ms(u8 ms)
{
unsigned int i;
do{
i = MAIN_Fosc / 13000;
while(--i) ; //14T per loop
}while(--ms);
}
/**************************************
延時X微秒(@12M)
不同的工作環(huán)境,需要調(diào)整此函數(shù)
此延時函數(shù)是使用1T的指令周期進行計算,與傳統(tǒng)的12T的MCU不同
**************************************/
void DelayXus(u8 n)
{
while (n--)
{
_nop_();
_nop_();
}
}
/*-------------------------------IIC通信相關(guān)函數(shù)-----------------------------------*/
void Start_I2C() //啟動IIC
{
I2C_SDA=1;
DelayXus(1);
I2C_SCL=1;
DelayXus(3);
I2C_SDA=0;
DelayXus(3);
I2C_SCL=0;
}
void Stop_I2C() //關(guān)閉IIC
{
I2C_SDA=0;
DelayXus(3);
I2C_SCL=1;
DelayXus(3);
I2C_SDA=1;
DelayXus(3);
I2C_SCL=0;
}
bit Wait_Ack(void) //等待應(yīng)答信號
{
u8 ucErrTime=0;
I2C_SCL=1;
DelayXus(3);
while(I2C_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
Stop_I2C();
return 1;
}
}
I2C_SCL=1;
return 0;
}
void I2CAck() //發(fā)送應(yīng)答信號
{
I2C_SCL=1;
DelayXus(3);
I2C_SDA=1;
DelayXus(3);
I2C_SCL=0;
}
void I2CNotAck() //發(fā)送非應(yīng)答信號
{
I2C_SCL=1;
DelayXus(3);
I2C_SDA=0;
DelayXus(3);
I2C_SCL=0;
}
void Send_I2C_Byte(u8 txd) //在總線上發(fā)送一個字節(jié)
{
u8 i;
for(i=0;i<8;i++)
{
I2C_SCL=0;
DelayXus(3);
if(txd&0x80)
I2C_SDA=1;
else
I2C_SDA=0;
txd<<=1;
DelayXus(3);
I2C_SCL=1;
DelayXus(3);
}
I2C_SCL=0;
}
u8 Receive_I2C() //在總線上接收一個字節(jié)
{
u8 i,receive=0,Data_R;
I2C_SCL=1;
DelayXus(3);
for(i=0;i<8;i++ )
{
I2C_SCL=0;
DelayXus(3);
I2C_SCL=1;
DelayXus(3);
Data_R=I2C_SDA;
if(Data_R==0X08)
receive|=0X80>>i;
}
I2C_SCL=0;
DelayXus(3);
return receive;
}
u8 read_byte(u8 add) //從D1307指定地址讀出一個字節(jié)數(shù)據(jù)
{
u8 dat,temp;
Start_I2C();
Send_I2C_Byte(DS1307_ADDR);
Wait_Ack();
Send_I2C_Byte(add);
Wait_Ack();
Stop_I2C();
Start_I2C();
Send_I2C_Byte(DS1307_ADDR+1);
Wait_Ack();
dat=Receive_I2C();
I2CAck();
Stop_I2C();
temp=dat/16;
dat=dat%16;
dat=dat+temp*10;
return dat;
}
void write_byte(u8 add,u8 dat) //向D1307中地址為address的寄存器寫入一字節(jié)數(shù)據(jù)
{
u8 temp;
temp=dat/10;
temp<<=4;
temp=dat%10+temp;
Start_I2C();
Send_I2C_Byte(DS1307_ADDR);
Wait_Ack();
Send_I2C_Byte(add);
Wait_Ack();
Send_I2C_Byte(temp);
Stop_I2C();
}
void Read_RTC(u8 *p) //讀取時間
{
u8 i;
for(i=0;i<7;i++)
{
p[i]=(read_byte(i));
}
}
void Set_RTC(u8 *p) //設(shè)置時間
{
u8 i,temp,dat;
Start_I2C();
Send_I2C_Byte(DS1307_ADDR);
Wait_Ack();
Send_I2C_Byte(0);
Wait_Ack();
for(i=0;i<7;i++)
{
dat=*p;
temp=dat/10;
temp<<=4;
temp=dat%10+temp;
Send_I2C_Byte(temp);
p++;
Wait_Ack();
}
Stop_I2C();
}
void SendByte(u8 dat)
{
B_TX1_Busy = 1; //標志發(fā)送忙
SBUF = dat; //發(fā)一個字節(jié)
while(B_TX1_Busy > 0); //等待發(fā)送完成
}
//========================================================================
// 函數(shù): void UART1_int (void) interrupt UART1_VECTOR
// 描述: UART1中斷函數(shù)。
//========================================================================
void UART1_int (void) interrupt 4
{
if(RI)
{
RI = 0;
}
if(TI)
{
TI = 0;
B_TX1_Busy = 0;
}
}
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1