时钟DS1302LCD

/********************************************************************
* 描述    :  该文件实现用DS1302来实现日历和时钟功能,液晶1602上显示出来。
***********************************************************************/
#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint  unsigned int

sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;

sbit T_CLK = P1^6; /*实时时钟时钟线引脚 */
sbit T_IO = P3^5; /*实时时钟数据线引脚 */
sbit T_RST = P1^7; /*实时时钟复位线引脚 */

//这三个引脚参考资料
sbit E=P2^7;        //1602使能引脚
sbit RW=P2^6;        //1602读写引脚    
sbit RS=P2^5;        //1602数据/命令选择引脚

/********************************************************************
* 名称 : delay()
* 功能 : 延时,延时时间大概为140US。
* 输入 : 无
* 输出 : 无
***********************************************************************/

void delay()
{
    int i,j;
    for(i=0; i<=10; i++)
    for(j=0; j<=2; j++)
;
}


/********************************************************************
* 名称 : enable(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/

void enable(uchar del)
{
    P0 = del;
    RS = 0;
    RW = 0;
    E = 0;
    delay();
    E = 1;
    delay();
}

/********************************************************************
* 名称 : write(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/

void write(uchar del)
{
    P0 = del;
    RS = 1;
    RW = 0;
    E = 0;
    delay();
    E = 1;
    delay();
}

/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{
    enable(0x01);
    enable(0x38);
    enable(0x0c);
    enable(0x06);
    enable(0xd0);
}

/********************************************************************
* 名称 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下
         L1602_char(1,5,'b')
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
    uchar a;
    if(hang == 1) a = 0x80;
    if(hang == 2) a = 0xc0;
    a = a + lie - 1;
    enable(a);
    write(sign);
}

/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
          L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
    uchar a;
    if(hang == 1) a = 0x80;
    if(hang == 2) a = 0xc0;
    a = a + lie - 1;
    enable(a);
    while(1)
    {
        if(*p == '\0') break;
        write(*p);
        p++;
    }
}

/********************************************************************
* 名称 :  v_RTInputByte()
* 功能 :  往DS1302写入1Byte数据
* 输入 :  ucDa 写入的数据
* 输出 :  无
***********************************************************************/
void v_RTInputByte(uchar ucDa)
{
    uchar i;
    ACC = ucDa;
    T_RST = 1;
    for(i=8; i>0; i--)
    {
        T_IO = ACC0;
        T_CLK = 1;
        T_CLK = 0;
        ACC = ACC >> 1;
    }
}

/********************************************************************
* 名称  :   uc_RTOutputByte()
* 功能  :   从DS1302读取1Byte数据
* 输入  :    无
* 返回值:   ACC
***********************************************************************/
uchar uc_RTOutputByte(void) 
{
    uchar i;
    T_RST = 1;
    for(i=8; i>0; i--)
    {
        ACC = ACC >>1;
        T_IO=1;
        ACC7 = T_IO;
        T_CLK = 1;
        T_CLK = 0;
    }
    return(ACC);
}

/********************************************************************
* 名称   :   v_W1302(uchar ucAddr, uchar ucDa)
* 功能   :   往DS1302写入数据
* 输入   :   ucAddr: DS1302地址, ucDa: 要写的数据
* 返回值 :   无
***********************************************************************/
void v_W1302(uchar ucAddr, uchar ucDa)
{
    T_RST = 0;
    T_CLK = 0;
    T_RST = 1;
    v_RTInputByte(ucAddr);   // 写地址 
    _nop_();
    _nop_();
    v_RTInputByte(ucDa);     // 写1Byte数据
    T_CLK = 1;
    T_RST = 0;
}

/********************************************************************
* 名称   :  uc_R1302(uchar ucAddr)
* 功能   :  读取DS1302某地址的数据
* 输入   :  ucAddr: DS1302地址
* 返回值 :  ucDa :读取的数据
***********************************************************************/
uchar uc_R1302(uchar ucAddr)
{
    uchar ucDa;
    T_RST = 0;
    T_CLK = 0;
    T_RST = 1;
    v_RTInputByte(ucAddr);    //写地址,命令
    _nop_();
    _nop_();
    ucDa = uc_RTOutputByte(); //读1Byte数据
    T_CLK = 1;
    T_RST = 0;
    return(ucDa);
}

