×
单片机 > 单片机程序设计 > 详情

51单片机做的智能时钟具有闹钟功能(DS1302+DS18B20+LCD1602)

发布时间:2020-06-08 发布时间:
|

本贴针对学完单片机并且有读懂代码的非新手同学。本人目前放寒假,这个是本人在上个学期的单片机课上要求做的综合实验,现在重新修改了下增加了菜单目前测试毫无问题可以完美使用。有志向做闹钟的同学可以参考一下,原码上由本人写的大量注释可以方便看懂。


使用了LCD1602、DS1302、DS18B20用来测试温度、内部含闹钟系统但本人没有做EEPROM有需要的同学可以自行添加。

单片机源程序如下:

#include

#include

#include

#include

#include

#include


#define normal 0//正常显示时钟界面

#define settime 1//设定时钟界面

#define setalarm 2//设定闹钟界面

#define displayalarm 3//显示闹钟界面

#define normal_12 4//显示十二小时制界面

#define caidan 5


unsigned char system=normal;//我一开始就把界面切换为正常显示时钟界面


extern unsigned char i,k;


extern unsigned int code song[3][300];


unsigned char code *week[8]={"NO ","Mon ","Tue ","Wed ","Thu ","Fri ","Sat ","Sun "};


unsigned char code *clockzifu[4]={"ON ","OFF ","REP ","NRE "};


struct Time timeset={0x18,0x01,0x16,0x14,0x30,0x50,0x03}; 


//第一个闹钟

//第二个闹钟

//第三个闹钟

//第四个闹钟

//第五个闹钟

struct alarmtime xdata clock[5]={{1,16,14,31,0,1,0,1},{1,8,14,32,3,0,0,0},{1,7,18,49,1,1,1,0},{0,0,0,0,0,0,1,0},{1,25,0,0,0,0,1,2}};


unsigned char alarmnum;//闹钟


unsigned char a;


unsigned char flag=0;


unsigned char xinghao=0;


unsigned char tentoBCD(unsigned char dat)//十进制转换为BCD码函数

{

        unsigned char dat1,dat2;

        dat1=dat/10;

        dat2=dat%10;

        dat2=dat2+dat1*16;

        return dat2;

}


unsigned char BCDtoten(unsigned char dat)//BCD码转为十进制函数

{

        unsigned char dat1,dat2;

        dat1=dat/16;

        dat2=dat%16;

        dat2=dat2+dat1*10;

        return dat2;

}


void DS18B20deal(int temp)//DS18B20数据处理函数 显示温度更新温度         

{

    //先判断温度值是否大于0或小于0等于0

           float tp;//保存的数据可能带小数  

        if(temp<0)//当温度值为负数

          {

                LCD1602_writechar(9,1,0x2D);//ASCII码中的-符号

                temp=temp-1;//因为读取的温度是实际温度的补码,所以减1,再取反求出原码

                temp=~temp;//还原读取的数据

                tp=temp;//保存到变量里面

                temp=tp*0.0625*100+0.5;//强制转换成一个整形的数据.留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就算加上0.5,还是在小数点后面。        

          }

        else//当温度值为正数

          {                        

                LCD1602_writechar(9,1,0x20);//ASCII码中的空格

                tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量。如果温度是正的那么,那么正数的原码就是补码它本身

                temp=tp*0.0625*100+0.5;//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点。后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就算加上0.5,还是在小数点后面。        

        }

        LCD1602_writechar(10,1,temp/10000+'0');//温度百位

        LCD1602_writechar(11,1,temp%10000/1000+'0');//温度十位

        LCD1602_writechar(12,1,temp%1000/100+'0');//温度个位

    LCD1602_writechar(13,1,0x2E);//ASCII码小数点

        LCD1602_writechar(14,1,temp%100/10+'0');//小数点后一位

        LCD1602_writechar(15,1,temp%10+'0');//小数点后两位

}


void updatetime()//更新时钟上的时间

{

        unsigned char time[9];//存储变量

        DS1302_gettime(×et);//读取时间

        time[0]=BCDtoten(timeset.hour)/10+'0';//小时的十位

        time[1]=BCDtoten(timeset.hour)%10+'0';//小时的个位

        time[2]=':';

        time[3]=BCDtoten(timeset.min)/10+'0';//分的十位

        time[4]=BCDtoten(timeset.min)%10+'0';//分的个位

        time[5]=':';

        time[6]=BCDtoten(timeset.sec)/10+'0';//秒的十位

        time[7]=BCDtoten(timeset.sec)%10+'0';//秒的个位

        time[8]='';//字符串结束标志


        LCD1602_writestr(0,1,time);//在LCD上面打印时间

}


void updatetime_12()//更新十二小时制界面的时间

{

        unsigned char time[9];

        DS1302_gettime(×et);//读取时间

        time[0]= BCDtoten(timeset.hour)%12/10+'0';//小时的十位 

        time[1]= BCDtoten(timeset.hour)%12%10+'0';//小时的个位

        time[2]=':';

        time[3]= BCDtoten(timeset.min)/10+'0';//分的十位

        time[4]= BCDtoten(timeset.min)%10+'0';//分的个位

        time[5]=':';

        time[6]= BCDtoten(timeset.sec)/10+'0';//秒的十位

        time[7]= BCDtoten(timeset.sec)%10+'0';//秒的个位

        time[8]='';//字符串结束标志                                                                                                                                                                                                               

        LCD1602_writestr(3,1,"TIME:");//打印出TIME的字符串

        LCD1602_writestr(8,1,time);//在第二行第四列显示时间

        if(BCDtoten(timeset.hour)>12)//要是小时大于12时

        {

          LCD1602_writestr(0,1,"PM");//则显示PM

        } 

        else//小时不大于12

        {

          LCD1602_writestr(0,1,"AM");//则显示AM

        }  

}


void updatedate()//更新日历

{

        unsigned char date[12];

        date[0]= '2';

        date[1]= '0';

        date[2]= BCDtoten(timeset.year)/10%10+'0';//年的十位

        date[3]= BCDtoten(timeset.year)%10+'0';//年的个位

        date[4]='.';

        date[5]= BCDtoten(timeset.mon)/10+'0';//月的十位

        date[6]= BCDtoten(timeset.mon)%10+'0';//月的个位

        date[7]='.';

        date[8]= BCDtoten(timeset.day)/10+'0';//日的十位

        date[9]= BCDtoten(timeset.day)%10+'0';//日的个位

        date[10]='';

        LCD1602_writestr(0,0,date);//显示年月日

        LCD1602_writestr(11,0,week[timeset.week]);//显示星期

}


void updatealarm()//更新闹钟设定值

{

        unsigned char str0[14];

        unsigned char str1[2];


        str0[0]=alarmnum+'0';

        str0[1]=' ';

        str0[2]=clock[alarmnum].mon/10+'0';//月份十位

        str0[3]=clock[alarmnum].mon%10+'0';//月份个位

        str0[4]='-';

        str0[5]=clock[alarmnum].day/10+'0';//日期十位

        str0[6]=clock[alarmnum].day%10+'0';//日期个位

        str0[7]=' ';

        str0[8]=clock[alarmnum].hour/10+'0';//小时十位

        str0[9]=clock[alarmnum].hour%10+'0';//小时个位

str0[10


关键字:51单片机  智能时钟  DS1302  DS18B20  LCD1602

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
STM32中断向量表的位置.重定向