找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4183|回复: 5
打印 上一主题 下一主题
收起左侧

一个基于stc89c52的万年历,LCD1602显示

[复制链接]
跳转到指定楼层
楼主
ID:388135 发表于 2018-8-20 14:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg52.h>
#include<INTRINS.H>
/************************************************************/
#define uchar unsigned char
#define uint unsigned int
#define TIME (0X10000-50000)
#define FLAG 0XEF //闹钟标志
/************************************************************/
//引脚连接图
sbit CLK=P1^2;
sbit RST=P1^4;
sbit DAT=P1^3;
sbit RS=P1^5;
sbit RW=P1^6;
sbit E=P1^7;
sbit P32=P3^2;
sbit KEY1 = P2^7;
sbit KEY2 = P2^6;
sbit KEY3 = P2^5;
sbit KEY4 = P2^4;
sbit ACC_7=ACC^7;
/************************************************************/

/*全局变量及常量定义*/

uchar i=20,j;
uchar DataBuf[16] = {};//日期
uchar TimeBuf[16] = {};//时间
uchar alarm[2],time[3];
uchar code Day[]={31,28,31,30,31,30,31,31,30,31,30,31};//12个月的最大日期(非闰年)

/*闰年月星期表*/

const uchar WeekTab[]=
        {
                (3 << 5) + 31,///1月
                (6 << 5) + 29,///2月
                (0 << 5) + 31,///3月
                (3 << 5) + 30,///4月
                (5 << 5) + 31,//5月
                (1 << 5) + 30,//6月
                (3 << 5) + 31,//7月
                (6 << 5) + 31,//8月
                (1 << 5) + 30,//9月
                (4 << 5) + 31,//10月
                (0 << 5) + 30,//11月
                (2 << 5) + 31 //12月
        };
       
/*音律表*/
       
uint code table1[]=
        {
                64260,64400,64524,64580,64684,
                64777,64820,64898,64968,65030,
          65058,65110,65157,65178,65217
        };
       
/*发声部分的延时时间*/
       
uchar code table2[]=
        {0x82,1,0x81,0xf4,0xd4,
                0xb4,0xa4,0x94,0xe2,1,
        0xe1,0xd4,0xb4,0xc4,0xb4,4,0
        };
       
/*闹钟中用的全局变量*/
       
uchar th1,tl1;
       
/************************************************************/
       
delay1ms(uchar time)//延时1ms函数
        {
                        uchar i,j;
                        for(i=0;i<time;i++)
                                {
                                                for(j=0;j<250;j++);
                                }
        }
/************************************************************/

Enable() //LCD控制函数
        {
                        RS=0;
                        RW=0;
                        E=0;
                        delay1ms(3);
                        E=1;
        }
/************************************************************/

LCD1602_WriteSChr(uchar i)//LCD1602写入字符函数
        {
                        P0=i;
                        RS=1;
                        RW=0;
                        E=0;
                        delay1ms(2);
                        E=1;
        }
/************************************************************/
       
/*LCD1602写入字符串函数
//入口函数
//uchar data *address : 写入数据首地址
//ucharm:写入字节数*/
       
LCD1602_WriteStr(uchar *address,uchar m)
        {
                        uchar i,j;
                        for(i=0;i<m;i++,address++)
                                {
                                        j=*address;
                                        LCD1602_WriteSChr(j);
                                }
        }
/************************************************************/

void LCDShow(void)//LCD显示
        {
                        P0=0XC; //显示器开、光标关
                        Enable();
                        //P0=0x80; //写入显示起始地址
                        //Enable();
                        //LCD1602_WriteStr(DataBuf,16); //写入日期显示缓存
                        P0=0xc1; //写入显示起始地址
                        Enable();
                        LCD1602_WriteStr(TimeBuf,16); //写入时间显示缓存
        }
/************************************************************/

void DS1302_Write(uchar temp)//DS1302写入子程序
                {
                                uchar i;
                                CLK=0; //将DS1320时钟脉冲拉低
                                _nop_();//延时一指令周期
                                RST=1; //RST置高电平
                                _nop_();//延时一指令周期
                                for(i=0;i<8;i++) //循环8次
                                        {
                                                        DAT=temp&0x01; //向DS1302写入一字节数据
                                                        _nop_(); //延时一指令周期
                                                        CLK=1; //拉高时钟脉冲
                                                        temp>>=1; //右移一位
                                                        CLK=0; //拉低时钟脉冲
                                        }
                }