/********************************************************************
* 名称   :  v_BurstW1302T
* 功能   :  往DS1302写入时钟数据(多字节方式)
* 输入   :  pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制
*                            8Byte (BCD码) 1B 1B 1B 1B 1B 1B  1B  1B
* 返回值 :  无
***********************************************************************/
void v_BurstW1302T(uchar *pSecDa)
{
    uchar i;
    v_W1302(0x8e, 0x00);          //控制命令,WP=0,写操作
    T_RST = 0;
    T_CLK = 0;
    T_RST = 1;
    v_RTInputByte(0xbe);          //0xbe:时钟多字节写命令
    for(i=8; i>0; i--)            //8Byte = 7Byte 时钟数据 + 1Byte 控制
    {
        v_RTInputByte(*pSecDa);   //写1Byte数据
        pSecDa++;
    }
    T_CLK = 1;
    T_RST = 0;
}

/********************************************************************
* 名称   :  v_BurstR1302T(uchar *pSecDa)
* 功能   :  读取DS1302时钟数据
* 输入   :  pSecDa: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年
*                            7Byte (BCD码) 1B 1B 1B 1B 1B 1B   1B
* 返回值 :  ucDa :读取的数据
***********************************************************************/
void v_BurstR1302T(uchar *pSecDa)
{
    uchar i;
    T_RST = 0;
    T_CLK = 0;
    T_RST = 1;
    v_RTInputByte(0xbf);               //0xbf:时钟多字节读命令
    for(i=8; i>0; i--)
    {
        *pSecDa = uc_RTOutputByte();   //读1Byte数据
        pSecDa++;
    }
    T_CLK = 1;
    T_RST = 0;
}

/********************************************************************
* 名称   :  v_BurstW1302R(uchar *pReDa)
* 功能   :  往DS1302寄存器数写入数据(多字节方式)
* 输入   :  pReDa: 寄存器数据地址
* 返回值 :  无
***********************************************************************/
void v_BurstW1302R(uchar *pReDa)
{
    uchar i;
    v_W1302(0x8e,0x00);         //控制命令,WP=0,写操作
    T_RST = 0;
    T_CLK = 0;
    T_RST = 1;
    v_RTInputByte(0xfe);       //0xbe:时钟多字节写命令
    for(i=31; i>0; i--)        //31Byte 寄存器数据
    {
        v_RTInputByte(*pReDa); //写1Byte数据
        pReDa++;
    }
    T_CLK = 1;
    T_RST = 0;
}

/********************************************************************
* 名称   :  v_BurstR1302R(uchar *pReDa)
* 功能   :  读取DS1302寄存器数据
* 输入   :  pReDa: 寄存器数据地址
* 返回值 :  无
***********************************************************************/
void v_BurstR1302R(uchar *pReDa)
{
    uchar i;
    T_RST = 0;
    T_CLK = 0;
    T_RST = 1;
    v_RTInputByte(0xff);            //0xbf:时钟多字节读命令
    for(i=31; i>0; i--)             //31Byte 寄存器数据
    {
        *pReDa = uc_RTOutputByte(); //读1Byte数据
        pReDa++;
    }
    T_CLK = 1;
    T_RST = 0;
}

/********************************************************************
* 名称  :  v_Set1302(uchar *pSecDa)
* 功能  :  设置初始时间
* 输入  :  pSecDa: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年
*                                    7Byte (BCD码) 1B 1B 1B 1B 1B 1B  1B
* 返回值: 无
***********************************************************************/
void v_Set1302(uchar *pSecDa)
{
    uchar i;
    uchar ucAddr = 0x80;
    v_W1302(0x8e, 0x00);            //控制命令,WP=0,写操作
    for(i=7; i>0; i--)
    {
        v_W1302(ucAddr, *pSecDa);   // 秒 分 时 日 月 星期 年
        pSecDa++;
        ucAddr += 2;
    }
    v_W1302(0x8e, 0x80);            //控制命令,WP=1,写保护
}

/********************************************************************
* 名称   : v_Get1302(uchar ucCurtime[])
* 功能   : 读取DS1302当前时间
* 输入   : ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年
*                                         7Byte (BCD码) 1B 1B 1B 1B 1B  1B  1B
* 返回值 : 无
***********************************************************************/
void v_Get1302(uchar ucCurtime[])
{
    uchar i;
    uchar ucAddr = 0x81;
    for(i=0; i<7; i++)
    {
        ucCurtime[i] = uc_R1302(ucAddr);    //格式为: 秒 分 时 日 月 星期 年
        ucAddr += 2;
    }
}

/********************************************************************
* 名称 : dectobcd(uchar dec)
* 功能 : DEC码转换为BCD码
* 输入 : dec码
* 输出 : bcd码
***********************************************************************/
uchar dectobcd(uchar dec)
{
    uchar bcd;
    bcd = 0;
    while(dec >= 10)
    {              
        dec -= 10;                         
        bcd++;
    } 
    bcd <<= 4;
    bcd |= dec;
    return bcd;
}

