river0830 发表于 2010-4-27 23:12:06

求助PCF8563c51程序显示问题?想不通啊,郁闷!

编写c51电子钟程序,出现了个奇怪的问题,程序如下
从pcf8563读出时间和日期值,读出数值暂存在数组num[]中,num为秒数据(BCD码),将BCD码转换成十进制数放入结构体秒单元etime.sec=((num/16)>>4)*10+num&0x0f;
但是在1602液晶上显示的时候采用指令LCDSendData(num/16+0x30); LCDSendData(num%16+0x30);显示时钟正常.
采用指令LCDSendData(etime.sec/10+0x30); LCDSendData(etime.sec%10+0x30); 显示不正常,秒从0走到15就变为0了,但是其他显示没问题.
想不明白啊,请大家看看!



#include "i2c.h"
#include "1602.h"
#include "eclock.h"

struct time
{
char hour;
char min;
char sec;
uchar day;
char week;
uchar month;
char year;
uchar centry; // 表示19**/20**
};

uchar num;                     // 时间日期存储缓冲区
struct time etime;

void pcf8563init(void)
{
I2CInit();
num=0x02;       //设置闹钟使能
num=0x01;
num=0x01;
I2CSendS(pcfsla,0,num,9);
num=0x80;   //关闭闹钟报警
num=0x80;
num=0x80;
num=0x80;
I2CSendS(pcfsla,9,num,4);
delay10ms();
}

void Readpcf8563(void)
{
I2CRecS(pcfsla,2,num,7);
num&=0x7f;                      // 秒
num&=0x7f;                      // 分
num&=0x3f;                      // 时   
num&=0x3f;                      // 日      
num&=0x07;                      // 星期   
if(num&0x80)                  // 判断是19** 还是 20**
etime.centry=19;
else
etime.centry=20;
num&=0x1f;                      // 月

etime.sec=((num/16)>>4)*10+num&0x0f;   
etime.min=((num/16)>>4)*10+num&0x0f;      
etime.hour=((num/16)>>4)*10+num&0x0f;   
etime.day=((num/16)>>4)*10+num&0x0f;   
etime.week=num&0x07;
etime.month=((num/16)>>4)*10+num&0x0f;   
etime.year=((num/16)>>4)*10+num&0x0f;

//在1602上显示时间和日期
LCDSendCommand(LCDROW1ADR);                        //第一行显示 月/日 星期 小时:分钟:秒
LCDSendData(etime.month/10+0x30);
LCDSendData(etime.month%10+0x30);
LCDSendData('/');
LCDSendData(etime.day/10+0x30);
LCDSendData(etime.day%10+0x30);
LCDSendData(' ');
LCDSendData(etime.week+0x31);
LCDSendCommand(LCDROW1ADR+8);
LCDSendData(etime.hour/10+0x30);
LCDSendData(etime.hour%10+0x30);
LCDSendData(':');
LCDSendData(etime.min/10+0x30);
LCDSendData(etime.min%10+0x30);
LCDSendData(':');
LCDSendData(num/16+0x30);
LCDSendData(num%16+0x30);
//采用下面指令显示不正常
/*
LCDSendData(etime.sec/10+0x30);
LCDSendData(etime.sec%10+0x30);
*/
LCDSendCommand(LCDROW2ADR+2);                           //液晶第二行显示年
LCDSendData(etime.centry/10+0x30);
LCDSendData(etime.centry%10+0x30);
LCDSendData(etime.year/10+0x30);
LCDSendData(etime.year%10+0x30);

}

void main(void)
{
uchar i;

delay10ms();
for(i=9;i>0;i--)
num=0;
pcf8563init();                                 
initlcd();

while(1)
{
   Readpcf8563();
}
}

river0830 发表于 2010-4-28 00:04:20

唉,采用下面指令分钟显示也不正常了,走到6分就变为0了,
LCDSendData(etime.min/10+0x30);
LCDSendData(etime.min%10+0x30);
改为
LCDSendData(num/16+0x30);
LCDSendData(num%16+0x30);
显示了半个小时了,没出现问题,估计小时显示也得改了,不然走了5、6个小时后就能归零了
I2C读写时序没问题,采用结构体数据的键盘扫描也没问题,没有仿真器,就只能反汇编一步一步查,太郁闷了

chess01 发表于 2010-4-28 15:38:40

etime.sec=((num/16)>>4)*10+num&0x0f;
这句有问题,num/16已经得到秒十位了,为什么还要右移4位?num/16等于num>>4

用下面的就好了
etime.sec=(num/16)*10+num&0x0f;

river0830 发表于 2010-4-28 21:05:43

哦,谢谢2楼提醒,不过改了之后显示也不行啊,一样是走到15秒就为0了
etime.sec=(num>>4)*10+num&0x0f;
LCDSendData(etime.sec/10+0x30);
LCDSendData(etime.sec%10+0x30);

cctnt 发表于 2010-4-28 21:23:13

优先级问题
etime.sec=(num>>4)*10+(num&0x0f);

river0830 发表于 2010-4-28 22:04:48

谢谢四楼提醒,+运算符优先级大于&,改后程序没问题了
呵呵,C语言不熟悉啊,还要努力才行!
呵呵,终于调试没问题了,感谢大家提醒,上传电子钟keil工程代码,带温度显示

river0830 发表于 2010-4-28 22:06:39

电子钟程序,采用ds18b20,pcf8563,1602显示,四个独立按键,可以设置闹钟,调整时间和日期!

点击此处下载 ourdev_549996.rar(文件大小:65K) (原文件名:EClock.rar)

xinghuncool 发表于 2012-5-5 14:31:20

文件压缩包错误啊~~~哪里可以下载的~~~

xinghuncool 发表于 2012-5-5 14:44:37

river0830 发表于 2010-4-28 22:06 static/image/common/back.gif
电子钟程序,采用ds18b20,pcf8563,1602显示,四个独立按键,可以设置闹钟,调整时间和日期!

点击此处下 ...

你好,请问能发一份到我邮箱吗?xinghuncool@163.com~~谢谢。目前论坛不能下载~~
页: [1]
查看完整版本: 求助PCF8563c51程序显示问题?想不通啊,郁闷!