找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5450|回复: 4
收起左侧

stc15单片机+LCD1602制作万年历

[复制链接]
ID:272080 发表于 2018-1-5 19:11 | 显示全部楼层 |阅读模式
代码如下:

此程序在stc15系列单片机上运行无误  如需换成51单片机运行  只需要更改温度函数中的延时函数即可,应为15系列单片机的运行速度为51的10倍左右


微信图片_20171231171017.jpg

此为效果图


微信截图_20180105190556.png 微信截图_20180105190625.png
1515150439(1).jpg


此为电路图


#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int

sfr AUXR=0x8e;

sbit rw=P2^1;
sbit rs=P2^0;
sbit en=P1^2;

sbit CE=P1^3;
sbit SCL=P1^7;
sbit io=P2^3;

sbit DQ=P1^4;

uchar hang1[17]={"temperature=    "};                        //温度显示
uchar hang2[17]={"2000-00-00-00-00"};                        //时间日期显示
                                //年   月 时 分 秒

uchar hang3[17]={"Happy New Year!"};

uchar int_ds[]={50,59,23,31,12,7,17};                         //初始化时间
                        //  秒分 时 日 月 周 年
uchar cmd_ds[7];                                                                //存放读取的时间

uchar new_char[]={0x04,0x0e,0x15,0x04,0x04,0x04,0x04,0x00};         //一个新的字符

uint sec_add;
bit sec_flag;

void int_t0();

void w_cmd(uchar cmd);                                                                 //1602写一个命令
void w_dat(uchar dat);                                                                 //1602写一个数据
void int_1602();                                                                         //初始化1602
void w_zfc(uchar x,uchar y,uchar *p);                                 //写入一个字符串
void delay_ms(uint time);                                                         //毫秒延时
void add_char(uchar cmd,uchar *p);                                         //新增一个自定义字符   cmd为字符地址  *p为字符点阵函数

void DS1302_wuchar(uchar cmd);                                                 //1302写入一个字节命令
uchar DS1302_ruchar();                                                                 //1302读取一个字节命令
void write_DS1302(uchar cmd,uchar dat);                                //向cmd寄存器写入一个dat命令
uchar red_DS1302();                                                                        //读取一个字节函数
void red_ds();                                                                                //
void int_DS1302();                                                                        

uchar red_temp();                                                        //温度传感器函数
void DS_int();
void write_DS(uchar cmd);
uchar red_DS_1820();
void Delay500us();
void Delay100us();

void main()
{
        uchar temp;
        int_1602();
        int_t0();
        int_DS1302();        
        add_char(0,new_char);
        w_zfc(0,0,hang1);
        w_zfc(0,1,hang2);
        while(1)
        {
                red_ds();

                if(sec_flag)
                {
                        temp=red_temp();
                        sec_flag=0;
                }
                hang1[12]=temp/10+0x30;
                hang1[13]=temp%10+0x30;

                hang2[14]=cmd_ds[0]/10+0x30;        //秒
                hang2[15]=cmd_ds[0]%10+0x30;

                hang2[11]=cmd_ds[1]/10+0x30;        //分
                hang2[12]=cmd_ds[1]%10+0x30;

                hang2[8]=cmd_ds[2]/10+0x30;                //时
                hang2[9]=cmd_ds[2]%10+0x30;

                hang2[2]=cmd_ds[6]/10+0x30;        //年
                hang2[3]=cmd_ds[6]%10+0x30;

                hang2[5]=cmd_ds[4]/10+0x30;        //月
                hang2[6]=cmd_ds[4]%10+0x30;


                w_zfc(0,0,hang1);
                w_zfc(0,1,hang2);
        }
}

void t0() interrupt 1
{
         sec_add++;
         if(sec_add==1000)
         {
                 sec_add=0;
                sec_flag=1;
         }
}

void int_t0()
{
        AUXR |= 0x80;                //定时器时钟1T模式
        TMOD &= 0xF0;                //设置定时器模式
        TL0 = 0xCD;                //设置定时初值
        TH0 = 0xD4;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时        
        EA=1;
        ET0=1;
}

void w_cmd(uchar cmd)
{
        rs=0;
        rw=0;
        en=0;
        P0=cmd;
        delay_ms(1);
        en=1;
        delay_ms(1);
        en=0;
}

void w_dat(uchar dat)
{
        rs=1;
        rw=0;
        en=0;
        P0=dat;
        delay_ms(1);
        en=1;
        delay_ms(1);
        en=0;
}

void int_1602()
{
        w_cmd(0x38);
        w_cmd(0x08);
        w_cmd(0x01);
        w_cmd(0x06);
        w_cmd(0x0c);
}

void add_char(uchar cmd,uchar *p)
{
        uchar i;
        cmd<<=4;
        for(i=0;i<8;i++)
        {
                w_cmd(0x40|cmd+i);
                w_dat(*p);
                p++;
        }
}

