OpenEdv-开源电子网

 找回密码
 立即注册

扫一扫,访问微社区

正点原子全套STM32/FPGA开发资料,上千讲STM32视频教程,RT1052教程免费下载啦...
查看: 1176|回复: 1

关于DS1307时钟芯片读写问题

[复制链接]

  离线 

17

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
94
金钱
94
注册时间
2014-12-1
在线时间
11 小时
发表于 2018-6-24 14:25:52 | 显示全部楼层 |阅读模式
5金钱
使用STC的15W系列单片机进行DS1307读写时遇到问题:读出来的数据都是00,程序是参考:http://www.openedv.com/forum.php?mod=viewthread&tid=20167&highlight=ds1307中3楼原子哥给的附件程序移植的,程序如下,请大家帮忙指正:
[C] 纯文本查看 复制代码
#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[i]);		
		}
		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[i]=(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;
	}
}

回复

使用道具 举报

  离线 

516

主题

9万

帖子

31

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
134732
金钱
134732
注册时间
2010-12-1
在线时间
1316 小时
发表于 2018-6-25 01:53:19 | 显示全部楼层
帮顶
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则




关闭

正点原子双11大促销上一条 /1 下一条

正点原子公众号

QQ|联系我们|手机版|官方淘宝店|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2018-11-16 17:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表
/* */