本贴针对学完单片机并且有读懂代码的非新手同学。本人目前放寒假,这个是本人在上个学期的单片机课上要求做的综合实验,现在重新修改了下增加了菜单目前测试毫无问题可以完美使用。有志向做闹钟的同学可以参考一下,原码上由本人写的大量注释可以方便看懂。
使用了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
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』