/************************************************************/

uchar DS1302_Read()//DS1302读取子程序
        {
                        uchar i,j=0;
                        for(i=0;i<8;i++)//循环8次
                                {
                                                j>>=1; //右移一位
                                                _nop_(); //延时一指令周期
                                                CLK=0; //拉低时钟脉冲
                                                _nop_(); //延时一指令周期
                                                if(DAT) //判断接收该位数据是否为1
                                                j|=0x80;//该位置1
                                                _nop_(); //延时一指令周期
                                                CLK=1; //拉高时钟脉冲
                                }
                        return(j); //返回数值
        }
/************************************************************/

TimeStart()//部分显示数据初始化
        {
                        TimeBuf[0]=TimeBuf[8]=TimeBuf[9]=TimeBuf[10]=0x20; //不显示字符
                        TimeBuf[2]=TimeBuf[5]=':'; //时间分隔显示
                        DS1302_Write(0xc1);
                        alarm[0]=DS1302_Read();
                        RST=0;
                        DS1302_Write(0xc3);
                        alarm[1]=DS1302_Read();
                        RST=0;
                        DS1302_Write(0xc5);
                        DataBuf[0]=DS1302_Read();
                        RST=0;
        }
/************************************************************/

ReadTime()//读取时间
        {
                        uchar i,m,n;
                        for(m=0,i=0,n=0x85;i<7;i+=3,n-=2,m++) //连续读取时,分,秒
                                {
                                                DS1302_Write(n); //写入读取寄存器指令
                                                time[m]=DS1302_Read(); //读取数据
                                                RST=0; //将RST电平拉低,停止传输
                                                TimeBuf[i]=time[m]/16+0x30; //将两位数据的十位转为字符格式
                                                TimeBuf[i+1]=time[m]%16+0x30;//将两位数据的个位转为字符格式
                                }
        }
/************************************************************/

time0() interrupt 1 using 1//功能选择超时定时器
        {
                        i--;
                        if(i==0)
                                {
                                                if(j!=0)
                                                j--;
                                                i=20;
                                }
                        TH0=TIME/256,TL0=TIME%256;
        }
/************************************************************/

intime1() interrupt 3//产生闹铃音调
        {
                        TH1=th1,TL1=tl1;
                        P32=!P32;
        }
/************************************************************/

void AlarmShow(void)//闹钟显示
        {
                        uchar i,j,a,b,n;
                        ET1=1;
                        for(j=0;j<6;j++)
                                {
                                                i=0;
                                                while(1)
                                                        {
                                                                        a=table2[i];
                                                                        if(a==0)
                                                                        break;
                                                                        b=a&0xf;
                                                                        a>>=4;
                                                                        if(a==0)
                                                                                {
                                                                                                TR1=0;
                                                                                                goto D1;
                                                                                }
                                                                        a=((--a)<<1)/2;
                                                                        TH1=th1=table1[a]/256,TL1=tl1=table1[a]%256;
                                                                        TR1=1;
                                                                        D1: do
                                                                                {
                                                                                                b--;
                                                                                                for(n=0;n<3;n++)
                                                                                                        {
                                                                                                                        ReadTime();
                                                                                                                        LCDShow();
                                                                                                                        P2=0xff;
                                                                                                                        if(KEY4 == 1)
                                                                                                                                {
                                                                                                                                                delay1ms(100);
                                                                                                                                                if(KEY4 == 1)
                                                                                                                                                        {
                                                                                                                                                                        TR1=0;
                                                                                                                                                                        ET1=0;
                                                                                                                                                                        P32 = 1;
                                                                                                                                                                        return;
                                                                                                                                                        }
                                                                                                                        }
                                                                                                        }
                                                                                }
                                                                        while(b!=0);
                                                                        i++;
                                                        }
                                                TR1=0;
                                }
                        ET1=0;
        }
/************************************************************/

