初级会员
- 积分
- 121
- 金钱
- 121
- 注册时间
- 2014-12-1
- 在线时间
- 17 小时
|
5金钱
使用STC的15W系列单片机进行DS1307读写时遇到问题:读出来的数据都是00,程序是参考:http://www.openedv.com/forum.php?mod=viewthread&tid=20167&highlight=ds1307中3楼原子哥给的附件程序移植的,程序如下,请大家帮忙指正:[mw_shl_code=c,true]#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; //数据信号引脚定义
//sbit I2C_SCL=P1^6; //时钟信号引脚定义
//sbit I2C_SDA=P1^7; //数据信号引脚定义
u8 B_TX1_Busy=0;
u8 Send_Buff[16];
u8 DS1307_Data[7]={0}; //数据读出缓存
u8 DS1307_Buff[7]={0,57,13,7,27,5,18}; //数据写入缓存
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);
//========================================================================
// 函数: void main(void)
// 描述: 主函数
//========================================================================
void main(void)
{
P1M1 = 0; P1M0 = 1; //设置为准双向口
P3M1 = 0; P3M0 = 1; //设置为准双向口
P5M1 = 0; P5M0 = 0; //设置为准双向口
WARNING=0;
I2C_SCL=1;
I2C_SDA=1;
UART1_Config_withT2(2);
EA=1;
Set_RTC(DS1307_Buff); //设置时间
//向其他寄存器写入数据
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++) //读取时间并用串口发送
{
SendByte(DS1307_Data);
}
SendByte(read_byte(0x09));
}
}
//========================================================================
// 描述: 设置Timer2做波特率发生器。
// 参数: 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位数据,可变波特率, 0x80: 9位数据,固定波特率, 0xc0: 9位数据,可变波特率
// PS = 1; //高优先级中断
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 (必须使用内部时钟)
// PCON2 |= (1<<4); //内部短路RXD与TXD, 做中继, ENABLE,DISABLE
B_TX1_Busy = 0;
}
/*--------------------------------延时相关函数--------------------------------*/
void delay_ms(u8 ms)
{
unsigned int i;
do{
i = MAIN_Fosc / 13000;
while(--i) ; //14T per loop
}while(--ms);
}
/**************************************
延时X微秒(@12M)
不同的工作环境,需要调整此函数
此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
**************************************/
void DelayXus(u8 n)
{
while (n--)
{
_nop_();
_nop_();
}
}
/*-------------------------------IIC通信相关函数-----------------------------------*/
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() //关闭IIC
{
I2C_SDA=0;
DelayXus(3);
I2C_SCL=1;
DelayXus(3);
I2C_SDA=1;
DelayXus(3);
I2C_SCL=0;
}
bit Wait_Ack(void) //等待应答信号
{
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() //发送应答信号
{
I2C_SCL=1;
DelayXus(3);
I2C_SDA=1;
DelayXus(3);
I2C_SCL=0;
}
void I2CNotAck() //发送非应答信号
{
I2C_SCL=1;
DelayXus(3);
I2C_SDA=0;
DelayXus(3);
I2C_SCL=0;
}
void Send_I2C_Byte(u8 txd) //在总线上发送一个字节
{
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() //在总线上接收一个字节
{
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指定地址读出一个字节数据
{
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的寄存器写入一字节数据
{
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=(read_byte(i));
}
}
void Set_RTC(u8 *p) //设置时间
{
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; //标志发送忙
SBUF = dat; //发一个字节
while(B_TX1_Busy > 0); //等待发送完成
}
//========================================================================
// 函数: void UART1_int (void) interrupt UART1_VECTOR
// 描述: UART1中断函数。
//========================================================================
void UART1_int (void) interrupt 4
{
if(RI)
{
RI = 0;
}
if(TI)
{
TI = 0;
B_TX1_Busy = 0;
}
}
[/mw_shl_code]
|
|