微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 求助!关于ds1302和lcd1602无法显示时间的问题。

求助!关于ds1302和lcd1602无法显示时间的问题。

时间:10-02 整理:3721RD 点击:

想利用ds1302和lcd1602做一个实时时钟,但程序不知道出了什么问题,LCD1602上显示的格式对了,但所有数字都是零。估计是DS1302部分的程序出了问题。本人新手菜鸟一枚,还望各位高手不i吝赐教!不胜感激!程序如下:
#include "STC12C5A.h"
sbit EN=P3^7;                   //位定义LCD1602的相关引脚
sbit RW=P3^6;
sbit RS=P3^5;
sbit SCLK=P1^3;              //位定义DS1302的相关引脚
sbit IO=P3^4;
sbit RST1=P0^7;
sbit BIT0=ACC^0;
sbit BIT7=ACC^7;
unsigned char time[]={0x00,0x40,0x23,0x24,0x01,0x05,0x15};    //初始化时间
unsigned char now[7];                                        //当前时间

void delay_ms(unsigned int time)
{
    unsigned int t;
    for(;time>0;time--)
    {t=1600;while(t--);}
}

/**********DS1302部分*******************/
/***************************************/
void ds1302_input(unsigned char addr,unsigned char dat)    //往ds1302写入数据
{
    unsigned char i;
    RST1=0;
    SCLK=0;
    RST1=1;
    ACC=addr;
    for(i=0;i<8;i++)
    {
        SCLK=0;   
        IO=BIT0;
        ACC>>=1;
        SCLK=1;   
    }
    ACC=dat;
    for(i=0;i<8;i++)
    {
        SCLK=0;
        IO=BIT0;
        ACC>>=1;
        SCLK=1;
    }
    RST1=0;
}

unsigned char ds1302_output(unsigned char addr)       //输出指定地址的数据
{
    unsigned char i;
    RST1=0;
    SCLK=0;
    RST1=1;
    ACC=addr;
    for(i=0;i<8;i++)
    {   
        SCLK=0;
        IO=BIT0;
        ACC>>=1;
        SCLK=1;
    }
    for(i=1;i<8;i++)
    {
        SCLK=1;
        BIT7=IO;
        ACC>>=1;
        SCLK=0;
    }   
    RST1=0;
    return ACC;
}

void time_init(unsigned char *time)       //设置初始时间
{
    unsigned char addr=0x80,i;
    ds1302_input(0x8e,0x00);           //取消写保护
    for(i=0;i<7;i++)
    {
        ds1302_input(addr,time);
        addr=addr+2;
    }
    ds1302_input(0x8e,0x80);           //开启写保护
}

void get_time(unsigned char *now)       //获取当前时间
{
    unsigned char addr=0x81,i,t;
    ds1302_input(0x8e,0x80);            //开启写保护
    for(i=0;i<7;i++)
    {
        ds1302_input(0x8e,0x00);
        t=ds1302_output(addr);
        ds1302_input(0x8e,0x80);
        addr=addr+2;
        now=(t/16)*10+(t&(0x0f));   
    }
}

/**********LCD1602部分*******************/
/***************************************/
void lcd_write_com(unsigned char com)     //lcd1602输入命令
{
    RS=0;
    RW=0;
    P0=com;
    delay_ms(5);
    EN=1;EN=0;
}

void lcd_write_dat(unsigned char dat)    //lcd1602输入数据
{
    RS=1;
    RW=0;
    P0=dat;
    delay_ms(5);
    EN=1;EN=0;
}

void lcd_init()                           //lcd1602初始化
{
    lcd_write_com(0x38);
    lcd_write_com(0x0c);
    lcd_write_com(0x06);
    lcd_write_com(0x01);
}

void show_time()                       //显示当前时间
{
    get_time(now);
    lcd_write_com(0x80);
    lcd_write_dat('0'+now[6]/10);
    lcd_write_dat('0'+now[6]%10);
    lcd_write_dat('-');
    lcd_write_com(0x83);
    lcd_write_dat('0'+now[4]/10);
    lcd_write_dat('0'+now[4]%10);
    lcd_write_dat('-');
    lcd_write_com(0x86);
    lcd_write_dat('0'+now[3]/10);
    lcd_write_dat('0'+now[3]%10);
    lcd_write_dat(' ');
    lcd_write_com(0x89);
    lcd_write_dat('0'+now[5]/10);
    lcd_write_dat('0'+now[5]%10);
    lcd_write_com(0x80+0x40);
    lcd_write_dat('0'+now[2]/10);
    lcd_write_dat('0'+now[2]%10);
    lcd_write_dat('-');
    lcd_write_com(0x80+0x40+3);
    lcd_write_dat('0'+now[1]/10);
    lcd_write_dat('0'+now[1]%10);
    lcd_write_dat('-');
    lcd_write_com(0x80+0x40+6);
    lcd_write_dat('0'+now[0]/10);
    lcd_write_dat('0'+now[0]%10);
}