void SetTime(void)//设置日期、时间
        {
                        uchar i=0xc2,year,month,day,n;
                        TimeBuf[6]=TimeBuf[7]=0x30;
                        DataBuf[14]=DataBuf[15]=0x20;
                        LCDShow();
                        while(1)
                        {
                                        P0=0xe; //显示器开、光标开
                                        Enable();
                                        P0=i; //定光标
                                        Enable();
                                        P2=0xff;
                                        if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
                                                {
                                                                delay1ms(100); //延时0.1s去抖动
                                                                if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
                                                                        {
                                                                                        j=7;
                                                                                        if(KEY1 == 1)
                                                                                                {
                                                                                                                i+=3; //更改设置项目
                                                                                                                if(i==0x8e)
                                                                                                                i=0xc2;
                                                                                                                else if(i>0xc5)
                                                                                                                i=0xc2;
                                                                                                }
                                                                                        else if(KEY2 == 1)
                                                                                                {
                                                                                                                year=(DataBuf[4]&0xf)*10+(DataBuf[5]&0xf); //将字符格式的年份转换为数值格式
                                                                                                                month=(DataBuf[7]&0xf)*10+(DataBuf[8]&0xf); //将字符格式的月份转换为数值格式
                                                                                                                day=(DataBuf[10]&0xf)*10+(DataBuf[11]&0xf); //将字符格式的日数转换为数值格式
                                                                                                                if(i==0x85) //设置年份
                                                                                                                        {
                                                                                                                                        year++;
                                                                                                                                        if(year>99)
                                                                                                                                        year=0;
                                                                                                                                        if((year%4)!=0)
                                                                                                                                        if(month==2&&day==29)
                                                                                                                                        day=28;
                                                                                                                        }
                                                                                                                else if(i==0x88) //设置月份
                                                                                                                        {
                                                                                                                                        month++;
                                                                                                                                        if(month>12)
                                                                                                                                        month=1;
                                                                                                                                        if(day>Day[month-1])
                                                                                                                                                {
                                                                                                                                                                day=Day[month-1];
                                                                                                                                                                if(month==2&&(year%4)==0) //计算是否闰年
                                                                                                                                                                day=29;
                                                                                                                                                }
                                                                                                                        }
                                                                                                                else if(i==0x8b) //设置日期
                                                                                                                        {
                                                                                                                                        day++;
                                                                                                                                        if(day>Day[month-1])
                                                                                                                                                {
                                                                                                                                                                if(month==2&&(year%4)==0) //计算是否闰年
                                                                                                                                                                        {
                                                                                                                                                                                        if(day>29)
                                                                                                                                                                                        day=1;
                                                                                                                                                                        }
                                                                                                                                                                if(month!=2)
                                                                                                                                                                day=1;
                                                                                                                                                }
                                                                                                                        }
                                                                                                                else if(i==0xc2) //设置小时
                                                                                                                        {
                                                                                                                                        n=(TimeBuf[0]&0xf)*10+(TimeBuf[1]&0xf);
                                                                                                                                        n++;
                                                                                                                                        if(n>23)
                                                                                                                                        n=0;
                                                                                                                                        TimeBuf[0]=n/10+0x30;
                                                                                                                                        TimeBuf[1]=n%10+0x30;
                                                                                                                        }
                                                                                                                else //设置分钟
                                                                                                                        {
                                                                                                                                        n=(TimeBuf[3]&0xf)*10+(TimeBuf[4]&0xf);
                                                                                                                                        n++;
                                                                                                                                        if(n>59)
                                                                                                                                        n=0;
                                                                                                                                        TimeBuf[3]=n/10+0x30;
                                                                                                                                        TimeBuf[4]=n%10+0x30;
                                                                                                                        }
                                                                                                                DataBuf[4]=year/10+0x30; //将数值格式的日期转换为字符形式
                                                                                                                DataBuf[5]=year%10+0x30;
                                                                                                                DataBuf[7]=month/10+0x30;
                                                                                                                DataBuf[8]=month%10+0x30;
                                                                                                                DataBuf[10]=day/10+0x30;
                                                                                                                DataBuf[11]=day%10+0x30;
                                                                                                                LCDShow();
                                                                                                }
                                                                                        else if(KEY3 == 1) //按保存退出键后,向DS1302写入设置后的日期时间
                                                                                                {
                                                                                                                DS1302_Write(0x8c);
                                                                                                                DS1302_Write((DataBuf[4]&0xf)*16+(DataBuf[5]&0xf));
                                                                                                                RST=0;
                                                                                                                DS1302_Write(0x8a);
                                                                                                                DS1302_Write(SetWeek());
                                                                                                                RST=0;
                                                                                                                for(i=7,n=0x88;i<11;i+=3,n-=2)
                                                                                                                        {
                                                                                                                                        DS1302_Write(n);
                                                                                                                                        DS1302_Write((DataBuf[i]&0xf)*16+(DataBuf[i+1]&0xf));
                                                                                                                                        RST=0;
                                                                                                                        }
                                                                                                                for(i=0;i<7;i+=3,n-=2)
                                                                                                                        {
                                                                                                                                        DS1302_Write(n);
                                                                                                                                        DS1302_Write((TimeBuf[i]&0xf)*16+(TimeBuf[i+1]&0xf));
                                                                                                                                        RST=0;
                                                                                                                        }
                                                                                                                TR0=0;
                                                                                                                return;
                                                                                                }
                                                                                        else
                                                                                                {
                                                                                                                TR0=0;
                                                                                                                return;
                                                                                                }
                                                                        }
                                                }
                                        if(j==0)
                                                {
                                                                TR0=0;
                                                                return;
                                                }
                        }
        }
