51单片机+LCD12864的万年历Proteus仿真

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51单片机+LCD12864的万年历Proteus仿真相关的知识,希望对你有一定的参考价值。

51单片机+LCD12864的万年历Proteus仿真


按键说明:递增按键的范围是根据设置的属性变化而变化,如果是年就是0-99,超出范围归0,如果是月份就是0-12超出范围归0,如果是日期就是0-31,超出归0,递减有所不同只能做到0-9之间递减。

实例代码

  • main.c
#include <reg51.h>
#include "DS18B20.h"
#include "DS1302.h"
#include "LCD12864.h"

char a;
sbit KEY1=P3^4;
sbit KEY2=P3^5;
sbit KEY3=P3^6;
sbit KEY4=P3^7;
/***按键触发标志位***/
bit KeyTrg1=0;
bit KeyCont1=0;

bit KeyTrg2=0;
bit KeyCont2=0;

bit KeyTrg3=0;
bit KeyCont3=0;

bit KeyTrg4=0;
bit KeyCont4=0;
/***按键触发标志位***/
/***按键模式选择***/
#define KEY_MODE 0x01    // 模式按键
#define KEY_PLUS 0x02     // 加
uint cnt_plus=0;
bit  flag=1; //进入/退出设置标志
uchar  choose=0x01; //切换标志

/***按键触发实现函数***/
void KeyRead1(void)
{
    unsigned char ReadData = KEY1^0x01;   // 
    KeyTrg1 = ReadData & (ReadData ^ KeyCont1);   // 触发
    KeyTrg1 = ReadData;                     //长按
    }
void KeyRead2(void)
{
    unsigned char ReadData = KEY2^0x01;   // 
    KeyTrg2 = ReadData & (ReadData ^ KeyCont2);   // 触发
    KeyTrg2 = ReadData;                     //长按
    }
void KeyRead3(void)
{
    unsigned char ReadData = KEY3^0x01;   // 
    KeyTrg3 = ReadData & (ReadData ^ KeyCont3);   // 触发
    KeyTrg3 = ReadData;                     //长按
    }
void KeyRead4(void)
{
    unsigned char ReadData = KEY4^0x01;   // 
    KeyTrg4 = ReadData & (ReadData ^ KeyCont4);   // 触发
    KeyTrg4 = ReadData;                     //长按
    }
/***按键触发实现函数***/
void delay10(void) //延时10ms
{
    unsigned char i,j;
    for(i=0; i<255; i++)
        for(j=0; j<200; j++);
}
void delay5ms(void)   //误差 0us
{
    unsigned char a,b;
    for(b=19; b>0; b--)
        for(a=130; a>0; a--);
}

//设置时ds1302寄存器值循环 如秒寄存器59时加一变为00
unsigned char conver(unsigned char a,unsigned char b,unsigned char c)
{

    if((a&0x0f)==0x0a) a=a+6;
    if(a==b)  a=c;
    return a;
}

void digplay() {

    //时间
    ShowNumber16_32(2,0,TIME[2]>>4&0x03); //时 十位
    ShowNumber16_32(2,16, TIME[2]&0x0f);//时  个位
    ShowNumber16_32(2,48,TIME[1]>>4&0x07);//分  十位
    ShowNumber16_32(2,64, TIME[1]&0x0f);//分  个位
    ShowNumber16_32(2,96,TIME[0]>>4&0x07);//秒 十位
    ShowNumber16_32(2,112, TIME[0]&0x0f);//秒  个位


    //日期
    ShowNumber(0,0,2);
    ShowNumber(0,8,0);
    ShowNumber(0,16,TIME[6]>>4&0x0f);
    ShowNumber(0,24, TIME[6]&0x0f);//年

    ShowNumber(0,40,TIME[4]>>4&0x01);
    ShowNumber(0,48, TIME[4]&0x0f);//月

    ShowNumber(0,64,TIME[3]>>4&0x03);
    ShowNumber(0,72, TIME[3]&0x0f);//日

    ShowChina(0,112,(TIME[5]&0x07)-1);//周
}
void wendu() {
    //温度
    a=Read_Temperature();	  //读取DS18B20的温度
    if(a<0)					  //处理温度正负
    {
        a = (-1)*a; 	// 取补
        ShowNumber(6,88,11);	  //温度计图标—
    }
    else
    {
        ShowNumber(6,88,12);//温度计图标+
    }
    ShowNumber(6,96,a/10%10);  //显示温度中位

    ShowNumber(6,104,a%10);	   //显示温度低位

}

void digplaystart() {//开机显示
    uchar i=0;
    ShowChina(2,64-16*1.5,19);
    ShowChina(2,64-16*0.5,20);
    ShowChina(2,64+16*0.5,21);
    ShowChina(2,64+16*1.5,22);
    for (i=0; i<10; i++) {
        ShowNumber(4,32+8*i,16);
        delay5ms();
        delay5ms();
    }
    ClearScreen(0);//清屏
}

