本帖最后由 东北小辉辉 于 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的话跪求大家别喷。。。 |