DS1307时钟模块通过I2C读取数据问题

2019-07-15 22:41发布

尊敬的各位大侠们好,这是我写的一个通过I2C读取DS1307时钟芯片的代码,可是发现最终在lcd1602上显示的数据有问题,给人的感觉好像是没有成功写入初始参数,也没有读出来。请大侠帮我看看代码哪里有问题。谢谢


#include<reg51.h>
#include<stdio.h>
#include<intrins.h>
#include"lcd.h"
//typedef unsigned char uchar;
//typedef unsigned int uint;
/*******************************************/
/*变量定义区
/*******************************************/
sbit SCL = P1^1;
sbit SDA = P1^2;
//#define FALSE 0
//#define TRUE 1
uchar sec,min,hor,day,mon,year;
uint year_h,year_l,mon_h,mon_l,day_h,day_l,hor_h,hor_l,min_h,min_l,sec_h,sec_l;
uchar dis[]={"0123456789"};
/*******************************************/
/*函数声明区
/*******************************************/
void delay_us(uint n);      //n微秒延时函数
void delay_ms(uint n);      //n毫秒延时函数
void init_IIC();       //初始化IIC总线
void start_IIC();       //IIC开始信号
void stop_IIC();       //IIC停止信号
//bit  ask();                  //应答信号
void ask();
void writedata(uchar dat);     //IIC写数据
uchar readdata();       //IIC读数据
void write_DS1307(uchar add,uchar infor); //时钟DS1307写操作,即:修改时间
uchar read_DS1307(uchar add);    //时钟DS1307读操作,即:读取时间
void setting();        //暂时代替时钟设置
void display();        //十进制数据转化为lcd显示输出
/*******************************************/
/*函数定义区
/*******************************************/
//void delay_us(uint n)  //n微秒延时函数
//{
// unsigned char a,b;
// for(b=0;b<n;b++)
// {
//     for(a=1;a>0;a--);
//     _nop_();     //if Keil,require use intrins.h
// }
//}
//
//void delay_ms(uint n)  //n毫秒延时函数
//{
// unsigned char a,b,c;
// for(c=0;c<n;c++)
// {
//     for(b=18;b>0;b--)
//         for(a=152;a>0;a--);
//     _nop_();     //if Keil,require use intrins.h
// }
//}
void init_IIC()    //初始化IIC总线
{
SDA = 1;
    delay_us(10);
SCL = 1;
delay_us(10);
}
void start_IIC()   //IIC开始信号
{
SDA = 1;
delay_us(10);
SCL = 1;
delay_us(10);
SDA = 0;
delay_us(10);
}
void stop_IIC()    //IIC停止信号
{
SDA = 0;
delay_us(10);
SCL = 1;
delay_us(10);
SDA = 1;
delay_us(10);
}
//bit ask()     //应答信号
//{
// //每一个被传送的字节后面必须跟随1位应答位(即一帧共有9位)
// bit flag;    //应答/非应答判断标志位
// SDA = 1;
// SCL = 1;
// delay_us(5);
// flag = SDA;
// delay_us(5);
// SCL = 0;
// delay_us(5);
// if(flag==1)
//  return FALSE;  //非应答
// else
//  return TRUE;  //应答
//}
void ask()
{
uchar z = 0;
while((SDA==1)&&(z<50))
z++;
delay_us(10);
}
void writedata(uchar dat) //IIC写数据
{
uchar i;
SCL = 0;    //此句可以省略
for(i=0;i<8;i++)  //1个BYTE包含8个bit,按位写
{
  dat = dat<<1;
  SCL = 0;
  delay_us(10);
  SDA = CY;   //PSW特殊寄存器中的CY进位标识位,dat左移后最高位赋给CY
  delay_us(10);
  SCL = 1;    //保持高电平,数据稳定
  delay_us(10);   
}
SCL = 0;
delay_us(10);
SDA = 1;    //总线释放
delay_us(10);
}
void write_DS1307(uchar add,uchar infor) //时钟DS1307写操作,即:修改时间
{
start_IIC();
writedata(0xd0);  //器件写地址
ask();
writedata(add);   //器件内部存储区的地址
ask();
writedata(infor);   //数据
ask();
stop_IIC();
}
uchar readdata()   //IIC读数据
{
uchar i,dat;
SCL = 0;
delay_us(10);
SDA = 1;    //数据总线释放
delay_us(10);
for(i=0;i<8;i++)
{         
  SCL = 1;
  delay_us(10);
  dat = (dat<<1)|(uchar)SDA;
  //dat左移一位,最低位变成0,与SDA的值按位或,将SDA的数据读到了dat的最低位
  SCL = 0;
  delay_us(10);  
}
return dat;  
}
uchar read_DS1307(uchar add) //时钟DS1307读操作,即:读取时间
{
uchar r = 0;
start_IIC();
writedata(0xd0);   //器件写地址
ask();
writedata(add);    //器件内部存储区的地址
ask();
start_IIC();
writedata(0xd1);    //器件读地址
ask();
r = readdata();
stop_IIC();

return r;
}
void setting()     //暂时代替时钟设置
{
write_DS1307(0x00,0x45);
delay_ms(10);
write_DS1307(0x01,0x30);
delay_ms(10);
write_DS1307(0x02,0x15);
delay_ms(10);
write_DS1307(0x03,0x05);
delay_ms(10);
write_DS1307(0x04,0x30);
delay_ms(10);
write_DS1307(0x05,0x08);
delay_ms(10);
write_DS1307(0x06,0x13);
delay_ms(10);  
}
void display()     //十进制数据转化为lcd显示输出
{
// uchar a[10],b[10],c[10];
// uchar l[10],m[10],n[10];
// //年.月.日
// L1602_string(1,0,"20");
// sprintf(a,"%s",year);
// L1602_string(1,2,a+0x30);
// L1602_string(1,4,".");
// sprintf(b,"%s",mon+0x30);
// L1602_string(1,5,b);
// L1602_string(1,7,".");
// sprintf(c,"%s",day+0x30);
// L1602_string(1,8,a);
// //时.分.秒
// sprintf(l,"%s",hor+0x30);
// L1602_string(2,0,l);
// L1602_string(2,2,".");
// sprintf(m,"%s",min+0x30);
// L1602_string(1,3,m);
// L1602_string(1,5,".");
// sprintf(n,"%s",sec+0x30);
// L1602_string(1,6,n);
year_h = year/10;
year_l = year%10;
mon_h  = mon/10;
mon_l  = mon%10;
day_h  = day/10;
day_l  = day%10;
hor_h  = hor/10;
hor_l  = hor%10;
min_h  = min/10;
min_l  = min%10;
sec_h  = sec/10;
sec_l  = sec%10;
L1602_char(1,1,'2');
L1602_char(1,2,'0');
L1602_char(1,3,dis[year_h]);
L1602_char(1,4,dis[year_l]);
L1602_char(1,5,'.');
L1602_char(1,6,dis[mon_h]);
L1602_char(1,7,dis[mon_l]);
L1602_char(1,8,'.');
L1602_char(1,9,dis[day_h]);
L1602_char(1,10,dis[day_l]);
L1602_char(2,1,dis[hor_h]);
L1602_char(2,2,dis[hor_l]);
L1602_char(2,3,'.');
L1602_char(2,4,dis[min_h]);
L1602_char(2,5,dis[min_l]);
L1602_char(2,6,'.');
L1602_char(2,7,dis[sec_h]);
L1602_char(2,8,dis[sec_l]);
}   
/*******************************************/
/*主函数main()
/*******************************************/
void main()
{
// uchar ch;
init_IIC();
L1602_init();
//setting();
// sec = read_DS1307(0x00);
// ch = (sec&0x80);       //判断秒[7]的值,得到芯片是否开始工作
// if(ch==0x80)
// sec = sec&0x7f;        //改变秒[7]=0,即已工作
// write_DS1307(0x00,sec);
while(1)
{
     enable(0x01);
  sec  = read_DS1307(0x00);    //读出“秒”的BCD码
  sec  = ((sec&0x70)>>4)*10+(sec&0x0f); //BCD码转换为10进制数
  min  = read_DS1307(0x01);    //读出“分”的BCD码
  min  = ((min&0x70)>>4)*10+(min&0x0f); //BCD码转换为10进制数
  hor  = read_DS1307(0x02);    //读出“时”的BCD码
  hor  = ((hor&0x70)>>4)*10+(hor&0x0f); //BCD码转换为10进制数
  day  = read_DS1307(0x04);    //读出“天”的BCD码
  day  = ((day&0x30)>>4)*10+(day&0x0f); //BCD码转换为10进制数
  mon  = read_DS1307(0x05);    //读出“月”的BCD码
  mon  = ((mon&0x10)>>4)*10+(mon&0x0f); //BCD码转换为10进制数
  year = read_DS1307(0x06);    //读出“年”的BCD码
  year = ((year&0xf0)>>4)*10+(year&0x0f); //BCD码转换为10进制数
  
  display();        //显示函数
  delay_ms(30);
}
}




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。