void main()
{
    lcd_init();
    time_init(time);
    while(1)
    {
        show_time();
        delay_ms(200);
    }
}

now=(t/16)*10+(t&(0x0f)); //能解释下这个是什么意思么

应该是now[i]=(t/16)*10+(t&(0x0f))
是想把BCD码转成十进制数

你用的cpu芯片是c51还是c52

哦,你ds1302好像没有初始化,

  1. sbit ds1302_RST =P2^4;
  2. sbit ds1302_IO  =P2^6;
  3. sbit ds1302_SCLK=P2^5;
  4. sbit ACC0=ACC^0;
  5. sbit ACC7=ACC^7;

  6. uchar  initial_time[]={0x40,0x07,0x12};
  7. uchar  now_time[5],ring_time[3];
  8. void init_ds1302();
  9. void get_ds1302() ;
  10. void set_ds1302(uchar taddr,uchar *P1302);
  11. uchar read_data_ds1302(uchar taddr);
  12. void write_data_ds1302(uchar taddr,uchar tdata);
  13. void  write_Byte(uchar tdata);
  14. uchar  read_Byte();
  15. void read_ring();



  16. uchar  read_Byte()
  17. {
  18.    uchar i;
  19.    for(i=8;i>0;i--)
  20.    {
  21.      ACC=ACC>>1;
  22.      ACC7=ds1302_IO;
  23.      ds1302_SCLK=1;
  24.      ds1302_SCLK=0;                 
  25.    }
  26.    return(ACC);
  27. }



  28. void  write_Byte(uchar tdata)
  29. {
  30.    uchar i;
  31.    ACC=tdata;
  32.    for(i=8;i>0;i--)
  33.    {
  34.      ds1302_IO=ACC0;
  35.      ds1302_SCLK=1;
  36.      ds1302_SCLK=0;
  37.      ACC=ACC>>1;
  38.    }

  39. }


  40. void write_data_ds1302(uchar taddr,uchar tdata)
  41. {
  42.    ds1302_RST=0;
  43.    ds1302_SCLK=0;
  44.    ds1302_RST=1;
  45.    write_Byte(taddr);
  46.    write_Byte(tdata);
  47.    ds1302_RST=0;
  48.    ds1302_SCLK=1;
  49. }


  50. uchar read_data_ds1302(uchar taddr)
  51. {  
  52.    uchar tdata;

  53.    ds1302_RST=0;
  54.    ds1302_SCLK=0;
  55.    ds1302_RST=1;
  56.    write_Byte(taddr);
  57.    tdata=read_Byte();
  58.    ds1302_RST=0;
  59.    ds1302_SCLK=1;
  60.    return(tdata);
  61. }



  62. void set_ds1302(uchar taddr,uchar *P1302)
  63. {
  64.     uchar i;
  65.     write_data_ds1302(0x8e,0x00);
  66.     for(i =3; i>0; i--)
  67.     {
  68.        write_data_ds1302(taddr,*P1302);   
  69.         P1302++;
  70.         taddr+=2;
  71.     }
  72.    write_data_ds1302(0x8e,0x80);         
  73. }


  74. void get_ds1302()
  75. {
  76.     uchar k;
  77.     uchar taddr = 0x81;
  78.     for (k=0; k<5; k++)
  79.     {
  80.         now_time[k] = read_data_ds1302(taddr);
  81.         taddr+=2;

  82.     }
  83. }

  84. void read_ring()
  85. {
  86.     uchar k;
  87.     uchar taddr=0xc1;
  88.     for(k=0;k<3;k++)
  89.     {
  90.         ring_time[k]=read_data_ds1302(taddr);
  91.         taddr+=2;
  92.     }
  93. }
  94. void init_ds1302()
  95. {
  96.     ds1302_RST=0;
  97.     ds1302_SCLK=0;
  98. }

复制代码


这是初始化程序,你加进去试下

单片机型号是stc12c5a60s2

终于发现问题了!
和for循环中的i有关,i从零开始时,keil会把ACC清零,再把ACC的值给i,所以原先写入ACC中的值清零了。
若i从8开始递减就没问题了。

好吧,发现问题就行了。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top