DS1302时钟芯片使用51单片机

51单片机使用DS1302实现时钟功能

调试过程中出现了很多情况,LCD1602显示的数据和写入的数据不一样;秒不是1秒+1,而是过了近2秒才+1,而且是不连续,中家缺少一些数据不显示,用示波器看波形也是正常的,没有显示在LCD1602的波形,在示波器数据中是存在的。后来发现是DS1302_Read_Byte中出现了问题,然而示波器里看不出来这里的时序是有问题的。

/**#include <reg52.h>
#include<intrins.h>

#define DATAOUTPUT P0

sbit SCK = P2^0;
sbit IO = P2^1;
sbit RST = P2^2;

unsigned char code num[] = "0123456789ABCDEF";
unsigned char num_i;

sbit RS = P2^4;
sbit RW = P2^5;
sbit EN = P2^6;

void delayus()
{
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();

}

void delayms(unsigned int t)
{
    unsigned int i,j;
    for(i = t; i > 0; i --)
    for(j = 110; j > 0; j --);
}

void Write_Data(unsigned char dat)
{
    EN = 0;
    RS = 1;
    RW = 0;

    DATAOUTPUT = dat;
//       delayms(5);
    EN = 1;
    delayms(5);
    EN = 0;
}

void Write_Cmd(unsigned char cmd)
{
    EN = 0;
    RS = 0;
    RW = 0;

    DATAOUTPUT = cmd;
//       delayms(5);
    EN = 1;
    delayms(5);
    EN = 0;
}

void Write_Str(unsigned char *s)
{
    while(*s != '\0')
    {
        Write_Data(*s);
        delayms(5);
        s ++;
    }
}

void LCD1602_Init()
{
    Write_Cmd(0x01);
    Write_Cmd(0x38);
    Write_Cmd(0x0f);
    Write_Cmd(0x06);
}



void DS1302_Write_Data(unsigned char cmd, unsigned char dat)
{
     unsigned char i;
     SCK = 0;
     RST = 0;
     delayus();
     RST = 0;
     delayus();
     RST = 1;
     delayus();
         for(i = 0; i < 8; i ++)
         {
              if((cmd&0x01)==0x01)
             {
                 IO = 1;
             }
             else
             {
                 IO = 0;
             }
             delayus();
             SCK = 1;
             delayus();
             cmd >>= 1;
             SCK = 0;
             delayus();
         }

         for(i = 0; i < 8; i ++)
         {
              if((dat&0x01)==0x01)
             {
                 IO = 1;
             }
             else
             {
                 IO = 0;
             }
             delayus();
             SCK = 1;
             delayus();
             dat >>= 1;
             SCK = 0;
             delayus();
         }

         RST = 0;

}

unsigned char DS1302_Read_Data(unsigned char cmd)
{
     unsigned char i,val;
     SCK = 0;
     RST = 0;
     delayus();
     RST = 0;
     delayus();
     RST = 1;
     delayus();
         for(i = 0; i < 8; i ++)
         {
              if((cmd&0x01)==0x01)
             {
                 IO = 1;
             }
             else
             {
                 IO = 0;
             }
             if(i < 7)
             {
                 delayus();
                 SCK = 1;
                 delayus();
                 cmd >>= 1;
                 SCK = 0;
                 delayus();
             }
             if(i == 7)
             {
                 
                delayus();
                SCK = 1;
                delayus();

             }
         }

         for(i = 0; i < 8; i ++)
         {
              
             if(IO == 1)
                 val |= 0x80;
             else
                 val |= 0x00;
             delayus();
             SCK = 0;
             delayus();

             if(i < 7)
             {
                 SCK = 1;
                 delayus();
             }
             val >>= 1;
         }

         RST = 0;
         delayus();
        return val;
}


void main()
{
    unsigned char HR,MIN,SEC;
    LCD1602_Init();

    DS1302_Write_Data(0x8e,0);     //WP clear
    DS1302_Write_Data(0x80,0x80);//sec stop

    DS1302_Write_Data(0x84,8);//write HR     8
    DS1302_Write_Data(0x82,8);//write MIN     16
    DS1302_Write_Data(0x80,8);//write SEC     24


    DS1302_Write_Data(0x8e,0x80);  // WP start

     

    while(1)
    {
        HR = DS1302_Read_Data(0x85);
        MIN = DS1302_Read_Data(0x83);
        SEC = (DS1302_Read_Data(0x81))&0x7f;
        
//        hr1 = HR/16;
//        hr2 = HR%16;
//        hr = hr1*10 + hr2;
        
        Write_Cmd(0x80);
        Write_Data(num[HR/16]);
        Write_Cmd(0x81);
        Write_Data(num[HR%16]);

        Write_Cmd(0x82);
        Write_Str(":");
        

        Write_Cmd(0x83);
        Write_Data(num[MIN/16]);
        Write_Cmd(0x84);
        Write_Data(num[MIN%16]);

        Write_Cmd(0x85);
        Write_Str(":");

        Write_Cmd(0x86);
        Write_Data(num[SEC/16]);
        Write_Cmd(0x87);
        Write_Data(num[SEC%16]);

            
    }
} */