void w_zfc(uchar x,uchar y,uchar *p)
{
        if(y==0)
        w_cmd(0x80+x);
        else
        w_cmd(0xc0+x);

        while(*p!='\0')
        {
                w_dat(*p);
                p++;
        }
}

void delay_ms(uint time)                                         //毫秒延时函数   根据单片机速度不同更改  此处为15系列单片机速度  51应i应改成120左右
{
        uint i;
        while(time--)
        {
                for(i=0;i<800;i++);
        }
}




void int_DS1302()          //初始化DS1302,把int_ds[]数组里的数写入相应时间寄存器地址
{
        write_DS1302(0x8e,0x00);
        write_DS1302(0x80,int_ds[0]);                //miao
        write_DS1302(0x82,int_ds[1]);                //fen
        write_DS1302(0x84,int_ds[2]);                //shi
    write_DS1302(0x86,int_ds[3]);           //ri
        write_DS1302(0x88,int_ds[4]);           //yue
        write_DS1302(0x8a,int_ds[5]);           //zhou
        write_DS1302(0x8c,int_ds[6]);           //nian
        write_DS1302(0x8e,0x80);
}

void DS1302_wuchar(uchar cmd)
{
        uchar i;
        for(i=0;i<8;i++)
        {
                SCL=0;
                io=cmd&0x01;
                SCL=1;
                cmd>>=1;
        }
}

uchar DS1302_ruchar()
{
        uchar dat,i;
        for(i=0;i<8;i++)
        {
                SCL=0;
                dat>>=1;
                if(io)
                dat|=0x80;        
                SCL=1;
        }
        return dat;        
}

void write_DS1302(uchar cmd,uchar dat)
{
        uchar x;
        CE=0;
        SCL=0;
        CE=1;
        DS1302_wuchar(cmd);        
        x=(dat/10<<4)|(dat%10);//十进制转换十六进制
        DS1302_wuchar(x);
        CE=0;        
}

uchar red_DS1302(uchar cmd)
{
        uchar dat;
        uchar dat1,dat2;
        CE=0;
        SCL=0;
        CE=1;
        DS1302_wuchar(cmd);
        dat=DS1302_ruchar();
        dat1=dat/16;                         //十六进制转十进制
        dat2=dat%16;
        dat=dat1*10+dat2;
        io=0;
        CE=0;
        return dat;
}
void red_ds()
{
        write_DS1302(0x8e,0x00);
        cmd_ds[0]=red_DS1302(0x81);        
        cmd_ds[1]=red_DS1302(0x83);        
        cmd_ds[2]=red_DS1302(0x85);
        cmd_ds[3]=red_DS1302(0x87);         //
        cmd_ds[4]=red_DS1302(0x89);         //
        cmd_ds[5]=red_DS1302(0x8b);         //
        cmd_ds[6]=red_DS1302(0x8d);         //
        write_DS1302(0x8e,0x80);        
}


void DS_int()                                  //总线初始化
{
          DQ = 0;
          Delay500us();// 延时大于480us
          DQ = 1;
    Delay500us();
}

void write_DS(uchar cmd)                 //写命令到DS18B20
{
        uchar i;
        for(i=0;i<8;i++)
        {
                DQ=0;
                DQ=cmd&0x01;
                Delay100us();
                DQ=1;
                cmd>>=1;
        }
}

void Delay500us()                //@11.0592MHz
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 6;
        j = 93;
        do
        {
                while (--j);
        } while (--i);
}

void Delay100us()                //@11.0592MHz
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 2;
        j = 15;
        do
        {
                while (--j);
        } while (--i);
}

uchar red_DS_1820()                                                 //读取一个字节温度  
{
        uchar temp,i;
         for(i=0;i<8;i++)
         {
                 DQ=0;
                 temp>>=1;
                 DQ=1;
                 if(DQ)
                 {
                          temp=temp|0x80;
                 }
                 Delay100us();
         }
         return temp;
}

uchar red_temp()
{
        uchar low,high,temp;
        DS_int();
        write_DS(0xcc);
        write_DS(0x44);
               
           DS_int();
        write_DS(0xcc);
        write_DS(0xbe);
        low=red_DS_1820();
        high=red_DS_1820();

        temp=high<<4;
        temp=temp|(low>>4);
        return temp;
}



1602万年历 温度显示.rar

396.87 KB, 下载次数: 80, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:272080 发表于 2018-1-5 19:12 | 显示全部楼层
电路图在压缩文件中
回复

使用道具 举报

ID:272080 发表于 2018-1-5 19:21 | 显示全部楼层
还有那个温度值为85  是因为通电时就是85初始化的数值 这个具体原因我也不太清楚  希望有高人指点  通电1秒后 会由85跳变成正常温度  这样照片是一通电就拍的所以就是85了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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