打印

关于ds1302时钟芯片,想请教一下大家

[复制链接]
2143|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 东北小辉辉 于 2012-10-15 18:02 编辑

RT小弟这两天在学习ds1302这个芯片,顺便学习一下spi总线协议,准备做一个时钟出来,但是程序的进展并不顺利,下面是程序,请大家看看问题出在哪里,谢谢了
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define sec_write 0x80
#define sec_read 0x81
#define min_write 0x82
#define min_read 0x83
#define hour_write 0x84
#define hour_read 0x85
#define day_write 0x86
#define day_read 0x87
#define mon_write 0x88
#define mon_read 0x89
#define week_write 0x8A
#define week_read 0x8B
#define year_write 0x8C
#define year_read 0x8D
#define protect_write 0x8E
sbit rst=P2^0;
sbit sclk=P2^1;
sbit dat=P2^2;
sbit lcdrs=P1^0;
sbit lcdrw=P1^1;
sbit lcden=P1^2;
int sec,min,hour,day,mon,year;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
  for(y=112;y>0;y--);
}
void write_cmd(uchar cmd)
{
lcdrs=0;
lcdrw=0;
lcden=0;
P0=cmd;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar dat)
{
lcdrs=1;
lcdrw=0;
lcden=0;
P0=dat;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void ds1302_write(uchar temp)
{
int i=8;
rst=0;
delay(5);
sclk=0;
delay(5);
rst=1;
for(i=8;i>0;i--)
{
  dat=temp&0x01;
  delay(10);
  sclk=1;
  temp>>=1;
  sclk=0;
}
}
uchar ds1302_read()
{
uchar i,j;
rst=0;
delay(5);
sclk=0;
delay(5);
rst=1;
for(i=8;i>0;i--)
{
  j>>=1;
  sclk=0;
  delay(10);
  if(dat)
  {
   j=j|0x80;
  }
  sclk=1;
}
return(j);
}
void write_sfm(uchar add,uchar dat)
{
uchar shi,ge;
shi=dat/10;
ge=dat%10;
write_cmd(0x80+0x40+add);
write_data(0x30+shi);
write_data(0x30+ge);
}
void write_nyr(uchar add,uchar dat)
{
uchar shi,ge;
shi=dat/10;
ge=dat%10;
write_cmd(0x80+add);
write_data(0x30+shi);
write_data(0x30+ge);
}
void reg_w(uchar add,uchar dat)
{
ds1302_write(add);
ds1302_write(dat);
}
uchar reg_r(uchar add)
{
int dat;
ds1302_write(add);
dat=ds1302_read();
return dat;   
}
void init()
{
reg_w(protect_write,0x00);//对写保护寄存器的定义,禁止写保护
reg_w(sec_write,0x00);//对秒寄存器的定义
reg_w(min_write,0x00);//对分寄存器的定义
reg_w(hour_write,0xA0);//对时寄存器的定义
reg_w(day_write,0x00);//对天寄存器的定义
reg_w(mon_write,0x00);//对月寄存器的定义
reg_w(year_write,0x00);//对年寄存器的定义
write_cmd(0x38);//液晶初始化,以下同
write_cmd(0x0c);
write_cmd(0x06);
write_cmd(0x01);  
}
void main()
{
init();
while(1)
{
  sec=reg_r(sec_read);
  min=reg_r(min_read);
  hour=reg_r(hour_read);
  day=reg_r(day_read);
  mon=reg_r(mon_read);
  year=reg_r(year_read);
  write_sfm(10,sec);
  write_sfm(7,min);
  write_sfm(4,hour);
  write_nyr(9,year);
  write_nyr(6,mon);
  write_nyr(3,day);
};
}
下面是仿真电路图

这个电路图很简单,我对程序是这样理解的,先宏定义ds1302的寄存器,然后写一个简单的一毫秒的延时函数,然后是液晶的写命令和写数据的函数,
然后是写1302一个字节的函数和读1302一个字节的函数,依据如下图

虽然写的有点罗嗦,但是不至于出错吧
然后就是液晶的刷新函数,我主要怀疑reg-r这个函数有问题,但是具体什么问题还不知道,读取到ds1302的地址时候显示的就是乱码,其他地址读取回液晶的数据都是0,我也不知道是怎么回事,可能是数据没有写进去还是怎么?
还有下面这句话是什么意思,我也不是很明白,

这个有用么,我貌似没用到这个东西,控制字怎么只有5位数,表示地址也不够啊。。。
还有1302的寄存器,他说是用BCD码表示,BCD码和16进制不同么,有什么不同呢?

问题比较多,希望大家能给解答一下,感激不进啊!
PS:小弟刚开始学,如果我问的问题很2的话跪求大家别喷。。。

相关帖子

沙发
ayb_ice| | 2012-10-15 17:01 | 只看该作者
为什么要写1秒的延时程序

使用特权

评论回复
板凳
东北小辉辉|  楼主 | 2012-10-15 17:56 | 只看该作者
因为写液晶的延时时候要用到啊

使用特权

评论回复
地板
东北小辉辉|  楼主 | 2012-10-15 18:06 | 只看该作者
哦 对不起 是延时1ms的函数,刚才说成了一秒了,我已经改正过来了

使用特权

评论回复
5
ningling_21| | 2012-10-15 20:21 | 只看该作者
百度一下别人的1302的程序试试... 如果可以的话 ,再看看区别在哪...

使用特权

评论回复
6
东北小辉辉|  楼主 | 2012-10-15 22:47 | 只看该作者
我看了,但是他们都是用ACC累加器写的,跟我写的不一样,而且有的地方看不懂,我想自己写一个程序,谢谢你的建议。 5# ningling_21

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

91

帖子

0

粉丝