#include<reg52.h>
#include<intrins.h>


sbit LCD1602_RS = P2^4;
sbit LCD1602_RW = P2^5;
sbit LCD1602_EN = P2^6;

#define LCD1602_DataPort P0

sbit DS1302_SCK = P1^0;
sbit DS1302_IO = P1^1;
sbit DS1302_RST = P1^2;

sbit LED = P1^3;

#define DS1302_SEC 0X80
#define DS1302_MIN 0X82
#define DS1302_HR 0X84
#define DS1302_DATE 0X86
#define DS1302_MONTH 0X88
#define DS1302_DAY 0X8A
#define DS1302_YEAR 0X8C
#define DS1302_CONTOR 0X8E

unsigned char DATE_MSG[] = {24,5,21,21,14,00,2};// year month date hr min sec day
unsigned char DATE_MSG2[7];

unsigned char code NUM_Table[] = "0123456789ABCDEF";


unsigned char T0_t = 0,T0_num = 0, T0_FLAG = 0;
//LCD1602
void delayus(unsigned char t);
void delayms(unsigned int t);
void LCD1602_Write_Data(unsigned char dat);
void LCD1602_Write_Cmd(unsigned char cmd);
void LCD1602_Write_Str(unsigned char *s);
void LCD1602_Init();

//DS1302
void DS1302_Write_Byte(unsigned char cmd, unsigned char dat);
unsigned char DS1302_Read_Byte(unsigned char cmd);
void DS1302_Write_Data();
void DS1302_Read_Data();

//T0定时器

void T0_MODE2_Init();

//main
void main()
{
   T0_MODE2_Init();
   LCD1602_Init();
   DS1302_Write_Data();

//   LCD1602_Write_Cmd(0x80);
//   LCD1602_Write_Str("hello world!");
//
//   LCD1602_Write_Cmd(0x80+0x40);
//   LCD1602_Write_Str("working!!!");

    LCD1602_Write_Cmd(0x80);
    LCD1602_Write_Str("  -  -  ");
    LCD1602_Write_Cmd(0xc0);
    LCD1602_Write_Str("  :  :  ");
   while(1)
   {
           if(T0_FLAG)
        {
            DS1302_Read_Data();
            T0_FLAG = 0;
        }

        LCD1602_Write_Cmd(0x80);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[0]/10]);
//            LCD1602_Write_Cmd(0x81);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[0]%10]);

            LCD1602_Write_Cmd(0x83);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[1]/10]);
//            LCD1602_Write_Cmd(0x84);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[1]%10]);

            LCD1602_Write_Cmd(0x86);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[2]/10]);
//            LCD1602_Write_Cmd(0x87);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[2]%10]);
    
            LCD1602_Write_Cmd(0xC0);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[3]/10]);
