找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于ds1302的万年历时钟proteus仿真源码

[复制链接]
跳转到指定楼层
楼主
ID:361428 发表于 2018-6-28 23:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg51.h>
#include "Clock.h"
#include "OrphanKey.h"
#include "I2C.h"
/*
1.利用实验板和配件,设计一个时钟,时间显示在LCD1602上,并按秒更新,能够在实验板上设计3个按键调整时,分,秒。其功能为:功能选择键,数值增大和数值减小键。利用板上AT24C02设计实现断电保护显示数据的功能。
*/

/*
步骤:
1、设计一个中断,用来计时
2、设计一个字符生成函数,用来生成所需的时间
3、独立按键监测功能,用来监测按下了什么键
4、一个外部中断
5、一个断点保护的功能,其实就是通过I2C写入,读取数值
*/

//=========全局变量区============================================
#define uchar unsigned char
#define uint unsigned int
uchar code table[]="12:23:12";
uchar code table1[]="I am a boy!";
sbit lcden=P2^7;  //液晶使能端
sbit lcdrs=P2^6;  //数据或命令控制(0代表命令,1代表数据)  
sbit LCDWR=P2^5;  //读写控制(0代表写,1代表读)
uchar num;
uchar FIRST_LINE=0x80;
uchar SECOND_LINE=0xc0;
uchar Current_Time[9];
uchar Hour,Minute,Second=0;//时、分、秒
sbit beer = P1 ^4;      //蜂鸣器
// sbit led1=P1^3;

//=========全局变量区结束============================================


//=========函数区============================================

/***********************************************************
    延时函数
    参数说明:
    z代表要延时z ms
***********************************************************/
void delay(uint z)
{
    uint x,y;
    for(x=z;x>0;x--)
       for(y=110;y>0;y--);
}
/***********************************************************
    写命令或数据
    参数说明:
    isRs=1代表写数据,isRs=0代表写命令
***********************************************************/
void write(uchar mdata, uchar isRs)
{
    lcdrs=isRs;
    P0=mdata;
    delay(5);
    lcden=1;
    delay(5);
    lcden=0;
}
/***********************************************************
    写命令
    参数说明:
    data代表要写的命令
***********************************************************/
void write_command(uchar com)
{
    write(com,0);
}
/***********************************************************
    写数据
    参数说明:
    data代表要写的数据
***********************************************************/
void write_data(uchar mdata)
{
    write(mdata,1);
}

/***********************************************************
    初始化时钟
***********************************************************/
void InitTime(){
    // 时间的转换
    Current_Time[0]=Hour/10+'0';
    Current_Time[1]=Hour%10+'0';
    Current_Time[2]=':';
    Current_Time[3]=Minute/10+'0';
    Current_Time[4]=Minute%10+'0';
    Current_Time[5]=':';
    Current_Time[6]=Second/10+'0';
    Current_Time[7]=Second%10+'0';
    Current_Time[8]='\0';
}

/***********************************************************
    保存时钟的值
***********************************************************/
void KeepClockValue(){
    I2C_write_address(2,Second);
    delay(10);
    I2C_write_address(3,Minute);     
    delay(10);
    I2C_write_address(4,Hour);   
}

/***********************************************************
    改变时间
***********************************************************/
void changeTime()
{
    // 时间的转换
    if(Second>=60){
       Second=0;
       Minute++;
    }else{
       ++Second;
    }

    if(Minute==60){
       Hour++;
       Minute=0;
    }
    if(Hour==24){
       Second=0;
       Minute=0;
       Hour=0;
    }
    KeepClockValue();
}
/**
    初始化
**/
void InitClockInterrupt(){//初始化中断

    TMOD=0x11;        // 对TMOD赋值,以确定T0和T1的工作方式。
    TH0=T_High_50ms;// 计算初值,并将其写入TH0、TL0或TH1、TL1。
    TL0=T_Low_50ms;
    EA =1;//开启中断总允许
    ET0 =1;  
    IT0 =1;   //开启定时器0,1中断允许
    TR0=1;     // 使TR0或TR1置位,启动定时/计数器定时或计数
    Count=Count_T1=Count_1s=0;//计数
}
/***********************************************************
    初始化按钮中断
***********************************************************/
void initButtonInterupt(){
    IT0 =0;
    //EA = 1;     //开启中断总允许
    EX0 =1;   //外部中断0允许位
}


