首页 > 其他分享 >DS1302时钟芯片使用51单片机

DS1302时钟芯片使用51单片机

时间:2024-05-21 21:43:54浏览次数:27  
标签:DS1302 51 unsigned Write 单片机 LCD1602 DATE Data

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;
            }
        }
     }
      
      
}

 

标签:DS1302,51,unsigned,Write,单片机,LCD1602,DATE,Data
From: https://www.cnblogs.com/chillytao-suiyuan/p/18204987

相关文章

  • CF1515F Phoenix and Earthquake
    CF1515FPhoenixandEarthquake证明题。思路考虑不合法的情况,如果\(\suma_i<(n-1)\timesx\),肯定是不合法的。再考虑对于一个可行的情况,最后缩的边肯定形成一棵树,所以我们大胆假设:任意一棵生成树只要满足\(\suma_i\geq(n-1)\timesx\)有合法的缩边方案。考虑归纳证......
  • MT3516W-ASEMI变频器整流桥MT3516W
    编辑:llMT3516W-ASEMI变频器整流桥MT3516W型号:MT3516W品牌:ASEMI封装:MT-W正向电流(Id):35A反向耐压(VRRM):1600V正向浪涌电流:450A正向电压(VF):1.20V引脚数量:5芯片个数:5芯片尺寸:102MIL功率(Pd):大功率设备工作温度:-55°C~150°C类型:整流方桥、插件整流桥、针脚应用领域工业电......
  • 在友晶DE10-Lite开发板实现8051单片机
    在友晶DE10-Lite开发板实现8051单片机1. 移植过程利用FPGA片内资源构建51系统。软核来自https://www.oreganosystems.at/。还需要添加rom、ram和ramx。rom用来放51单片机的程序,即编译后的.hex文件。ram用来运行51单片机程序。时钟由PLLIP生成20MHz的时钟信号。分配管脚,编译配......
  • 洛谷 P10512 序列合并
    哭死,比赛的时候完全想歪了,想的是考虑一次合并能造成多大的贡献,按照贡献排序然后合并。这样做只能考虑局部造成的贡献,然而最后算的时候要考虑整体,所以并不是很对。正着想没有思路就可以倒着想,考虑枚举答案。合并k次,意味着最后是n-k个数。经典从二进制高位到低位考虑,考虑这一位(假......
  • 20240519比赛总结
    T1Colorhttps://gxyzoj.com/d/hzoj/p/3692显然,答案与元素的位置无关,只与个数有关考虑每个元素能经过若干次操作变成n个的概率,记\(p_i\)为i个数能变到n个数的概率进行一次操作后,会分成三种情况,+1,-1,和不变,所以式子是:\[p_i=\dfrac{i(n-i)}{n(n-1)}p_{i-1}+\dfrac{i(n-i)}{n(n......
  • 20240519刷题总结
    T1(数学化审题)541。观察到其实和最初功率没有关系,功率就是个系数,于是可以把系数提出来。于是定义f[i]为功率为1,i~n最长信息。直接转移就好。#include<iostream>#include<algorithm>#include<cstdio>#include<algorithm>usingnamespacestd;constintN=100010;......
  • 0519 基础特征数列
    1.质数数列235711131719232931+1变形34681214倒序变形29231917131175加和变形3(2+1)5(3+2)8(5+3)11(7+4)16(11+5)19(13+6)24(17+7)2.合数数列468910121415(偶数里夹了1个奇数)3.周期数列1341341......
  • AT89S52单片机寻址时未用到的地址线同时设置为‘1’或‘0’的原因
    AT89S52单片机寻址时未用到的地址线同时设置为‘1’或‘0’的原因在AT89S52单片机或其他类似微控制器中,未用到的地址线需要设置为同为0或同为1的原因主要与以下几个方面有关:1.确定性和稳定性确保未用到的地址线设置为同一电平(全为0或全为1)可以避免这些未使用的引脚在悬空状态......
  • [20240515]vim bccalc_XXX.vim使用插件简介.txt
    [20240515]vimbccalc_XXX.vim使用插件简介.txt--//这是我改写vim.org网站的一个调用bc做计算的一个插件bccalc.vim,感觉自己越写越复杂.做一个介绍,便于自己查阅.--//另外注意如果选择多行,结尾要像C语言一样使用分号(;).--//我已经统一在selectvisualnormal模式都是<leader>作......
  • [20240515]建立完善t2sh.sql脚本.txt
    [20240515]建立完善t2sh.sql脚本.txt--//建立一个简单输入简单文本计算sql_id,hash_values的sql脚本,主要用于简单sql语句以及对象的full_hash_value,sql_id,hash_value计算.--Copyright2023lfree.Allrightsreserved.--LicensedundertheApacheLicense,Version2.0.Se......