用51+lcd1602+ds3231做一个时钟,时钟的显示位置不对

2019-07-15 16:56发布

小白最近想用51+lcd1602+ds3231做一个时钟,由于编程实在菜,只好先用proteus仿真提高成功率,无奈proteus里面没有ds3231只有ds3232,看了一下资料两个芯片编程可以直接移植,于是就用了24c02的程序结合ds3231来修改。结果发现了问题,时钟的时、分、秒都能读出来,但是显示的位置不对,如下图:
QQ图片20150602220643.png


把几段相关程序贴出来,大神们帮看看是哪出错了
/********************************************************************
* 名称 : flash()
* 功能 : 延时,时间为2个NOP,大概为2US
* 输入 : 无
* 输出 : 无
***********************************************************************/
void flash(void)
{
_nop_();
_nop_();
}
/********************************************************************
* 名称 : IIC_init()
* 功能 : IIC初始化子程序
* 输入 : 无
* 输出 : 无
***********************************************************************/
void IIC_init(void)
{
scl = 1;
flash();
sda = 1;
flash();
}
/********************************************************************
* 名称 : start(void)
* 功能 : 启动IIC总线
* 输入 : 无
* 输出 : 无
***********************************************************************/
void start(void)
{
scl = 1;
flash();
sda = 1;
flash();
sda = 0;
flash();
scl = 0;
flash();
}
/********************************************************************
* 名称 : stop()
* 功能 : 停止I2C总线
* 输入 : 无
* 输出 : 无
***********************************************************************/
void stop()
{
scl = 0;
flash();
sda = 0;
flash();
scl = 1;
flash();
sda = 1;
flash();
}
/********************************************************************
* 名称 : writex()
* 功能 : 写一个字节
* 输入 : j(需要写入的值)
* 输出 : 无
***********************************************************************/
void writex(uchar j)
{  
uchar i,temp;
temp = j;
for(i=0; i<8; i++)
{
  scl = 0;
  flash();
  sda = (bit)(temp & 0x80);
  flash();
  scl = 1;
  flash();
  temp = temp << 1;
}
scl = 0;
flash();
}
/********************************************************************
* 名称 : readx()
* 功能 : 读一个字节
* 输入 : 无
* 输出 : 读出的值
***********************************************************************/
uchar readx(void)
{
uchar i, j, k = 0;
for(i=0; i<8; i++)
{
  scl = 1;
  flash();  
  if(sda == 1)
  {
   j = 1;
  }
  else j = 0;
  k = (k << 1) | j;
  scl = 0;
  flash();
}
return(k);
}
/********************************************************************
* 名称 : ack()
* 功能 : I2C总线时钟
* 输入 : 无
* 输出 : 无
***********************************************************************/
void ack(void)
{
uchar i = 0;
scl = 1;
flash();
while((sda == 1) && (i < 255))
{
  i++;
}
scl = 0;
flash();
}
/********************************************************************
* 名称 : IIC_read()
* 功能 : 从IIC中读出值
* 输入 : address(要在这个地址读取值)
* 输出 : 从IIC中读出的值
***********************************************************************/
uchar IIC_read(uchar address)
{
uchar i;
start();
writex(0xd0);
ack();
writex(address);
ack();
stop();
start();
writex(0xd1);
ack();
i = readx();
stop();   
return(i);
}
/********************************************************************
* 名称 : IIC_write()
* 功能 : 想IIC中写入数据
* 输入 : address(地址) , info(值)
* 输出 : 无
***********************************************************************/
void IIC_write(uchar address, uchar info)
{
start();
writex(0xd0);
ack();
writex(address);
ack();
writex(info);
ack();
stop();
}
/********************************************************************
* 名称 : B2H()
* 功能 : BCD转Hex
* 输入 : val(值)
* 输出 : 无
***********************************************************************/
uchar B2H(uchar val)
{
uchar temp;
    temp=val&0x0f;
    val>>=4;
    val&=0x0f;
    val*=10;
    temp+=val;  
    return (temp);
}
/********************************************************************
* 名称 : H2B()
* 功能 : Hex转BCD
* 输入 : val(值)
* 输出 : 无
***********************************************************************/
uchar H2B(uchar val)
{
  uchar i,j,k;
    i=val/10;
    j=val%10;
    k=j+(i<<4);
    return k;
}
/********************************************************************
* 名称 : read_time()
* 功能 : 读取时间并显示
* 输入 :
* 输出 : 无
***********************************************************************/
void read_time()  //当hou、min、sec三段程序位置互换时,显示的位置也会变化
{
hou0=IIC_read(0x02);
hou0&=0x3f;
hou1=B2H(hou0);
LCD_write_command(0x80);
LCD_write_data(hou1/10+0x30);
LCD_write_command(0x81);
LCD_write_data(hou1%10+0x30);

min0=IIC_read(0x01);
min1=B2H(min0);
LCD_write_command(0x83);
LCD_write_data(min0/10+0x30);
LCD_write_command(0x84);
LCD_write_data(min0%10+0x30);

sec0=IIC_read(0x00);
sec1=B2H(sec0);
LCD_write_command(0x86);
LCD_write_data(sec1/10+0x30);
LCD_write_command(0x87);
LCD_write_data(sec1%10+0x30);

}
/********************************************************************
* 名称 : write_time()
* 功能 : 写入初始时间
* 输入 : hou(时),min(分),sec(秒)
* 输出 : 无
***********************************************************************/
void write_time(uchar hou,uchar min,uchar sec)
{
uchar temp;
temp=H2B(hou);
    IIC_write(0x02,temp);   //修改时
   
    temp=H2B(min);
    IIC_write(0x01,temp); //修改分
   
    temp=H2B(sec);
    IIC_write(0x00,temp); //修改秒
}
void main()
{
LCD_init();
IIC_init();
for(i=0;i<13;i++)
LCD_disp_char(i,1,date0);   //显示两个“:”
write_time(4,30,22);
while(1)
{
  read_time();
  delay(10);
}
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
天堂小白
1楼-- · 2019-07-15 20:57
 精彩回答 2  元偷偷看……
金池思密达
2楼-- · 2019-07-15 21:22
太长了,看了下。没看懂
zeng10119
3楼-- · 2019-07-15 23:59
是不是显示地址的问题,我没看懂程序但最近做的电子钟,验收时老师要求把时分秒位置互换,我就是把1602显示地址换一下就得了。
liuzhaoxin1020
4楼-- · 2019-07-16 02:18
不错的,文件值得收藏

一周热门 更多>