找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5556|回复: 1
收起左侧

51单片机实现 lcd1602时间显示

[复制链接]
ID:433198 发表于 2018-11-26 09:16 | 显示全部楼层 |阅读模式
主函数
#include<reg52.h>

#include<lcd.h>
#include<ds1302.h>

void LcdDisplay();

void main()
{
    LcdInit();                                                                   //lcd初始化
        Ds1302Init();                                                           //Ds1302初始化                 
    while(1)
    {
           Ds1302ReadTime();
       LcdDisplay();
    }                                                           //lcd显示
}

void LcdDisplay()
{
        LcdWriteCom(0x80);                                                        //第一行
        LcdWriteData('2');
        LcdWriteData('0');
        LcdWriteData('0'+TIME[6]/16);                            
        LcdWriteData('0'+(TIME[6]&0x0f));                        //年
        LcdWriteData('-');
        LcdWriteData('0'+TIME[4]/16);                    
        LcdWriteData('0'+(TIME[4]&0x0f));                        //月
        LcdWriteData('-');
        LcdWriteData('0'+TIME[3]/16);                            
        LcdWriteData('0'+(TIME[3]&0x0f));                        //日                                       

        LcdWriteCom(0x80+0x40);                                                //第二行
        LcdWriteData('0'+TIME[2]/16);
        LcdWriteData('0'+(TIME[2]&0x0f));                        //时         
        LcdWriteData('-');
        LcdWriteData('0'+TIME[1]/16);                               
        LcdWriteData('0'+(TIME[1]&0x0f));                         //分
        LcdWriteData('-');
        LcdWriteData('0'+TIME[0]/16);                       
        LcdWriteData('0'+(TIME[0]&0x0f));                         //秒
        LcdWriteData(' ');
        LcdWriteData(' ');
}

lcd.c

#include<lcd.h>

void Lcd1602_Delay1ms(uint c)   //延时函数
{
    uchar a,b;
        for (; c>0; c--)
        {
                 for (b=199;b>0;b--)
                 {
                          for(a=1;a>0;a--);
                 }      
        }
           
}

#ifndef         LCD1602_4PINS                 //当没有定义这个LCD1602_4PINS的时候
void LcdWriteCom(uchar com)                 //写入命令
{
        LCD1602_E = 0;                  //使能
        LCD1602_RS = 0;                        //选择发送命令
        LCD1602_RW = 0;                        //选择写入
                                          
        LCD1602_DATAPINS = com;         //发送命令
        Lcd1602_Delay1ms(1);                    //等待数据稳定
                                                          
        LCD1602_E = 1;                        //写入时序
        Lcd1602_Delay1ms(5);                //保持时间
        LCD1602_E = 0;
}
#else                                                   
void LcdWriteCom(uchar com)                //写入命令
{
        LCD1602_E = 0;         //使能清零
        LCD1602_RS = 0;         //选择写入命令
        LCD1602_RW = 0;         //选择写入

        LCD1602_DATAPINS = com;                 //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;                        //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;

//        Lcd1602_Delay1ms(1);
        LCD1602_DATAPINS = com << 4;    //发送低四位
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;                        //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;
}
#endif
                  
#ifndef         LCD1602_4PINS                  
void LcdWriteData(uchar dat)                        //写入数据
{
        LCD1602_E = 0;                            //使能清零
        LCD1602_RS = 1;                            //选择输入数据
        LCD1602_RW = 0;                            //选择写入
                                                                          
        LCD1602_DATAPINS = dat;             //写入数据
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;                      //写入时序
        Lcd1602_Delay1ms(5);                //保持时间
        LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)                        //写入数据
{
        LCD1602_E = 0;                            //使能清零
        LCD1602_RS = 1;                            //选择写入数据
        LCD1602_RW = 0;                            //选择写入

        LCD1602_DATAPINS = dat;                 //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;                            //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;

        LCD1602_DATAPINS = dat << 4;        //写入低四位
        Lcd1602_Delay1ms(1);

        LCD1602_E = 1;                           //写入时序
        Lcd1602_Delay1ms(5);
        LCD1602_E = 0;
}
#endif
                  