//            LCD1602_Write_Cmd(0xC1);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[3]%10]);

            LCD1602_Write_Cmd(0xC3);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[4]/10]);
//            LCD1602_Write_Cmd(0xC4);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[4]%10]);

            LCD1602_Write_Cmd(0xC6);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[5]/10]);
//            LCD1602_Write_Cmd(0xC7);
            LCD1602_Write_Data(NUM_Table[DATE_MSG2[5]%10]);

        
        

   } 
}


void delayms(unsigned int t)
{
    unsigned int i,j;
    for(i = t; i > 0; i --)
    for(j = 110; j > 0; j --);
}

void delayus(unsigned char t)
{
    while(t --)
    {
        _nop_();
    }
}

//LCD1602---------------------------------------
void LCD1602_Write_Data(unsigned char dat)
{
    LCD1602_EN = 0;
//    LCD1602_RW = 1;
    LCD1602_RS = 1;
    
    LCD1602_RW = 0;

    LCD1602_DataPort = dat;
    delayms(5);
//    LCD1602_EN = 0;
//    delayms(5);
    LCD1602_EN = 1;
    delayms(5);
    LCD1602_EN = 0;
}

void LCD1602_Write_Cmd(unsigned char cmd)
{
    LCD1602_EN = 0;
//    LCD1602_RW = 1;
    LCD1602_RS = 0;
    
    LCD1602_RW = 0;

    LCD1602_DataPort = cmd;
    delayms(5);
//    LCD1602_EN = 0;
//    delayms(5);
    LCD1602_EN = 1;
    delayms(5);
    LCD1602_EN = 0;
}

void LCD1602_Write_Str(unsigned char *s)
{
      while(*s != '\0')
      {
              LCD1602_Write_Data(*s);
//            delayms(5);
            s ++;    
      }
      
}

void LCD1602_Init()
{
    LCD1602_Write_Cmd(0x38);
    LCD1602_Write_Cmd(0x0c);
    LCD1602_Write_Cmd(0x06);
    LCD1602_Write_Cmd(0x01);

}

//DS1302-------------------------------------------
/*
void Ds1302_Write_Byte(unsigned char addr, unsigned char d)
{

    unsigned char i;
    RST_SET;    
    
    //写入目标地址:addr
    addr = addr & 0xFE;     //最低位置零
    for (i = 0; i < 8; i ++) 
        { 
        if (addr & 0x01) 
            {
            IO_SET;
            }
        else 
            {
            IO_CLR;
            }
        SCK_SET;
        SCK_CLR;
        addr = addr >> 1;
        }
    
    //写入数据:d
    for (i = 0; i < 8; i ++) 
       {
        if (d & 0x01) 
            {
            IO_SET;
            }
        else 
            {
            IO_CLR;
            }
        SCK_SET;
        SCK_CLR;
        d = d >> 1;
        }
    RST_CLR;                    //停止DS1302总线
}*/
void DS1302_Write_Byte(unsigned char cmd, unsigned char dat)
{
    unsigned char i;

    DS1302_RST = 0;
    DS1302_SCK = 0;

    DS1302_RST = 1;
    delayus(15);
    
    for(i = 0; i < 8; i ++)
    {
        delayus(15);

        if((cmd&0x01) == 0x01)
        {
            DS1302_IO = 1;
        }
        else
            DS1302_IO = 0;

        DS1302_SCK = 1;
        delayus(15);

        
        DS1302_SCK = 0;
        cmd >>= 1;
    }

    for(i = 0; i < 8; i ++)
    {
        delayus(15);
        if((dat&0x01) == 0x01)
            DS1302_IO = 1;
        else
            DS1302_IO = 0;

        DS1302_SCK = 1;
        delayus(15);

        
        DS1302_SCK = 0;

        dat >>= 1;
    }

    delayus(15);
    DS1302_RST = 0;
    delayus(15);
}