void main(void)
{
    uchar i;
    InitLCD();	  //初始化LCD12864
    digplaystart();
    delay5ms();
    Ds1302Init();//Ds1302初始化,并且附上设定的默认时间
    a=Read_Temperature();	  //读取DS18B20的温度
    ShowNumber(0,32,11);//-
    ShowNumber(0,56,11);//-
    ShowChina(0,96,7);//汉字周
    ShowNumber16_32(2,32,10);//:
    ShowNumber16_32(2,80,10);//:
    ShowChina(6,112,8);//℃
    while(1)
    {
        wendu();//温度显示
        if(flag==1)
            Ds1302ReadTime();
        //读取DS1302的时间
        else
            Ds1302WriteTime();
				
				KeyRead1();
					KeyRead2();
				KeyRead3();
					KeyRead4();	
//        if(KEY1==0)				  //按键1--处理设定时间和返回
//        {
//            delay10();
            if(KeyTrg1==1)
            {
                delay10();
                flag=~flag;

                if(flag==0) {
                    ShowChina(6,48,9);
                    ShowChina(6,0,16);
                    ShowChina(6,16,17);
                    ShowNumber(6,32,10);
                }
                if(flag==1) {
                    for( i=0; i<8; i++) {
                        ShowNumber(6,8*i,15);
                    }
                }
            }
//        }

//        if(KEY2==0)				  //按键2--处理选择设定时间的项目
//        {
//            delay10();
            if(KeyTrg2==1)
            {
                delay10();
                choose++;
                ShowChina(6,48,8+choose);
                if(choose==7)
                    choose=0x00;
            }
//        }

//        if(KEY3==0)				  //按键3--处理设定时间和返回
//        {   
//					delay10();
            if(KeyTrg3 & KEY_MODE)
            {
                delay10();
                switch(choose)
                {
                case 1:
                    TIME[6]++;
                    TIME[6]=conver(TIME[6],0xa0,0x00);
                    break;//年
                case 2:
                    TIME[5]++;
                    TIME[5]=conver(TIME[5],0x08,0x01);
                    break;//周
                case 3:
                    TIME[4]++;
                    TIME[4]=conver(TIME[4],0x13,0x01);
                    break;//月
                case 4:
                    TIME[3]++;
                    TIME[3]=conver(TIME[3],0x32,0x01);
                    break;//日
                case 5:
                    TIME[2]++;
                    TIME[2]=conver(TIME[2],0x24,0x00);
                    break;//时
                case 6:
                    TIME[1]++;
                    TIME[1]=conver(TIME[1],0x60,0x00);
                    break;//分
                case 7:
                    TIME[0]++;
                    TIME[0]=conver(TIME[0],0x60,0x00);
                    break;//秒
                }
                digplay();
            }
						/**********长按模式没有起作用***********/
            if(KeyCont3 & KEY_PLUS)
            {
                cnt_plus++;
							if (cnt_plus > 100) // 20ms*100 = 2S 如果时间到
         {
                switch(choose)
                {
                case 1:
                    TIME[6] +=5;
                    TIME[6]=conver(TIME[6],0xa0,0x00);
                    break;//年
                case 2:
                    TIME[5] +=5;
                    TIME[5]=conver(TIME[5],0x08,0x01);
                    break;//周
                case 3:
                    TIME[4] +=5;
                    TIME[4]=conver(TIME[4],0x13,0x01);
                    break;//月
                case 4:
                    TIME[3]+=5;
                    TIME[3]=conver(TIME[3],0x32,0x01);
                    break;//日
                case 5:
                    TIME[2]+=5;
                    TIME[2]=conver(TIME[2],0x24,0x00);
                    break;//时
                case 6:
                    TIME[1]+=5;
                    TIME[1]=conver(TIME[1],0x60,0x00);
                    break;//分
                case 7:
                    TIME[0]+=5;
                    TIME[0]=conver(TIME[0],0x60,0x00);
                    break;//秒
                }
                digplay();
								cnt_plus=0;
					}
            }
            if(KeyTrg4 & KEY_MODE)
            {
                delay10();
                switch(choose)
                {
                case 1:
                    TIME[6] --;
                    TIME[6]=conver(TIME[6],0xa0,0x00);
                    break;//年
                case 2:
                    TIME[5] --;
                    TIME[5]=conver(TIME[5],0x08,0x01);
                    break;//周
                case 3:
                    TIME[4] --;
                    TIME[4]=conver(TIME[4],0x13,0x01);
                    break;//月
                case 4:
                    TIME[3] --;
                    TIME[3]=conver(TIME[3],0x32,0x01);
                    break;//日
                case 5:
                    TIME[2] --;
                    TIME[2]=conver(TIME[2],0x24,<

以上是关于51单片机+LCD12864的万年历Proteus仿真的主要内容,如果未能解决你的问题,请参考以下文章

51单片机+LCD12864驱动显示汉字模板+Proteus仿真

51单片机ADC0832模数转换+ LCD12864显示+Proteus仿真

51单片机ADC0831+LCD12864+DAC0808+DS1302+24C64+Proteus仿真

51单片机 DHT11+LCD12864温湿度显示 + Proteus仿真

51单片机ST7920的LCD12864屏幕驱动显示

基于51单片机数码管万年历按键可调(Proteus仿真设计)