#ifndef                LCD1602_4PINS
void LcdInit()                                   //LCD初始化子程序
{
        LcdWriteCom(0x38);                 //开显示
        LcdWriteCom(0x0c);                 //开显示不显示光标
        LcdWriteCom(0x06);                 //写一个指针加1
        LcdWriteCom(0x01);                 //清屏
        LcdWriteCom(0x80);                 //设置数据指针起点
}
#else
void LcdInit()                                                  //LCD初始化子程序
{
        LcdWriteCom(0x32);                      //将8位总线转为4位总线
        LcdWriteCom(0x28);                      //在四位线下的初始化
        LcdWriteCom(0x0c);                //开显示不显示光标
        LcdWriteCom(0x06);                //写一个指针加1
        LcdWriteCom(0x01);                //清屏
        LcdWriteCom(0x80);                //设置数据指针起点
}
#endif


lcd.h
#ifndef __LCD_H_
#define __LCD_H_

//#define LCD1602_4PINS

#include<reg52.h>

#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif

#define LCD1602_DATAPINS P0

sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;


void Lcd1602_Delay1ms(uint c);    /*在51单片机12MHZ时钟下的延时函数*/

void LcdWriteCom(uchar com);      /*LCD1602写入8位命令子函数*/
       
void LcdWriteData(uchar dat);     /*LCD1602写入8位数据子函数*/
               
void LcdInit();                                          /*LCD1602初始化子程序*/          

#endif


ds1302.c
#include<ds1302.h>

uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};           //DS1302写入和读取时分秒的地址命令
uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};          //秒分时日月周年 最低位读写位

uchar TIME[7] = {0, 0, 0x12, 0x24, 0x11, 0x02, 0x18};                                                  //DS1302时钟初始化2013年1月1日星期二12点00分00秒

void Ds1302Write(uchar addr, uchar dat)
{
        uchar n;
        RST = 0;
        _nop_();

        SCLK = 0;                            //先将SCLK置低电平                                    
        _nop_();                                                  
        RST = 1;                                                            //然后将RST(CE)置高电平                                                       
        _nop_();

        for (n=0; n<8; n++)                                        //开始传送八位地址命令                                                                     
        {
                DSIO = addr & 0x01;              //数据从低位开始传送                                    
                addr >>= 1;
                SCLK = 1;                        //数据在上升沿时,DS1302读取数据                                    
                _nop_();
                SCLK = 0;
                _nop_();
        }
        for (n=0; n<8; n++)                  //写入8位数据                                    
        {
                DSIO = dat & 0x01;
                dat >>= 1;
                SCLK = 1;                       //数据在上升沿时,DS1302读取数据                                      
                _nop_();
                SCLK = 0;
                _nop_();       
        }       
                 
        RST = 0;                           //传送数据结束                                       
        _nop_();
}

uchar Ds1302Read(uchar addr)
{
        uchar n,dat,dat1;
        RST = 0;
        _nop_();

        SCLK = 0;                          //先将SCLK置低电平。                                       
        _nop_();
        RST = 1;                          //然后将RST(CE)置高电平。
        _nop_();

        for(n=0; n<8; n++)                //开始传送八位地址命令
        {                                                          
                DSIO = addr & 0x01;           //数据从低位开始传送
                addr >>= 1;
                SCLK = 1;                     //数据在上升沿时,DS1302读取数据
                _nop_();
                SCLK = 0;                     //DS1302下降沿时,放置数据
                _nop_();
        }
        _nop_();
        for(n=0; n<8; n++)                //读取8位数据
        {
                dat1 = DSIO;                  //从最低位开始接收
                dat = (dat>>1) | (dat1<<7);
                SCLK = 1;
                _nop_();
                SCLK = 0;                     //DS1302下降沿时,放置数据
                _nop_();
        }

        RST = 0;
        _nop_();                              //以下为DS1302复位的稳定时间,必须的。
        SCLK = 1;
        _nop_();
        DSIO = 0;
        _nop_();
        DSIO = 1;
        _nop_();
        return dat;       
}

void Ds1302Init()
{
        uchar n;                                         
        Ds1302Write(0x8E,0X00);                     //禁止写保护,就是关闭写保护功能
        for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
        {
                Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);       
        }
        Ds1302Write(0x8E,0x80);                     //打开写保护功能
}

void Ds1302ReadTime()                             //读取7个字节的时钟信号:分秒时日月周年                                                          
{
        uchar n;
        for (n=0; n<7; n++)      
        {
                TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
        }
               
}



ds1302.h

#ifndef __DS1302_H_
#define __DS1302_H_

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

#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int
#endif

sbit DSIO=P3^4;
sbit RST=P3^5;
sbit SCLK=P3^6;

void Ds1302Write(uchar addr, uchar dat);

uchar Ds1302Read(uchar addr);

void Ds1302Init();

void Ds1302ReadTime();

extern uchar TIME[7];   //加入全局变量

#endif





回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表