DS1302 读出时间不正确,是什么原因?
用STC12C 5412AD芯片 12 M晶体,程序是用 公版程序,程序用于另一个板子(STC 12C5A62S2 4M)可以正常运行。现像为:FF 02 FF 09 05 11,FF 02 FF 05 59 最后一位,秒可以读出,最大变化到59 后,就变成7F, 其他位读出不对。
按理接线是对的,驱动也是对的! P1 口有AD转换,只用P1.0,与P1.1用作AD。 是不是没有BCD转换? 时序不对吧?贴程序看看。 按你说的所有都没问题,那就是遇见鬼了 &0x3f........ 速度快,增加延时。 v_8787 发表于 2017-1-8 09:33
是不是没有BCD转换?
程序在另一款板子上是Ok的!~~~可以正常读出来显示挺好的! node720 发表于 2017-1-8 09:48
时序不对吧?贴程序看看。
sbit RST = P1^2;
sbit IO= P1^4;
sbit SCK = P1^5;
uchar time_buf = {0x20,0x10,0x0c,0x05,0x0F,0x08,0x55,0x02};//³õ
unsigned char idata Rec_buf= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char idata Ctrl_buf={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
/*****Ôö¼Óds1302******/
#define ds1302_sec_add 0x80 //ÃëÊý¾ÝµØÖ·
#define ds1302_min_add 0x82 //·ÖÊý¾ÝµØÖ·
#define ds1302_hr_add 0x84 //ʱÊý¾ÝµØÖ·
#define ds1302_date_add 0x86 //ÈÕÊý¾ÝµØÖ·
#define ds1302_month_add 0x88 //ÔÂÊý¾ÝµØÖ·
#define ds1302_day_add 0x8a //ÐÇÆÚÊý¾ÝµØÖ·
#define ds1302_year_add 0x8c //ÄêÊý¾ÝµØÖ·
#define ds1302_control_add 0x8e //¿ØÖÆÊý¾ÝµØÖ·
#define ds1302_charger_add 0x90
#define ds1302_clkburst_add 0xbe
void ds1302_init(void) //OK
{
RST=0; //RST½ÅÖõÍ
SCK=0; //SCK½ÅÖõÍ
}
void ds1302_write_byte(uchar addr, uchar d)
{
uchar i;
RST=1; //Æô¶¯DS1302×ÜÏß
//дÈëÄ¿±êµØÖ·£ºaddr
addr = addr & 0xFE; //×îµÍλÖÃÁ㣬¼Ä´æÆ÷0λΪ0ʱд£¬Îª1ʱ¶Á
for (i = 0; i < 8; i ++) {
if (addr & 0x01) {
IO=1;
}
else {
IO=0;
}
SCK=1; //²úÉúʱÖÓ
SCK=0;
addr = addr >> 1;
}
//дÈëÊý¾Ý£ºd
for (i = 0; i < 8; i ++) {
if (d & 0x01) {
IO=1;
}
else {
IO=0;
}
SCK=1; //²úÉúʱÖÓ
SCK=0;
d = d >> 1;
}
RST=0; //Í£Ö¹DS1302×ÜÏß
}
//´ÓDS1302¶Á³öÒ»×Ö½ÚÊý¾Ý
uchar ds1302_read_byte(uchar addr) {
uchar i,temp;
RST=1; //Æô¶¯DS1302×ÜÏß
//дÈëÄ¿±êµØÖ·£ºaddr
addr = addr | 0x01; //×îµÍλÖøߣ¬¼Ä´æÆ÷0λΪ0ʱд£¬Îª1ʱ¶Á
for (i = 0; i < 8; i ++) {
if (addr & 0x01) {
IO=1;
}
else {
IO=0;
}
SCK=1;
SCK=0;
addr = addr >> 1;
}
//Êä³öÊý¾Ý£ºtemp
for (i = 0; i < 8; i ++) {
temp = temp >> 1;
if (IO) {
temp |= 0x80;
}
else {
temp &= 0x7F;
}
SCK=1;
SCK=0;
}
RST=0; //Í£Ö¹DS1302×ÜÏß
return temp;
}
//ÏòDS302дÈëʱÖÓÊý¾Ý
void ds1302_write_time(void)
{
ds1302_write_byte(ds1302_control_add,0x00); //¹Ø±Õд±£»¤
ds1302_write_byte(ds1302_sec_add,0x80); //ÔÝͣʱÖÓ
//ds1302_write_byte(ds1302_charger_add,0xa9); //ä¸Á÷³äµç
ds1302_write_byte(ds1302_year_add,time_buf); //Äê
ds1302_write_byte(ds1302_month_add,time_buf); //ÔÂ
ds1302_write_byte(ds1302_date_add,time_buf); //ÈÕ
ds1302_write_byte(ds1302_hr_add,time_buf); //ʱ
ds1302_write_byte(ds1302_min_add,time_buf); //·Ö
ds1302_write_byte(ds1302_sec_add,time_buf); //Ãë
ds1302_write_byte(ds1302_day_add,time_buf); //ÖÜ
ds1302_write_byte(ds1302_control_add,0x80); //´ò¿ªÐ´±£»¤
}
//´ÓDS302¶Á³öʱÖÓÊý¾Ý
void ds1302_read_time(void)
{
time_buf=ds1302_read_byte(ds1302_year_add); //Äê
time_buf=ds1302_read_byte(ds1302_month_add); //ÔÂ
time_buf=ds1302_read_byte(ds1302_date_add); //ÈÕ
time_buf=ds1302_read_byte(ds1302_hr_add); //ʱ
time_buf=ds1302_read_byte(ds1302_min_add); //·Ö
time_buf=(ds1302_read_byte(ds1302_sec_add))&0x7f;//Ã룬ÆÁ±ÎÃëµÄµÚ7룬±ÜÃⳬ³ö59
time_buf=ds1302_read_byte(ds1302_day_add); //ÖÜ
}
if(RTCOK_fag==0) 读出并上传时间数据~
{Rec_buf=0x55;
delayms(10);
ds1302_read_time();
Rec_buf=0x55;
Rec_buf=time_buf;//年
Rec_buf=time_buf;//月
Rec_buf=time_buf; //日
Rec_buf=time_buf; //时
Rec_buf=time_buf; //分
Rec_buf=time_buf;//秒
Rec_buf=0xE5; //
Rec_buf=0xaa;//
send1();//串口发送数据据!
}
主要程序!!
liyo2012 发表于 2017-1-8 14:48
sbit RST = P1^2;
sbit IO= P1^4;
sbit SCK = P1^5;
加上拉电阻 加延时可以读出时间了。但是修改不了,,可能还是速度问题:
调了一个晚上:
void ds1302_write_byte(uchar addr, uchar d)
{
uchar i;
delay100us(200); //加延时
RST=1;
delay100us(200); //启动DS1302总线
//写入目标地址:addr
addr = addr & 0xFE; //最低位置零,寄存器0位为0时写,为1时读
for (i = 0; i < 8; i ++) {
_nop_;
_nop_;
_nop_;
_nop_;
_nop_;
_nop_;
if (addr & 0x01) {
_nop_;
_nop_;
_nop_;
IO=1;
}
else {
_nop_;
_nop_;
_nop_;
IO=0;
}
SCK=1; //产生时钟
SCK=0;
addr = addr >> 1;
}
//写入数据:d
for (i = 0; i < 8; i ++) {
if (d & 0x01) {
_nop_;
_nop_;
_nop_;
IO=1;
}
else {
_nop_;
_nop_;
_nop_;
IO=0;
}
SCK=1; //产生时钟
_nop_;
SCK=0;
d = d >> 1;
}
RST=0; //停止DS1302总线
}
上面延时还是不行!
谁有这方面的经验 告诉一下!!!!
买个便宜的逻辑分析仪,几十块钱那种,AXpro, 抓一下波形。 TBG3 发表于 2017-1-11 12:20
买个便宜的逻辑分析仪,几十块钱那种,AXpro, 抓一下波形。
求淘宝地址!!!! 本帖最后由 Eric_Xue 于 2017-1-12 08:53 编辑
LZ,试下,看是否能解决问题
uchar ds1302_read_byte(uchar addr) {
uchar i,temp;
RST=1; //此处RST 应该改为DS1302_CS
addr = addr | 0x01;
// Send Addr
for (i = 0; i < 8; i ++)
{
if (addr & 0x01) {
IO=1;
}
else {
IO=0;
}
SCK=0;
addr >>=1;
SCK=1;
}
//Read Data
for (i = 0; i < 8; i ++) {
SCK=0;
temp >>=1;
if (IO) {
temp |= 0x80;
}
else {
temp &= 0x7F;
}
SCK=1;
}
RST=0; //此处RST 应该改为DS1302_CS
return temp;
} Eric_Xue 发表于 2017-1-12 08:44
LZ,试下,看是否能解决问题
uchar ds1302_read_byte(uchar addr) {
"DS1302_CS " 我的这个不是定义是这个啊! liyo2012 发表于 2017-1-12 15:11
"DS1302_CS " 我的这个不是定义是这个啊!
好吧,你这个RST实际是连DS1302的CS脚吧?我是建议你名字改一下,不过你要用RST也行。用我的程序替代你的程序,看是否有改善。 Eric_Xue 发表于 2017-1-12 18:11
好吧,你这个RST实际是连DS1302的CS脚吧?我是建议你名字改一下,不过你要用RST也行。用我的程序替代你的 ...
好的!我试试下! liyo2012 发表于 2017-1-12 19:26
好的!我试试下!
我记得还要解锁才能写的,不知道怎么表达
页:
[1]