unsigned char DS1302_Read_Byte(unsigned char cmd)
{
    unsigned char i,dat,val;

    dat = (cmd|0x01);

    DS1302_RST = 0;
    DS1302_SCK = 0;

    DS1302_RST = 1;
    delayus(15);
    
    for(i = 0; i < 8; i ++)
    {
        delayus(15);

        if((dat&0x01) == 0x01)
        {
            DS1302_IO = 1;
        }
        else
            DS1302_IO = 0;

        DS1302_SCK = 1;
        delayus(15);

        
        DS1302_SCK = 0;
        dat >>= 1;
    }

    for(i = 0; i < 8; i ++)
    {
        val >>= 1;      //这一句找了好久,不然放最后,2s过去了秒才能+1 ,而且数据不对
        delayus(15);

        if(DS1302_IO == 1)
            val |= 0x80;    
        delayus(15);

        DS1302_SCK = 1;
        delayus(15);

        
        DS1302_SCK = 0;
        
    }

    delayus(15);
    DS1302_RST = 0;
    delayus(15);
    
    return val;
}

void DS1302_Write_Data()
{
    unsigned char i ,tmp1;
    for(i = 0; i < 7; i ++)
    {
        tmp1 = DATE_MSG[i]/10;
        DATE_MSG[i] = DATE_MSG[i]%10;

        DATE_MSG2[i] = tmp1*16 + DATE_MSG[i]; 

    }

    DS1302_Write_Byte(DS1302_CONTOR, 0x00);//WP DISABLE
    DS1302_Write_Byte(DS1302_SEC, 0X80);//STOP COUNT
    DS1302_Write_Byte(DS1302_YEAR, DATE_MSG2[0]);
    DS1302_Write_Byte(DS1302_MONTH, DATE_MSG2[1]);
    DS1302_Write_Byte(DS1302_DATE, DATE_MSG2[2]);
    DS1302_Write_Byte(DS1302_HR, DATE_MSG2[3]);
    DS1302_Write_Byte(DS1302_MIN, DATE_MSG2[4]);
    
    DS1302_Write_Byte(DS1302_DAY, DATE_MSG2[6]);
    DS1302_Write_Byte(DS1302_SEC, DATE_MSG2[5]);//START COUNT

    DS1302_Write_Byte(DS1302_CONTOR, 0x80);// WP ENABLE

}

void DS1302_Read_Data()
{
    unsigned char i ,tmp1;


    
    DATE_MSG[0] = DS1302_Read_Byte(DS1302_YEAR);
    DATE_MSG[1] = DS1302_Read_Byte(DS1302_MONTH);
    DATE_MSG[2] = DS1302_Read_Byte(DS1302_DATE);
    DATE_MSG[3] = DS1302_Read_Byte(DS1302_HR);
    DATE_MSG[4] = DS1302_Read_Byte(DS1302_MIN);
    DATE_MSG[5] = DS1302_Read_Byte(DS1302_SEC)&0X7F;
    DATE_MSG[6] = DS1302_Read_Byte(DS1302_DAY);

    

    for(i = 0; i < 7; i ++)
    {
        tmp1 = DATE_MSG[i]/16;
        DATE_MSG2[i] = DATE_MSG[i]%16;

        DATE_MSG2[i] = tmp1*10 + DATE_MSG2[i]; 

    }
   
}


//T0
void T0_MODE2_Init()
{
    TMOD = 0x02;

    TH0 = (256-230);
    TL0 = (256-230);
    ET0 = 1;
    TR0 = 1;
    EA = 1;
}


void T0_Ser() interrupt 1
{
     T0_t ++;
     if(T0_t >= 40)
     {
         T0_t = 0;
        T0_num ++;
        {
            if(T0_num >= 100)
            {
                T0_num = 0;
                T0_FLAG = 1;
                LED = !LED;
            }
        }
     }
      
      
}

 

posted @ 2024-05-21 21:32  了解2号  阅读(128)  评论(0编辑  收藏  举报