找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1365|回复: 2
收起左侧

比较好的电子时钟

[复制链接]
ID:274998 发表于 2018-1-11 21:21 | 显示全部楼层 |阅读模式
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
/////////////////
sbit rw = P2^6;//
sbit rs = P2^5;//        1602 IO口位定义
sbit en = P2^7;//
/////////////////
///////////////////
sbit rst = P3^5; //
sbit sclk = P3^6;//                1302 IO口位定义
sbit io = P3^4;        //
///////////////////
///////////////////
sbit key1 = P1^0;//
sbit key2 = P1^1;//                独立按键位定义
sbit key3 = P1^2;//
sbit key4 = P1^3;//               
///////////////////
///////////////////
sbit DQ = P2^2;////
///////////////////
uchar tempL=0; //临时变量低位
uchar tempH=0; //临时变量高位
uint temperature;
uint hour, minute, second, year, month, day;
uint key = 0;
uchar tab_num[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x2d}; //对应字符为:        {        0 1 2 3 4 5 6 7 8 9 : -        }
uchar tab_time[] = {1,2,10,3,4,10,5,6};
uchar tab_date[] = {2,0,1,0,11,0,9,11,2,7};
// 延时函数,延时z毫秒 ******
void delay(uint z)       
{
        uint x, y;
        for(x=0;x<z;x++)
                for(y=0;y<110;y++);
}
//***************************
/****************************************************************************
函数功能:延时子程序
入口参数:k
出口参数:
****************************************************************************/
void delay18b20(unsigned int k)
{
        unsigned int n;
       
        n=0;
       
        while(n < k)
       
        {n++;}
       
        return;
}
/****************************************************************************
函数功能:DS18B20初始化子程序
入口参数:
出口参数:
****************************************************************************/
Init_DS18B20(void)
{
        unsigned char x=0;
       
        DQ=1; //DQ先置高
       
        delay18b20(8); //延时
       
        DQ=0; //发送复位脉冲
       
        delay18b20(85); //延时(>480ms)
       
        DQ=1; //拉高数据线
       
        delay18b20(14); //等待(15~60ms)
}
/****************************************************************************
函数功能:DS18B20读一字节数据
入口参数:
出口参数:dat
****************************************************************************/
ReadOneChar(void)
{
        unsigned char i=0;
       
        unsigned char dat=0;
       
        for (i=8;i>0;i--)
        {
                DQ=1;
               
                delay18b20(1);
               
                DQ=0;
               
                dat>>=1;
               
                DQ=1;
               
                if(DQ)
               
                dat|=0x80;
               
                delay18b20(4);
               
        }
        return(dat);
}
/****************************************************************************
函数功能:DS18B20写一字节数据
入口参数:dat
出口参数:
****************************************************************************/
WriteOneChar(unsigned char dat)
{
        unsigned char i=0;
       
        for(i=8;i>0;i--)
        {
               
                DQ=0;
               
                DQ=dat&0x01;
               
                delay18b20(5);
               
                DQ=1;
               
                dat>>=1;
       
        }
        delay18b20(4);
}
/****************************************************************************
函数功能:DS18B20读温度值
入口参数:
出口参数:temperature
****************************************************************************/
uint ReadTemperature(void)
{
        Init_DS18B20(); //初始化
       
        WriteOneChar(0xcc); //跳过读序列号的操作
       
        WriteOneChar(0x44); //启动温度转换
       
        delay18b20(125); //转换需要一点时间,延时
       
        Init_DS18B20(); //初始化
       
        WriteOneChar(0xcc); //跳过读序列号的操作
       
        WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)
       
        tempL=ReadOneChar(); //读出温度的低位LSB
       
        tempH=ReadOneChar(); //读出温度的高位MSB
        //温度转换,把高低位做相应的运算转化为实际温度
       
        temperature=((tempH*256)+tempL)*5/8;
       
        delay18b20(200);
       
        return(temperature);
}
//========1302写一个字节=========
void write_byte(uchar dat)
{
        uchar i, dat_w;
        dat_w = dat;
        for(i=0;i<8;i++)
        {
                io = 0;
                if(dat_w & 0x01)
                        io = 1;
                else
                        io = 0;
                dat_w = dat_w >> 1;
                sclk = 0;
                sclk = 1;
        }
        sclk = 0;
}
//===============================
//========1302读一个字节=========
uchar read_byte()
{
        uchar i, k;
        k = 0;
        for(i=0;i<8;i++)
        {
                k = k >> 1;
                if(io)
                        k = k|0x80;
                sclk = 1;
                sclk = 0;
        }
        sclk = 0;
        return (k);
}
//===============================
//========1302把数据写入地址=====
void write_add(uchar add, uchar dat)
{
        rst = 0;
        sclk = 0;
        rst = 1;
        write_byte(add);
        write_byte((dat / 10 << 4) | (dat % 10));
        sclk = 0;
        rst = 0;
}
//===============================
//========1302从地址读出数据=====
uchar read_add(uchar add)
{
        uchar temp, dat1, dat2;
        rst = 0;
        sclk = 0;
        rst = 1;
        write_byte(add);
        temp = read_byte();
        sclk = 0;
        rst = 0;
        dat1 = temp / 16;
        dat2 = temp % 16;
        temp = dat1 * 10 + dat2;
        return (temp);
}
//===============================
//=========1302时间初始化========
void ds1302_init()
{
        write_add(0x8e,0x00);        //打开写保护,写入时间;
        write_add(0x80,50);                //初始化--秒  50
        write_add(0x82,59);                //初始化--分  59
        write_add(0x84,23);                //初始化--时  23
        write_add(0x86,31);                //初始化--日  31
        write_add(0x88,12);                //初始化--月  12
        write_add(0x8c,10);                //初始化--年  2010
        write_add(0x8e,0x80);        //关闭写保护,禁止写入。
}
//===============================
//=========1302读出时间==========
void ds1302()
{
        write_add(0x8e,0x00);                        //打开写保护,读出时间;
        second = read_add(0x81);                //1302读出时间--秒;
        minute = read_add(0x83);                //1302读出时间--分;
        hour   = read_add(0x85);                //1302读出时间--时;
        day    = read_add(0x87);                //1302读出时间--日;
        month  = read_add(0x89);                //1302读出时间--月;
        year   = read_add(0x8d);                //1302读出时间--年;
        write_add(0x8e,0x80);                        //关闭写保护,禁止读出;
}
//===============================
//写命令函数 ****************
void write_com(uchar com)
{
        rs = 0;
        rw = 0;
        en = 0;
        delay(5);
        P0 = com;
        delay(5);
        en = 1;
        delay(5);
        en = 0;
}
//***************************
//写数据函数*****************
void write_data(uchar date)
{
        rs = 1;
        rw = 0;
        en = 0;
        delay(5);
        P0 = date;
        delay(5);
        en = 1;
        delay(5);
        en = 0;
}
//***************************
//1602显示一个字符===========
void DisplayOne(uchar *p)
{
                write_data(*p);
}
//===========================
//======时间重新赋值=========
void time()
{
        tab_time[0] = hour / 10;
        tab_time[1] = hour % 10;
        tab_time[3] = minute /10;
        tab_time[4] = minute % 10;
        tab_time[6] = second / 10;
        tab_time[7] = second % 10;
        tab_date[2] = year / 10;
        tab_date[3] = year % 10;
        tab_date[5] = month / 10;
        tab_date[6] = month % 10;
        tab_date[8] = day / 10;
        tab_date[9] = day % 10;
}
//===========================
//======1602初始化===========
void init()
{
        write_com(0x38);
        write_com(0x0c);
        write_com(0x06);
        write_com(0x01);       
}
//===========================
//=====时间显示函数==========
void DisplayTime()
{
        uint n;
        ds1302();
        time();
        write_com(0x80 + 6);
        for(n=0;n<10;n++)
        {
                DisplayOne(tab_num + tab_date[n]);        //显示日期
        }
               
        write_com(0x80 + 0x40 + 6);
        for(n=0;n<8;n++)
        {
                DisplayOne(tab_num + tab_time[n]);        //显示时间
        }
}
//===========================
//=========时钟停止==========
void stop()
{
        write_add(0x8e, 00);                //打开写保护
        write_add(0x80,80);                //时钟停止
        write_add(0x8e, 80);                //禁止写保护
       
        write_com(0x80+0x40+12);                                //===================
        write_data(tab_num[second/10]);                //                显示秒
        write_data(tab_num[second%10]);                //===================
}
//===========================
//==========时钟开始=========
void start()
{
        write_add(0x8e, 00);                //打开写保护
        write_add(0x80,second);                //读入秒
        write_add(0x8e, 80);                //禁止写保护
}
//=====矩阵键盘扫描函数======
void KeyScan()          
{
        P1 = 0xff;
        if(key1 == 0)          //即独立键盘中的k1
        {
                delay(10);
                if(key1 == 0)
                {
                        key = 1;
                        while(!key1);
                }
        }
        if(key2 == 0)          //即独立键盘中的k2
        {
                delay(10);
                if(key2 == 0)
                {
                        key = 2;
                        while(!key2);
                }
        }
        if(key3 == 0)          //即独立键盘中的k3
        {
                delay(10);
                if(key3 == 0)
                {
                        key = 3;
                        while(!key3);
                }
        }       
        if(key4 == 0)          //即独立键盘中的k6
        {
                delay(10);
                if(key4 == 0)
                {
                        key = 4;
                        while(!key4);
                }
        }
}
//============================
//======按键操作函数==========
void KeyDo()
{
        uint m = 15;        //用以修改日期(第一行)时,移动闪烁光标。
        uint n = 13;        //用以修改时间(第二行)时,移动闪烁光标。
        if(key == 1)
        {
                key = 0;
                stop();
                write_com(0x80 + 0x40 + n);                         
                write_com(0x0f);                               
                while(1)
                {
                        KeyScan();
                        if(key == 3)
                        {
                                n = n + 3;
                                if(n > 13)
                                        n = 7;
                                write_com(0x80 + 0x40 + n);
                                write_com(0x0f);
                                key = 0;
                        }
                        switch(n)
                        {
                                case 13 :
                                        if(key == 2)
                                        {
                                                second++;
                                                if(second == 60)
                                                        second = 0;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x80,second);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 0x40 + 12);       
                                                DisplayOne(tab_num + tab_time[6]);               
                                                DisplayOne(tab_num + tab_time[7]);
                                                write_com(0x80 + 0x40 + 13);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                                        if(key == 4)
                                        {
                                                second--;
                                                if(second == -1)
                                                        second = 59;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x80,second);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 0x40 + 12);       
                                                DisplayOne(tab_num + tab_time[6]);               
                                                DisplayOne(tab_num + tab_time[7]);
                                                write_com(0x80 + 0x40 + 13);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                                case 10 :
                                        if(key == 2)
                                        {
                                                minute++;
                                                if(minute == 60)
                                                        minute = 0;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x82,minute);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 0x40 + 9);       
                                                DisplayOne(tab_num + tab_time[3]);               
                                                DisplayOne(tab_num + tab_time[4]);
                                                write_com(0x80 + 0x40 + 10);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                                        if(key == 4)
                                        {
                                                minute--;
                                                if(minute == -1)
                                                        minute = 59;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x82,minute);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 0x40 + 9);       
                                                DisplayOne(tab_num + tab_time[3]);               
                                                DisplayOne(tab_num + tab_time[4]);
                                                write_com(0x80 + 0x40 + 10);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                                case 7 :
                                        if(key == 2)
                                        {
                                                hour++;
                                                if(hour == 24)
                                                        hour = 0;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x84,hour);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 0x40 + 6);       
                                                DisplayOne(tab_num + tab_time[0]);               
                                                DisplayOne(tab_num + tab_time[1]);
                                                write_com(0x80 + 0x40 + 7);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                                        if(key == 4)
                                        {
                                                hour--;
                                                if(hour == -1)
                                                        hour = 23;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x84,hour);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 0x40 + 6);       
                                                DisplayOne(tab_num + tab_time[0]);               
                                                DisplayOne(tab_num + tab_time[1]);
                                                write_com(0x80 + 0x40 + 7);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                        }
                        if(key == 1)
                        {
                                start();
                                key = 0;
                                write_com(0x0c);
                                break;
                        }
                }       
        }
        if(key == 3)
        {
                stop();
                write_com(0x80 + m);          
                write_com(0x0f);
                while(1)
                {
                        KeyScan();
                        if(key == 3)
                        {
                                m = m + 3;
                                if(m > 15)
                                        m = 9;
                                write_com(0x80 + m);
                                write_com(0x0f);
                                key = 0;
                        }
                        switch(m)
                        {
                                case 15 :
                                        if(key == 2)
                                        {
                                                day++;
                                                if(day == 32)
                                                        day = 1;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x86,day);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 14);       
                                                DisplayOne(tab_num + tab_date[8]);               
                                                DisplayOne(tab_num + tab_date[9]);
                                                write_com(0x80 + 15);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                                        if(key == 4)
                                        {
                                                day--;
                                                if(day == 0)
                                                        day = 31;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x86,day);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 14);       
                                                DisplayOne(tab_num + tab_date[8]);               
                                                DisplayOne(tab_num + tab_date[9]);
                                                write_com(0x80 + 15);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                                case 12 :
                                        if(key == 2)
                                        {
                                                month++;
                                                if(month == 13)
                                                        month = 1;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x88,month);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 11);       
                                                DisplayOne(tab_num + tab_date[5]);               
                                                DisplayOne(tab_num + tab_date[6]);
                                                write_com(0x80 + 12);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                                        if(key == 4)
                                        {
                                                month--;
                                                if(month == -1)
                                                        month = 12;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x88,month);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 11);       
                                                DisplayOne(tab_num + tab_date[5]);               
                                                DisplayOne(tab_num + tab_date[6]);
                                                write_com(0x80 + 12);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                                case 9 :
                                        if(key == 2)
                                        {
                                                year++;
                                                if(year == 100)
                                                        year = 0;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x8c,year);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 8);       
                                                DisplayOne(tab_num + tab_date[2]);               
                                                DisplayOne(tab_num + tab_date[3]);
                                                write_com(0x80 + 9);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                                        if(key == 4)
                                        {
                                                year--;
                                                if(year == -1)
                                                        year = 23;       
                                                time();
                                                write_add(0x8e,0x00);
                                                write_add(0x8c,year);
                                                write_add(0x8e,0x80);
                                                write_com(0x80 + 8);       
                                                DisplayOne(tab_num + tab_date[2]);               
                                                DisplayOne(tab_num + tab_date[3]);
                                                write_com(0x80 + 9);
                                                write_com(0x0f);       
                                                key = 0;       
                                        }
                        }
                        if(key == 1)
                        {       
                                key = 0;
                                start();
                                write_com(0x0c);
                                break;
                        }
                }       
        }
}
void Display_18b20()
{
        uint t1,t2,t3;
        t1 = ReadTemperature()/100%10;
        t2 = ReadTemperature()/10%10;
        t3 = ReadTemperature()%10;
        write_com(0x80);
        write_data(tab_num[t1]);
        write_data(tab_num[t2]);
        DisplayOne(".");
        write_data(tab_num[t3]);
}
//============================
void main()
{
        init();
        ds1302_init();       
        while(1)
        {       
                Display_18b20();
                KeyScan();
                KeyDo();
                DisplayTime();       
        }
}

回复

使用道具 举报

ID:274998 发表于 2018-1-11 21:26 | 显示全部楼层
大家来看看  提点建议
回复

使用道具 举报

ID:275025 发表于 2018-1-11 22:32 | 显示全部楼层
看起来不错,感谢分享!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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