/************************************************************/

void SetAlarm(void)//设置闹钟
        {
                        uchar i,n;
                        for(i=1;i<16;i++)
                                {
                                                DataBuf[i]=0x20;
                                }
                        TimeBuf[0]=alarm[0]/16+0x30;
                        TimeBuf[1]=(alarm[0]&0xf)+0x30;
                        TimeBuf[3]=alarm[1]/16+0x30;
                        TimeBuf[4]=(alarm[1]&0xf)+0x30;
                        TimeBuf[6]=TimeBuf[7]=0x30;
                        LCDShow();
                        i=0xc2;
                        while(1)
                                        {
                                                        P0=0xe; //显示器开、光标开
                                                        Enable();
                                                        P0=i; //定光标
                                                        Enable();
                                                        P2=0xff;
                                                        if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
                                                                {
                                                                                delay1ms(100); //延时0.1s去抖动
                                                                                if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1)||(KEY4 == 1))
                                                                                        {
                                                                                                        j=7;
                                                                                                        if(KEY1 == 1)
                                                                                                                {
                                                                                                                                i+=3;
                                                                                                                                if(i>0xc5)
                                                                                                                                i=0xc2;
                                                                                                                }
                                                                                                        else if(KEY2 == 1)
                                                                                                                {
                                                                                                                                if(i==0xc2)
                                                                                                                                        {
                                                                                                                                                        n=(TimeBuf[0]&0xf)*10+(TimeBuf[1]&0xf);
                                                                                                                                                        n++;
                                                                                                                                                        if(n>23)
                                                                                                                                                        n=0;
                                                                                                                                                        TimeBuf[0]=n/10+0x30;
                                                                                                                                                        TimeBuf[1]=n%10+0x30;
                                                                                                                                                        }
                                                                                                                                else
                                                                                                                                        {
                                                                                                                                                        n=(TimeBuf[3]&0xf)*10+(TimeBuf[4]&0xf);
                                                                                                                                                        n++;
                                                                                                                                                        if(n>59)
                                                                                                                                                        n=0;
                                                                                                                                                        TimeBuf[3]=n/10+0x30;
                                                                                                                                                        TimeBuf[4]=n%10+0x30;
                                                                                                                                        }
                                                                                                                                LCDShow();
                                                                                                                }
                                                                                                        else if(KEY3 == 1)
                                                                                                                {
                                                                                                                                DS1302_Write(0xc0);
                                                                                                                                DS1302_Write((TimeBuf[0]&0xf)*16+(TimeBuf[1]&0xf));
                                                                                                                                RST=0;
                                                                                                                                DS1302_Write(0xc2);
                                                                                                                                DS1302_Write((TimeBuf[3]&0xf)*16+(TimeBuf[4]&0xf));
                                                                                                                                RST=0;
                                                                                                                                DataBuf[0]=FLAG;
                                                                                                                                DS1302_Write(0xc4);
                                                                                                                                DS1302_Write(DataBuf[0]);
                                                                                                                                RST=0;
                                                                                                                                TR0=0;
                                                                                                                                TimeStart();
                                                                                                                                return;
                                                                                                                }
                                                                                                        else
                                                                                                                {
                                                                                                                                TR0=0;
                                                                                                                                TimeStart();
                                                                                                                                return;
                                                                                                                }
                                                                                        }
                                                                }
                                                        if(j==0)
                                                        {
                                                                        TR0=0;
                                                                        TimeStart();
                                                                        return;
                                                        }
                                }
        }
/************************************************************/