void init()
{

    InitTime();
    lcden=0;
    LCDWR=0;
    write_command(0x38);//设置16X2显示,5X7点阵,8位数据接口
    write_command(0x0c);//设置开显示,不显示光标
    write_command(0x06);//写一个字符后地址指针加1
    write_command(0x01);//显示清零,数据指针清零
}
void WriteStringToLCD(uchar *dat)
{
    while(*dat!='\0')
    {  
       write_data(*dat);
       dat++;
       delay(5);
    }
}
/***********************************************************
    向LCD整体左移动
***********************************************************/
void LCD_MoveToLeft(){
    int num;
    for(num=0;num<16;num++)
    {
           write_command(0x18);
           delay(200);
    }
}


/***********************************************************
    向LCD打印字符串
***********************************************************/
void PrintToLCD(){

    //write_command(FIRST_LINE);
    //WriteStringToLCD(table);
    write_command(SECOND_LINE);
    WriteStringToLCD(Current_Time);

}

/***********************************************************
    是否加1
***********************************************************/
void IsAdd(){
    if(PRESSED==Key_ADD){       //当加1按键按下
       delay(10);        //去抖动
       if(PRESSED==Key_ADD){    //当加1按键按下
           changeTime();
           InitTime();
           PrintToLCD();
           while(!Key_ADD);
       }
    }
}
/***********************************************************
    是否减1
***********************************************************/
void IsMinus(){
    if(PRESSED==KEY_MINUS){     //当减1按键按下
       delay(10);        //去抖动
       if(PRESSED==KEY_MINUS){  //当减1按键按下
           if(Second>0){    //防止按下减1按钮的时候,被减成负数
              Second--;
              InitTime();
              PrintToLCD();
              while(!KEY_MINUS);
           }
       }
    }
}
/***********************************************************
    是否运行
***********************************************************/
void IsRun(){
    if(PRESSED==FUNCTION_KEY){      //当减1按键按下
       delay(10);        //去抖动

       if(PRESSED==FUNCTION_KEY){  //当减1按键按下
           SUSPEND=~SUSPEND;
           // led1=SUSPEND;
       while(!KEY_MINUS);
        }
    }
}
/***********************************************************
    是否暂停
***********************************************************/
void IsSuspend(){
    IsRun();
    IsMinus();        //监测是否需要减1
    IsAdd();          //监测是否需要加1     
}
/***********************************************************
    重新计数
***********************************************************/
void ReCount(){
    Count=0;  //开始下一轮1s的计时
    TH0=T_High_50ms;// 计算初值,并将其写入TH0、TL0或TH1、TL1。
    TL0=T_Low_50ms;
}
/***********************************************************
    初始化时钟的值
***********************************************************/
void initClockValue(){
    Second=I2C_read_address(2);    //读出保存的数据赋于Second

    Minute=I2C_read_address(3);
    Hour=I2C_read_address(4);
}
void main()
{
    init();
    InitClockInterrupt();
    initButtonInterupt();
    initClockValue();
    if(Second>100)        //防止首次读取出错误数据
       Second=0;

    while(1){
    IsSuspend();
    if(Count>=20&&(!SUSPEND)){//定时器0 1s时间到
           ReCount();
           changeTime();
           InitTime();
           PrintToLCD();
       }
    }

}
//=========函数区结束============================================

//=========中断函数区============================================

/**
    初始化按钮外部中断
**/
void intButton() interrupt 0//外部中断0
{

}

/**
    用定时0实现8个发光二极管以1s间隔闪烁
**/
void int0() interrupt 1//定时/计数器T0中断
{
    Count++;
}


//=========中断函数区结束============================================

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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