精华内容
下载资源
问答
  • 51单片机LCD1602电子时钟

    千次阅读 2019-01-05 18:59:22
    51单片机LCD1602电子时钟 一.完成部分 基于51单片机用LCD1602实现时-分的显示 按键控制时-分的调整 能实现整时报时的功能(蜂鸣器响) 按键切换模式(模式一:时-分显示,模式二:60秒倒计时) 闹钟模式 ...

    51单片机LCD1602电子时钟

    一.完成部分

    基于51单片机用LCD1602实现时-分的显示
    按键控制时-分的调整
    能实现整时报时的功能(蜂鸣器响)
    按键切换模式(模式一:时-分显示,模式二:60秒倒计时)
    闹钟模式

    二.未完成部分

    电路板的焊接

    三.从中学到了什么

    1.新部分:首先我了解到了lcd1602的工作方式,其中:Vss接电源地,Vcc接5V电源,RS与WR为输入令与数据端口,D0~D7为输入数据口。以及可以选择地址进行输入。
    2.单片机部分:进一步了解了各种外部中断的的应用,如:在考虑四种模式和按键的关系上,考虑相互的优先级和需求,进一步规划
    3.同时要灵活应用已有的各种条件,如在整点报时上要求“不影响主程序的延时”首先计时器已经满足不影响主程序,并且每次运行都有一个比较固定的时间,只要设定好次数就可以做到

    四.未来计划

    1.争取了解多种解决问题的方法
    2.尝试自己读懂每个原件的使用说明,做到深入了解每个原件
    3.了解下载模块,在焊接上发挥
    4.深入了解c51单片机的性能(此次存在内存超出的情况)

    五.本次出现的问题

    1.未合理分配内存,导致内存超出
    解决方法:调整并在数组前加“code”
    2.循环的失误导致闪屏
    解决方法:调整初始化的位置
    3.变量数据溢出
    解决方法:考虑变量的内存大小,到达一定值后置初值

    六.对本次要求的详细解读

    1.首先,时钟显示模式需求的本质上还是数字的进位和显示的不断更新。再就是整点报时,这个可以通过位变化检测或者单纯的数字变化来确定蜂鸣器启动的时间点。
    2.时钟调整模式要求对时分进行键位调整,当然,之后的时钟显示也应该是调整后的,可以采取先改变再对调,或者先暂停再改变。
    3.再就是闹钟模式,闹钟模式调整上其实和调整模式差不多,关键就是设置一个值和时钟显示模式对应,让其能够再
    对应的时间点使蜂鸣器启动。
    4.倒计时其实关键并不在于显示和计时,因为这两点参考前面就行了,主要是可控性,也就是设置开关。

    七.本次对自己个人觉得要注意的点

    1.下面来满足这些需求,首先这里有四种模式,如果用两个外部中断肯定不够,况且0号口外度中断优先于计时器,
    为了不干扰计时器,所以我将四种模式都置于主程序里,将中断作为一种改变判断的工具,并且尽量简短,以免影响主
    程序的运行
    2. 显示里面需要注意的是每次最好要重新标志好初始的输入点,避免输入错位

    八.有关错误的查找

    有些错误不一定会显示,如内存溢出这种就不会显示,这些还需要自己去了解,通过上网搜索等方式寻找解决方法

    #include <reg51.h>
    #include <math.h>
    
    sbit RS=P2^4;
    sbit RW=P2^5;
    sbit E=P2^6;
    sbit BUZ=P1^0;
    sbit IN=P2^0;
    sbit DE=P2^1;
    sbit BA=P2^2;
    
    unsigned char code mod1[]=" workmod1:clock ";
    unsigned char code mod2[]=" workmod2:setup ";
    unsigned char code mod3[]=" workmod3:alarm ";
    unsigned char code mod4[]=" workmod4:timer ";
    unsigned int code timenumber[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};//0,1,2,3,4,5,6,7,8,9
    
    unsigned int o,p;
    unsigned char bs,i;
    unsigned int c1,c2,c3,c4,c5,c6,z,i3;//mod1
    unsigned int s;//mod2
    long int a;
    long int kk,k2;//mod4
    long int t,k,i1,i2;//timer
    
    void delay(int t)//50us
    {
    	unsigned int x;
        for(;t>0;t--)
        for(x=19;x>0;x--);
    }
    
    void writecom(unsigned char com)
    {
        E=0;
        RS=0;
        RW=0;
        P0=com;
        delay(10);
        E=1;
        delay(20);
        E=0;
    }
    
    void writedate(unsigned char dat)
    {
    	E=0;
    	RS=1;
    	RW=0;
    	P0=dat;
    	delay(10);
    	E=1;
    	delay(20);
    	E=0;
    }
    
    void innit()
    {
    	delay(30);
    	writecom(0x38);
        delay(10);
        writecom(0x38);
        delay(10);
        writecom(0x38);
        writecom(0x38);
        writecom(0x08);
        writecom(0x01);
        writecom(0x06);
        writecom(0x0c);
    }
    
    void workmod1()
    {
    innit();
    s=0;
    while(bs==0)
    {
    	writecom(0x80);
    	for(i=0;i<16;i++)
    	{
    		writedate(mod1[i]);
    	}
    	writecom(0x80+0x40);
    	if(s==0)writedate('O'),writedate('F'),writedate('F');
    	if(s==1)writedate('O'),writedate('N'),writedate(' ');
    	c1=i1%10,c2=i1/10,c3=i2%60%10,c4=i2%60/10,c5=i2/60%24%10,c6=i2/60%24/10;
    	writecom(0x80+0x45);
    	writedate(timenumber[c6]);writedate(timenumber[c5]);
    	writedate(':');
    	writedate(timenumber[c4]);writedate(timenumber[c3]);
    	writedate(':');
    	writedate(timenumber[c2]);writedate(timenumber[c1]);
    	i3=i2/60;
    	if(i3!=z)//strike
    	{
    		o=1;	
    		z=i3;
    	}
    	if(s==1&&a==i2)o=1;//alarm
        }
    }
    
    void workmod2()
    {
    innit();
    s=0;
    writecom(0x80);
    for(i=0;i<16;i++)
    {
    	writedate(mod2[i]);
    }
      while(bs==1)
    {
    	i1=0;
    	writecom(0x80+0x4a);
    	writedate(':');writedate('0');writedate('0');
    	writecom(0x80+0x40);
    	switch(s)
    		{
    			case 0:
    				{
    					writedate('M');
    					if(IN==0)
    						{
    							delay(500);
    							i2++;
    							delay(500);
    						}
    						else if(DE==0)
    							{
    								delay(500);
    								i2--;
    								delay(500);
    							}
    				}break;
    			case 1:
    				{
    					writedate('H');
    					if(IN==0)
    						{
    							delay(500);
    							i2=i2+60;
    							delay(500);
    						}
    						else if(DE==0)
    							{
    								delay(500);
    								i2=i2-60;
    								delay(500);
    							}
    				}break;
    		}
    		c1=i1%10,c2=i1/10,c3=i2%60%10,c4=i2%60/10,c5=i2/60%24%10,c6=i2/60%24/10;
    		writecom(0x80+0x45);
    		writedate(timenumber[c6]);writedate(timenumber[c5]);
    		writedate(':');
    		writedate(timenumber[c4]);writedate(timenumber[c3]);
    }
    }
    
    void workmod3()
    {
    innit();
    s=0;
    writecom(0x80);
    for(i=0;i<16;i++)
    {
    	writedate(mod3[i]);
    }
    while(bs==2)
    	{
    		if(a==1440)a=0;
    		writecom(0x80+0x40);
    		switch(s)
    			{
    			case 0:
    				{
    					writedate('M');
    					if(IN==0)
    						{
    							delay(500);
    							a++;
    							delay(500);
    						}
    						else if(DE==0)
    							{
    								delay(500);
    								a--;
    								delay(500);
    							}
    				}break;
    			case 1:
    				{
    					writedate('H');
    					if(IN==0)
    						{
    							delay(500);
    							a=a+60;
    							delay(500);
    						}
    						else if(DE==0)
    							{
    								delay(500);
    								a=a+60;
    								delay(500);
    							}
    				}break;
    			}
    			writecom(0x80+0x45);
    			c3=a%60%10,c4=a%60/10,c5=a/60%10,c6=a/60/10;
    			writedate(timenumber[c6]);writedate(timenumber[c5]);
    			writedate(':');
    			writedate(timenumber[c4]);writedate(timenumber[c3]);
    	}
    }
    
    void workmod4()
    {
    innit();
    kk=0;
    writecom(0x80);
    for(i=0;i<16;i++)
    {
    	writedate(mod4[i]);
    }
    while(bs==3)
    	{
    		k2=0;
    		if(s==0)
    			{
    				writecom(0x80+0x45);
    				writedate('R');
    				writedate('E');
    				writedate('A');
    				writedate('D');
    				writedate('Y');
    			}
    			else if(s==1)
    				{
    					writecom(0x80+0x45);
    					for(i=0;i<5;i++)
    					writedate(' ');
    				while(kk!=60&&bs==3&&s==1)
    					{
    						kk=k2/20;
    						writecom(0x80+0x47);
    						writedate(timenumber[(60-kk)/10]);writedate(timenumber[(60-kk)%10]);
    					}
    					if(kk==60)o=1,s=0,kk=0;
    				}
    	}
    }
    
    void main()
    {
    innit();
    TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;
    EA=1;EX0=1;EX1=1;
    IT0=1;IT1=1;
    ET0=1;TR0=1;
    k=0;bs=0;s=0;z=0;k2=0;i1=0;i2=0;kk=0;a=0;o=0;p=0;
    while(1)
    {
    	switch(bs)
    	{
    		case 0:workmod1();break;
    		case 1:workmod2();break;
    		case 2:workmod3();break;
    		case 3:workmod4();break;
    	}
    }
    }
    
    void int0 () interrupt 0//buttion:affirm
    {
    s++;s=s%2;
    BUZ=1;
    }
    
    void timer0 () interrupt 1
    {
    for(t=0;t<20;t++)
    {
    	TH0=(65536-50000)/256;
    	TL0=(65536-50000)%256;
    }
    k++;
    if(k==20) i1++,k=0;
    if(i1==60) i2++,i1=0;
    if(i2==1440) i2=0;
    k2++;//only mod4
    if(o)BUZ=0,p++;
    if(p==40)BUZ=1,o=0,p=0;
    }
    
    void int2 () interrupt 2//buttion:set up
    {
    kk=0;BUZ=1;
    bs++;
    bs=bs%4;
    }
    
    展开全文
  • 之前写了51单片机的LCD1602的程序,现在画了电路图,焊接了电路板,做出了基于51单片机LCD1602电子时钟的实物。 注意事项: 焊接过程中,注意提前布局电路。 对应好端口(避免接线错误),我由于将LCD的正负极接反...

    之前写了51单片机的LCD1602的程序,现在画了电路图,焊接了电路板,做出了基于51单片机LCD1602电子时钟的实物。
    注意事项:
    焊接过程中,注意提前布局电路。
    对应好端口(避免接线错误),我由于将LCD的正负极接反差点烧了一块LCD
    成果展示:
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • 基于51单片机LCD1602显示时钟(温度报警),程序,仿真图,元器件表
  • 基于51单片机LCD1602电子时钟

    万次阅读 多人点赞 2018-12-13 22:50:03
    本次设计的数字电子时钟采用了STC89C52芯片进行控制,使用DS1302时钟芯片产生时钟数据,通过LCD1602液晶显示屏进行刷新显示。同时,使用4*4矩阵键盘,可以进行日期和时间的调整,且操作简单,计时误差小,显示亮度高...

    摘要:
    51系列单片机是各单片机中最为典型和最有代表性的一种。由RAM ,ROM,CPU构成,定时,计数和多种接口于一体的微控制器。本次设计的数字电子时钟采用了STC89C52芯片进行控制,使用DS1302时钟芯片产生时钟数据,通过LCD1602液晶显示屏进行刷新显示。同时,使用4*4矩阵键盘,可以进行日期和时间的调整,且操作简单,计时误差小,显示亮度高,具有良好的实用价值。

    一.电子时钟的功能及原理
    1.本设计采用时钟芯片,通过单片机对其输出的时间数据进行年、月、日、时、分、秒的解码,并将解码后的数据送到显示屏进行显示。单片机使用定时器T0,每定时2ms后,单片机便产生一个的计时溢出中断,在中断服务函数对矩阵按键进行动态扫描,这样既避免了按键消抖,又减轻了CPU的工作载荷。
    2.此外,为了提高电子时钟的实用性,本课题还添加了一个矩阵键盘和蜂鸣器,通过矩阵键盘来调整时间,16个按键分别为‘0~9数字键’、‘设置键’、‘esc键’、‘增加键’、‘减少键’、‘向左键’、‘向右键’。 单片机确定有按键按下,在蜂鸣器控制脚产生一个高电平,使蜂鸣器发出“嘀”的一声,以此来说明按下的动作被执行了。
    3.同时电子时钟具有报时的功能,当时间到了整点,比如到了10点钟时,蜂鸣器会连续发出10个响声,表示现在是10点正;当时间到了某点30分时,蜂鸣器会响一声,表示现在是某时半点。

    二.电子时钟的硬件设计
    1.总体硬件框图
    在这里插入图片描述
    2 电子时钟硬件系统主要模块功能简要介绍
    (1)单片机:本次设计采用AT89C52芯片,低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。256字节RAM, 32 位I/O 口线,与工业80C51 产品指令和引脚完全兼容。价格较低,能满足本次设计的要求
    在这里插入图片描述
    (2) 电源和复位模块:AT89C52需5V电压,所以可以采用USB接口的5V电源对其供电,复位电路可采用上电复位、按键电平复位、按键脉冲复位3种,本次采用按键电平复位。
    (3)显示模块:该模块由LCD1602液晶显示屏组成,共有16个引脚,其中有11个需与单片机相接,工作控制引脚分别接于单片机的P2.4-P2.6脚,数据引脚接于单片机的P0.0-P0.7口上,使用可调电阻实现对显示屏文字清析度的调节。
    在这里插入图片描述
    (4)矩阵键盘模块:键盘由16个按键组成,行脚分别接在单片机的P1.0-P1.3口,列脚分别接在单片机P1.4-P1.7口上。
    在这里插入图片描述
    (5)DS1302时钟模块:为了保证同步工作方式的思想,单片机必须有时钟信号,以使其系统在时钟信号的控制下按时序协调工作。
    在这里插入图片描述
    (6)总体实物图
    在这里插入图片描述
    3. 电子时钟元器件清单
    在这里插入图片描述
    三.电子时钟软件系统的设计

    1 电子时钟软件系统主要模块功能简要介绍
    (1) 主程序:主程序的主要功能是进行定时器/计数器,显示缓冲区的初始化,显示,以及判断是否有功能键按下,判断按下的键并调相应的键功能程序。
    (2) 键功能程序:键功能程序的主要功能是执行对应的功能,主要对16个按键进行编码,当单片机得到按下的键的编码,单片机便会跳转到相应的子程序执行相应的功能。
    (3) 中断服务程序:中断服务程序的主要功能是进行计时操作和按键扫描,程序开始进行按键检测,然后判断计数溢出是否满了100次,若不满100次则表明没有到达最小的刷新时间,则中断结束;若满100次表明已到达了刷新时间,则将刷新时间标志位置1,进行时间的刷新。

    2 电子时钟软件系统程序流程框图
    在这里插入图片描述
    3.主程序代码

    void main()
    {
        InitLCD1602(); //初始化 lcd1602
        InitDS1302(); //初始化 DS1302
        ConfgiTimer0(2); //初始化定时器,并定时 2ms
        Delay_nms(10);
        buz = 0;
        LcdShowStr(0,0,"Date:20 - - ");
        LcdShowStr(0,1,"Time: : : ");
        while(1)
        {
            KeyDriver();//检测按键动作
            if (flag200ms == 1 && (setTimeIndex == 0)) //每 200ms 且 setTimeIndex==0 处于非设定时间状态时刷新一次时间显示
            {
                flag200ms = 0;
                GetTimeFromDS1302(&timeBuf); //从 DS1302 中获取时间到 timeBuf 结构体指针变量的成员中
                if(timeBuf.sec != psec) //当前秒值和上一次的秒值不相等
                {
                    RefreshLcdShowTime();//刷新时间显示
                    psec = timeBuf.sec;//备份当前的秒值(秒寄存器值)
                    On_Timr_Alarm();
                }
            }
        }
    }
    

    源码下载:关注公众号,首页回复“电子时钟”获取电子时钟的源码工程
    在这里插入图片描述

    展开全文
  • 基于单片机LCD1602电子时钟程序和仿真
  • 当时看书看到lcd那章,就想利用定时器做一个电子时钟,当时也不知道有时钟模块的,以为都是定时器定时产生的时间,也是一个main文件从头到尾的版本,注释倒不少,不要说什么代码优化,想到什么就写什么,业余的就是...

    当时看书看到lcd那章,就想利用定时器做一个电子时钟,当时也不知道有时钟模块的,以为都是定时器定时产生的时间,也是一个main文件从头到尾的版本,注释倒不少,不要说什么模块化编程和代码优化,想到什么就写什么,业余的就是可以随便写,所以思路肯定比别人的清楚明白,随便谁都看得懂,当然后来就把自己写的例程都自己做了个c51的库,傻瓜型的库,以后有空想到就慢慢记录下来

    #include <reg52.h>
    #include <string.h>
    
    #define uchar unsigned char
    #define uint unsigned int
    
    //sbit u1la=P2^6;        		//U1锁存器  为1则打开锁存器 为0则关闭锁存器
    //sbit u2la=P2^7;     	 		//U2锁存器
    sbit lcdrs=P2^5;          //lcd数据命令选择端  rs为L(ledrs=0)则写命令 H(ledrs=1)则写数据
    sbit lcdrw=P2^6;
    sbit lcden=P2^7;          //lcd使能   lcden=1 则写入 
    
    //sbit key1=P3^0;         //矩阵键盘中第4列中从上到下  第一个按键轮流3种状态 按一下小时闪烁 分钟闪烁 不闪烁则继续加秒数
    //sbit key2=P3^1;          //         								第二个按键增加当前选中的秒 小时或者 分钟 等
    //sbit key3=P3^2;           //         								第三个按键减少当前选中的数字
    //sbit rd=P3^7;							//置低电平后分离出第4列四个独立按键
    sbit key1=P3^6;      //独立 按键  由于P34 P35端口已经被lcd占用  所以只有两个独立按键可以用
    sbit key2=P3^7;
    sbit sbeep=P2^3;        //蜂鸣器
    
    uchar code table1[]="   2019-08-05";
    uchar code table2[]="    00:00:00";
    int code month[12]={31,28,31,30,31,30,31,31,30,31,30,31};   //每个月天数  第二月有两种情况 运用时闰年判断下后处理
    char code *week[7]={"SUN","MON","TUE","WED","THU","FRI","SAT"};       //每周一天英文缩写  元素从0 星期天开始
    void delayms(uint ms) ; 												 //延迟子函数
    void display(uchar *table,uchar line);           //显示字符串子函数  table为字符串,最大16字符  line为显示的行数,1为第一行 2为第二行  函数目前不容错
    void write_com(uchar cmd);                       //lcd写命令子函数  一次写入一个命令 例如0x80
    void write_data1(uchar);										 //lcd写数据子函数 一次写入一个字符
    void write_data(uchar ,uchar , uchar );        //写数据 第几行 第几个开始  数据  第三个参数必须是1-2位数
    void init();                                     //初始化函数
    void day_add();																	//增加一天后处理函数
    void calweek();																		//计算某一天星期几并刷新显示
    void mybeep();																		//蜂鸣器
    void keyscan();																	//检测 处理按键
    void settime_add();                                  //按键修改时间后刷新时间
    void settime_minus();																//修改时间
    void cursor_blink();                                  //判断blink状态 更新光标闪烁
    uchar num0;																						//num0为定时器0中断次数 
    char months,weeks, days, hours,minutes,seconds,comparemonth,m;    //月 周几 日 小时 分钟 秒 每月天数 m用来公式计算周几
    char blink;                                      //第一个设置按键状态 循环7中状态 秒闪烁  分钟闪烁 小时闪烁 月 日 年 不闪烁
    unsigned int years;                                      //年份超过255数字
                                                                                                                                            
    void main()
    {
    	init();
    	display(table1,1);
    	display(table2,2);
    	while(1)
    	{
    		keyscan();
    		delayms(5);
    		cursor_blink();
    	}
    }
    
    void init()
    {
    		TMOD = 0x01;								//定时器1工作方式1 定时器0工作方式1   定时器1在高四位
    		TH0=(65536-45872)/256;			//定时器0  16位计数器高8位初始计数
    		TL0=(65536-45872)%256;			//定时器0  16位计数器低8位初始计数
    		EA=1;												//中端使能  中端总开关
    		ET0=1;											//定时器0 中断允许位 
    		TR0=1;											//初始中断开始启动				
    //		rd=0;										//初始化rd******此处用来分离矩阵键盘独立按键第四列*******
    //		u1la=0;             //关闭U1 
    //		u2la=0;             //关闭U2
    		lcden=0;            //lcd关闭写入
    		lcdrw=0;
    		years=2019;         //初始化显示  2019/08/05 程序开始测试的日子
    		months=8;
    		days=5;
    		weeks=1;
    		blink=0;
    		
    		write_com(0x38);    //设置16x2显示 5x7点阵 8位数据接口
    		write_com(0x0c);		//开显示 不显示光标
    		write_com(0x06);		//写一个字符后地址指针加1
    		write_com(0x01);		//显示清零 数据指针清零  要写入数据先写入命令 write_cmd(0x80) 第一行第一个字符地址  0x80+0x40 第二行开头地址写入
    		write_com(0x80+0x40+6);
    		write_data1(':');
    		write_com(0x80+0x40+9);
    		write_data1(':');	
    		calweek();
    }
    void T0_time() interrupt 1        //*******定时器0的中断序号是1*********
    {    
    		TH0=(65536-45872)/256;			//进入中断再次初始化计数 TRO=1 所以计数会不停 下次中断仍然是50ms后
    		TL0=(65536-45872)%256;			//16位计数器低8位初始计数
    		num0++;									
    		if(num0 == 20)								//中断20次后 50ms20次为1s
    		{	
    			num0=0;
    			seconds++;
    			if(seconds==60)                //60秒加1分钟
    			{
    				seconds=0;
    				minutes++;
    				if(minutes==60)              //60分钟加1小时
    				{
    					minutes=0;
    					hours++;
    					if(hours==24)            //超过24小时增加一天
    					{
    						hours=0;						
    						day_add();
    					}
    					write_data(2,4,hours);
    				}
    				write_data(2,7,minutes);
    			}
    			write_data(2,10,seconds);
    		}
    }
    void keyscan()
    {
    	if(key1==0)            //第一个按键轮流7种状态 按一下秒闪烁  分钟闪烁 小时闪烁 月 日 年 不闪烁则继续加秒数  0 1 2 3 4 5
    	{
    		delayms(10);
    		if(key1==0)
    		{
    			mybeep();
    			blink++;         //循环blink状态
    			if(blink ==7) 
    			{
    				blink=0;          
    				write_com(0x0c);     //取消光标闪烁
    				TR0=1;								//继续计时
    			}
    			if(blink != 0)
    			{
    				TR0=0;        //暂停计时
    //				cursor_blink();
    			}
    		}
    		while(!key1);     //等待按键弹起
    	}
    	if(key2==0)             //第二个按键在闪烁时增加 小时、分钟等数字  各数字不联动
    	{
    		delayms(10);
    		if(key2==0)           //确认按下按键
    		{
    			mybeep();
    			switch (blink)
    					{
    						case 1: seconds++;					//秒
    										settime_add();										
    										break;
    						case 2: minutes++;        			 //分
    										settime_add();
    										break;
    						case 3: hours++;               			//时
    										settime_add();
    										break;
    						case 4: days++;          					 //天
    										settime_add();
    										break;
    						case 5: months++;        						 //月
    										settime_add();
    										break;				
    						case 6: years++;       							 //年
    										settime_add();
    										break;				
    						default :      ;      //光标不闪烁的时候按增加键  不处理												
    					}
    		}
    		while(!key2);            //按键弹起后继续
    	}
    //	if(key3==0)
    //	{
    //		delayms(10);
    //		if(key3==0)             //按键3  减小数字
    //		{
    //						mybeep();
    //			switch (blink)
    //					{
    //						case 1: seconds--;						//秒		
    //										settime_minus();
    //										break;
    //						case 2: minutes--;        		//分
    //										settime_minus();
    //										break;
    //						case 3: hours--;               //时
    //										settime_minus();
    //										break;
    //						case 4: days--;          					 //天
    //										settime_minus();
    //										break;
    //						case 5: months--;        						 //月
    //										settime_minus();
    //										break;				
    //						case 6: years--;       							 //年
    //										settime_minus();
    //										break;				
    //						default :      ;      //光标不闪烁的时候按减小键  不处理												
    //					}
    //		}
    //		while(!key3);
    //	}
    }
    
    void settime_add()         //增大时间时,不进位 只处理溢出情况
    {
    		if(seconds==60) 	seconds=0;
    		if(minutes==60)   minutes=0;
    		if(hours==24) 		hours=0;	
    		comparemonth=month[months-1];  //comparemonth除了2月不确定,其他每月天数都是数组中的数字
    		if(months==2)    	{  	if(years%4==0)	comparemonth=29;	}	 //闰年二月29天
    		if(days>comparemonth)  days=1;	
    		if(months>12)  		months=1;	
    		if(years%100==0)	write_data(1,3,years/100);  //年份后两位进位就增加年份前两位更新
    		write_data(1,5,years%100);       //年份后两位没进位,只要更新后两位
    		write_data(2,4,hours);
    		write_data(2,7,minutes);
    		write_data(2,10,seconds);	
    		write_data(1,8,months);     //更新月份
    		write_data(1,11,days);             //更新天数
    		calweek();                       //计算周几并更新		
    }
    void settime_minus()         //减小时间时,不退位 只处理溢出情况
    {
    		if(seconds<0) 		seconds=59;
    		if(minutes<0)   	minutes=59;
    		if(hours<0) 			hours=23;	
    		comparemonth=month[months-1];  //comparemonth除了2月不确定,其他每月天数都是数组中的数字
    		if(months==2)    	{  	if(years%4==0)	comparemonth=29;	}	 //闰年二月29天
    		if(days==0)  			days=comparemonth;	
    		if(months==0) 		months=12;	
    		if(years%100==0)	write_data(1,3,years/100);  //年份后两位进位就增加年份前两位更新
    		write_data(1,5,years%100);       //年份后两位没进位,只要更新后两位
    		write_data(2,4,hours);
    		write_data(2,7,minutes);
    		write_data(2,10,seconds);	
    		write_data(1,8,months);     //更新月份
    		write_data(1,11,days);             //更新天数
    		calweek();                       //计算周几并更新		
    }
    void calweek()
    {
    	char numi; //显示字符串for 循环用
    	if(months==1 || months==2)      //如果是1 2月份,要看成前一年的13 14月
    	{
    		m=months+12;
    		years--;
    	}
    	else m=months;
    	weeks=(days+2*m+3*(m+1)/5+years+years/4-years/100+years/400+1)%7;       //基姆拉尔森公式算星期几
    	write_com(0x80+0x40+13);
    	for(numi=0;numi<3;numi++)              //for循环写入字符串每一个字符
    		{			
    			write_data1(week[weeks][numi]);
    			delayms(5);
    		}
    }
    void cursor_blink()
    {
    		switch (blink)
    		{
    			case 1: write_com(0x80+0x40+11);              //秒 光标定位到秒
    							write_com(0x0f);												//光标开始闪烁
    							break;
    			case 2: write_com(0x80+0x40+8); 				 				//分
    							write_com(0x0f);	
    							break;
    			case 3: write_com(0x80+0x40+5);     						//时
    							write_com(0x0f);	
    							break;
    			case 4: write_com(0x80+12);          					 //天
    							write_com(0x0f);	
    							break;
    			case 5: write_com(0x80+9);        						 //月
    							write_com(0x0f);	
    							break;				
    			case 6: write_com(0x80+6);     							 //年
    							write_com(0x0f);	
    							break;				
    			default :        ;         //光标不闪烁																					
    		}
    }
    
    void day_add()
    {
    	comparemonth=month[months-1];
    	if(months==2)           //闰年二月29天
    	{
    		if(years%4==0)
    			comparemonth=29;
    	}	
    	days++;
    	if(days>comparemonth)        //days超过当月天数 回归1日 月份加一
    	{
    		days=1;
    		months++;
    		if(months>12)								//加一年
    		{
    			months=1;
    			years++;
    			if(years%100==0)								//加一个世纪
    			{
    				write_data(1,3,years/100);      //年份后两位近位就前两位更新
    			}
    			write_data(1,5,years%100);       //年份后两位没进位,只要更新后两位
    		}
    		write_data(1,8,months);     //更新月份
    	}
    	write_data(1,11,days);             //更新天数
    	calweek();                       //计算周几
    }
    
    void write_com(uchar cmd)
    {
    	lcdrs=0;									//lcd数据命令选择端  rs为L(ledrs=0)则写命令 H(ledrs=1)则写数据
    	P0=cmd;                   //P0数据与lcd数据口相连
    	delayms(1);
    	lcden=1;                  //写入命令
    	delayms(1); 
    	lcden=0;									//关闭写入
    }
    void write_data1(uchar data2)
    {
    	lcdrs=1;									//lcd数据命令选择端  rs为L(ledrs=0)则写命令 H(ledrs=1)则写数据
    	P0=data2;                 
    	delayms(1);
    	lcden=1;
    	delayms(1);
    	lcden=0;
    }
    void write_data(uchar line,uchar add, uchar data1)   //写数据 第几行 第几个开始  数据  data1必须是1-2位数  此程序中不会溢出
    {
    	uchar address,shi,ge;
    	shi=data1/10;
    	ge=data1%10;
    	address=0x80+(line-1)*0x40+add;         //根据行数和add参数定位写数据位置
    	write_com(address);						
    	write_data1(0x30+shi); 		输出十位字符****写完后光标自动下移一个,无需再定位地址****
      write_data1(0x30+ge);     输出个位字符
    }
    void display(uchar *table,uchar line)       //显示字符串子函数  table为字符串,最大16字符  line为显示的行数,1为第一行 2为第二行  函数目前容错
    {
    	uchar strlen1;
    	uchar num;
    	strlen1=strlen(table);                    //strlen函数得到当前字符串长度
    	if(strlen1>16) strlen1=16;								//超出16字符后只取前16字符
    	if(line==1)      													//第一行写入地址0x80
    		write_com(0x80);
    	else if(line==2)                                  //第二行写入地址0xc0
    		write_com(0x80+0x40);
    	if(line==1 || line==2)                    //line参数1或者2才操作,不然不处理
    	{
    		for(num=0;num<strlen1;num++)              //for循环写入字符串每一个字符
    			{
    				write_data1(table[num]);
    				delayms(1);
    			}
    	}
    	else                                       //行数溢出 bibi两声
    	{
    		mybeep();
    		mybeep();
    	}
    }
    void delayms(uint ms)         							//延迟毫秒函数 参数为需要延迟的毫秒数
    {
    	uint i,j;
    	for(i=ms;i>0;i--)
    		for(j=110;j>0;j--);
    }
    void mybeep()                            //蜂鸣器发声
    {
    	sbeep=0;
    	delayms(100);
    	sbeep=1;
    }
    
    展开全文
  • 基于51单片机LCD1602的简易数字

    千次阅读 2020-10-10 11:11:20
    LCD1602简易数字 选用芯片:AT89S52 此函数功能为:用定时器的中断方式实现数字功能,然后在LCD1602上显示,能校时和校分,具有整点报时功能(四低一高)。 博主才疏学浅,可能会出现设计不足和错误,欢迎大家...
  • 基于51单片机LCD1602电子时钟显示

    千次阅读 2018-11-13 20:40:56
    完成部分:基于51单片机控制的LCD1602实现分-秒计时的程序书写;实现按键分别控制分和秒的调整;实现满一分钟的报时功能;完成PCB板的绘制与焊接。 未完成部分:发挥部分(按键切换模式)。 二、从中学到了什么 1...
  • 51单片机项目设计:时钟万年历、闹钟(lcd1602显示)

    万次阅读 多人点赞 2020-05-13 17:17:52
    项目功能: 1、能够显示年、月、日、星期、时间、实时温度。 2、能够按键实现修改当前时间与日期。 3、能够同时设定3个闹钟,在指定时间蜂鸣器发出滴滴声响。 4、掉电走时,掉电闹钟...STC89C52RC:51单片机系列,32
  • 51单片机 普中V2 数字时钟 电子时钟 万年历 DS1302 LCD1602 AT24C0251
  • 目录原理图LCD1602 原理图 新人求赞 ???? 谢谢大家 主控芯片原理图 LCD接口电路原理图 LCD1602 模块化代码在后面 其实1602说白了就是我们向1602传送数据,1602在光标所在的位置把我们的数据全部写出来即可。所以...
  • 51单片机时钟电路(LCD1602显示)完整源码与仿真,适用于51单片机初学者
  • 电子数字》这篇是基于定时器,所以首先就有了定时器的应用,本想着在数码管上显示,但是既然学了LCD1602,刚好拿来用用。还有对独立键盘的使用。(除完整代码外,其余代码都是拼接在一起的,单独使用要注意) ...
  • lcd1602显示计时,矩阵按键切换功能,按键功能有计时与暂停,菜单切换,记录,查记录,清零等。最大计时99.59.99分,每分钟误差不超过0.05秒,可自定义记录时间的组数。矩阵按键采用定时器消抖,大大减少误差。
  • 基于51单片机1602LCD时钟 最近做了个51单片机时钟、具有设置时间、闹钟等功能 程序分为3个模块。程序比较简单、由于用于学习交流用没有做掉电运行功能。 供大家学习。 isis仿真图 这是设置时间时的效果 这是...
  • 51单片机+ds1302+lcd1602简易电子时钟(带闹钟功能) AT89C52、LCD1602、DS1302、speaker、 Proteus仿真 实例代码 #include<reg52.H> #include<INTRINS.H> #define TIME (0X10000-50000) #define ...
  • 功能实现:显示年月日时秒分以及星期,整点报时、闹钟、秒表以及灭屏不显示,硬件电路采用Protues搭建,程序用Keil编写。
  • 1、LCD显示区域划分 2、按键分布 3、按键操作逻辑 (1)、首先,这是正常的时钟模式,右下角显示TIME (2)、长按设置键可以选择模式,左下角模式调整区clock,按key1 OK键进入时钟调整模式 ...
  • 液晶屏为JM12864或FYD12864(带字库),我用这两种型号的屏没问题, 4行*8列汉字=32 串行通信 接/口P1.5--P1.7,可根据你的电路修改相应的接口。
  • C51单片机利用LCD1602设计时钟

    千次阅读 2018-11-13 21:11:57
    -设计思路 -知识积累 -编写代码 -总结 1. 设计思路 第一行显示年月日,第二行显示时间 ...上电之后计时开始,K2控制分秒设置,按第一次计时停止秒针闪烁...(1)LCD1602接口信号说明 VSS:电源地信号引脚; VDD...
  • 基于C51单片机LCD电子时钟设计

    千次阅读 多人点赞 2020-07-05 07:50:37
    1 LCD电子时钟设计 1、 制作一个基于LCD显示的电子钟,在LCD显示器上显示当前时间。 2、 使用字符型LCD显示器显示时间。 3、 显示格式:“时时:分分:秒秒”。 4、 用4个功能键操作来设置当前时间。功能键K1~K4功能...
  • 基于51单片机LCD1602实现分秒的计时;按键控制分秒的调整(两个按键分别控制分和秒的增加);能实现整时报时的功能(蜂鸣器响);了解下载模块、下载原理;基本上了解并使用DXP绘制PCB板;
  • 51电子闹钟实现了:界面LCD1602显示器,显示年、月、日、星期、时、分、秒、温度,具有闹钟设定,铃声变换设定,时间设定,事件设定,掉电不丢失,12/24进制切换功能。 资源含有实验报告及源码(含注释及使用方法)
  • 本文和大家分享一个LCD1602屏幕单片机电子时钟程序,并带有详细注释,感兴趣的朋友可以看看。
  • C51单片机_LCD电子时钟

    千次阅读 2019-05-31 14:44:52
    C51单片机_LCD电子时钟 可以手动设置初始时间和修改时间,可以设置闹钟时间,响应时蜂鸣器会响,步进电机会转动 #include <intrins.h> #include <reg52.h> //包含头文件,一般情况不需要改动,头文件...
  • 51单片机DS1302时钟LCD1602显示(可以按键设置时钟

    万次阅读 多人点赞 2019-02-08 23:02:07
    DS1302实时时钟具有能计算2100年之前的秒、分、时、日、日期、星期、月、年的能力,还有闰年调整的能力。 图1:DS1302引脚示意图 其中: X1、X2:32.768KHz晶振接入引脚。 GND:地。 :复位引脚,低电平有效,操作时...
  • 系统以AT89S52单片机为控制器,以串行时钟日历芯片DS1302记录日历和时间,它可以对年、月、日、时、分、秒进行计时,还具有闰年补偿等多种功能。温度采集选用DS18B20芯片,万年历采用直观的数字显示,数据显示采用...
  • 申明:以前上传过名字相似的资源,上传时不慎点错文件,现在又无法删除,只好重新上传一份。对于已经下载了错误资源的同志表示歉意! 附有proteus仿真文件,程序是根据仿真电路设计的 实现功能: ...
  • DS1302时钟模块LCD1602显示DS1302时钟模块相关介绍基本介绍时序图 DS1302时钟模块相关介绍 基本介绍 DS1302 可慢速充电实时时钟芯片包含实时时钟/日历和 31 字节的非易失性静态 RAM。它经过一个简 单的串行接口与微...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,349
精华内容 539
关键字:

51单片机lcd1602电子时钟