OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7523|回复: 2

关于DS1307时钟芯片读写问题

[复制链接]

17

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
121
金钱
121
注册时间
2014-12-1
在线时间
17 小时
发表于 2018-6-24 14:25:52 | 显示全部楼层 |阅读模式
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]

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

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

使用道具 举报

8

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
114
金钱
114
注册时间
2019-5-25
在线时间
29 小时
发表于 2020-9-3 07:26:26 | 显示全部楼层
拔掉电池试试能不能读出来
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 07:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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