void DS1302_Init(void)//DS1302初始化程序
        {
                        uchar i,n;
                        DS1302_Write(0x8c);
                        DS1302_Write((DataBuf[4]&0xf)*16+(DataBuf[5]&0xf));
                        RST=0;
                        DS1302_Write(0x8a);
                        DS1302_Write(SetWeek());
                        RST=0;
                        for(i=7,n=0x88;i<11;i+=3,n-=2)
                                {
                                                DS1302_Write(n);
                                                DS1302_Write((DataBuf[i]&0xf)*16+(DataBuf[i+1]&0xf));
                                                RST=0;
                                }
                        for(i=0;i<7;i+=3,n-=2)
                                {
                                                DS1302_Write(n);
                                                DS1302_Write((TimeBuf[i]&0xf)*16+(TimeBuf[i+1]&0xf));
                                                RST=0;
                                }
        }
/************************************************************/

void zhu_Init()
        {
                        IE=0x82;
                        TMOD=0x11;
                        DS1302_Write(0x8E); //禁止写保护
                        DS1302_Write(0);
                        RST=0;
                        P0=1; //清屏并光标复位
                        Enable();
                        P0=0x38; //设置显示模式:8位2行5x7点阵
                        Enable();
                        P0=6; //文字不动,光标自动右移
                        Enable();
                        DS1302_Init();
                        TimeStart();
        }
main()//主函数
        {
                  zhu_Init()
                        while(1)
                                {
                                                ReadTime(); //读取时间
                                                LCDShow(); //显示时间
                                                if(DataBuf[0]!=0x20)
                                                if(time[0]==alarm[0])
                                                if(time[1]==alarm[1])
                                                if(time[2]==0)
                                                AlarmShow();
                                                P2=0xff;
                                                if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1))
                                                        {
                                                                        delay1ms(100); //延时0.1s去抖动
                                                                        if((KEY1 == 1)||(KEY2 == 1)||(KEY3 == 1))
                                                                                {
                                                                                                j=7;
                                                                                                TH0=TIME/256,TL0=TIME%256;
                                                                                                TR0=1;
                                                                                                if(KEY1 == 1)
                                                                                                        {
                                                                                                                        SetTime();
                                                                                                        }
                                                                                                else if(KEY2 == 1)
                                                                                                        {
                                                                                                                        SetAlarm();
                                                                                                        }
                                                                                                else if(KEY3 == 1)
                                                                                                        {
                                                                                                                        TR0=0;
                                                                                                                        if(DataBuf[0]==FLAG)
                                                                                                                        DataBuf[0]=0x20;
                                                                                                                        else
                                                                                                                        DataBuf[0]=FLAG;
                                                                                                                        DS1302_Write(0xc4);
                                                                                                                        DS1302_Write(DataBuf[0]);
                                                                                                                        RST=0;
                                                                                                        }
                                                                                }
                                                        }
                                                delay1ms(100);
                                }
        }

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:431698 发表于 2019-1-1 20:12 | 只看该作者
为什么我keil3编译时  uchar DataBuf[16] = {};//日期 uchar TimeBuf[16] = {};//时间 报错的?
回复

使用道具 举报

板凳
ID:431698 发表于 2019-1-3 14:13 | 只看该作者
up助主   你能仿真么
修改过能生成hex文件进行protus仿真,显示屏没任何显示
回复

使用道具 举报

地板
ID:388135 发表于 2019-7-4 22:02 | 只看该作者
张二蛋 发表于 2019-1-1 20:12
为什么我keil3编译时  uchar DataBuf[16] = {};//日期 uchar TimeBuf[16] = {};//时间 报错的?

代码张粘贴上去的时候没有自动换行,你这是两行代码
uchar DataBuf[16] = {};//日期
uchar TimeBuf[16] = {};//时间
回复

使用道具 举报

5#
ID:585877 发表于 2019-7-28 11:02 | 只看该作者
jiasirer123 发表于 2019-7-4 22:02
代码张粘贴上去的时候没有自动换行,你这是两行代码
uchar DataBuf[16] = {};//日期
uchar TimeBuf[16 ...

楼主你好,我这个换行了但还是显示语法错误,怎么搞?
回复

使用道具 举报

6#
ID:388135 发表于 2019-7-31 21:02 | 只看该作者
chycc 发表于 2019-7-28 11:02
楼主你好,我这个换行了但还是显示语法错误,怎么搞?

你可以试试kell5啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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