/********************************************************************
* 名称 : bcdtodec(uchar bcd)
* 功能 : BCD码转换为DEC码
* 输入 : bcd码
* 输出 : dec码
***********************************************************************/
uchar bcdtodec(uchar bcd)
{
    uchar data1;
    data1 = bcd & 0x0f;     //取BCD低4位
    bcd = bcd & 0x70;       //剔除BCD的最高位和低4位。
    data1 += bcd >> 1;
    data1 += bcd >> 3;      //用位移代替乘法运算
    return data1;
}

/********************************************************************
* 名称 : Write_DS1302Init()
* 功能 : 往DS1302中写入数据。最开始显示的数据就是在这里设置的。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Write_DS1302Init(void)
{
    v_W1302(0x8e,0);
    v_W1302(0x80,0x50);    //写入秒
    v_W1302(0x8e,0);
    v_W1302(0x82,0x59);    //写入分
    v_W1302(0x8e,0);
    v_W1302(0x84,0x07);    //写入小时
    v_W1302(0x8e,0);
    v_W1302(0x86,0x08);    //写入日
    v_W1302(0x8e,0);
    v_W1302(0x88,0x08);    //写入月
    v_W1302(0x8e,0);
    v_W1302(0x8a,0x05);    //写入星期
    v_W1302(0x8e,0);
    v_W1302(0x8c,0x08);    //写入年    
}

/********************************************************************
* 名称 : Run_DS1302(void)
* 功能 : 读出DS1302中的数据,并在液晶1602上进行显示
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Run_DS1302(void)
{
    uchar sec, min, hour, day, month, year;
    while(1)
    {
        v_W1302(0x8f, 0);
        sec = bcdtodec(uc_R1302(0x81));       //读出DS1302中的秒
        v_W1302(0x8f, 0);
        min = bcdtodec(uc_R1302(0x83));       //读出DS1302中的分
        v_W1302(0x8f, 0);
        hour = bcdtodec(uc_R1302(0x85));   //读出DS1302中的小时
        v_W1302(0x8f, 0);
        day = bcdtodec(uc_R1302(0x87));       //读出DS1302中的日
        v_W1302(0x8f, 0);
        month = bcdtodec(uc_R1302(0x89));  //读出DS1302中的月
        v_W1302(0x8f, 0);
        year = bcdtodec(uc_R1302(0x8d));   //读出DS1302中的年

        L1602_char(2, 6, hour / 10 % 10 + 48);
        L1602_char(2, 7, hour % 10 + 48);
        L1602_char(2, 8, '-');
        L1602_char(2, 9, min / 10 % 10 + 48);
        L1602_char(2, 10, min % 10 + 48);
        L1602_char(2, 11, '-');
        L1602_char(2, 12, sec / 10 % 10 + 48);
        L1602_char(2, 13, sec % 10 + 48);
        L1602_char(1, 8, year / 10 % 10 + 48);
        L1602_char(1, 9, year % 10 + 48);
        L1602_char(1, 10, '-');
        L1602_char(1, 11, month / 10 % 10 + 48);
        L1602_char(1, 12, month % 10 + 48);
        L1602_char(1, 13, '-');
        L1602_char(1, 14, day / 10 % 10 + 48);
        L1602_char(1, 15, day % 10 + 48);
    }

/********************************************************************
* 名称 : Main(void)
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/ 
void Main(void)
{
    L1602_init();
    L1602_string(1,1,"DAYS 20");
    L1602_string(2,1,"TIME");
    Write_DS1302Init();
    Run_DS1302();
}

相关推荐

  1. 时钟DS1302LCD

    2023-12-13 10:24:05       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-13 10:24:05       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-13 10:24:05       106 阅读
  3. 在Django里面运行非项目文件

    2023-12-13 10:24:05       87 阅读
  4. Python语言-面向对象

    2023-12-13 10:24:05       96 阅读

热门阅读

  1. 力扣-242. 有效的字母异位词

    2023-12-13 10:24:05       69 阅读
  2. Ajax 请求的原理

    2023-12-13 10:24:05       63 阅读
  3. LeetCode 2697. 字典序最小回文串

    2023-12-13 10:24:05       65 阅读
  4. linux查看某个时间段的日志(sed -n)

    2023-12-13 10:24:05       62 阅读
  5. 第二步:私有镜像仓库Harbor的使用

    2023-12-13 10:24:05       57 阅读
  6. 1032 挖掘机技术哪家强

    2023-12-13 10:24:05       65 阅读