/*******************************************************************************
* 学校名 :杭州电子科技大学
* 大作业名 :万年历
* 小组成员 :xxx、xxx、xxx
* 实验效果 :LCD1602显示万年历,按K1进入时钟设置,按K2选择设置的年月日周时分秒,按K3选择设置+1,按K4选择设置-1
*******************************************************************************/
#include <reg51.h>
#include "lcd.h"
#include "ds1302.h"
#include "temp.h"
sbit K1 = P3 ^ 0; //设置/完成设置
sbit K2 = P3 ^ 1; //切换设置位
sbit K3 = P3 ^ 2; //+
sbit K4 = P3 ^ 3; //—
void EnterTimeSet();
void ExitTimeSet();
void IncSetTime();
void DecSetTime();
void RefreshSetShow();
void RightShiftTimeSet();
unsigned char KeyScan(); //不支持连按
void KeyAction();
void Delay10ms(void); //误差 0us
void LcdDisplay();
void LcdDisplay_temp(int temp);
unsigned char flag, year;
unsigned char SetPlace = 9;
unsigned char keynum = 5;
unsigned char T0RH = 0; //T0重载值的高字节
unsigned char T0RL = 0; //T0重载值的低字节
/*******************************************************************************
* 函数名 : main
* 函数功能 : 主函数
*******************************************************************************/
void main()
{
LcdInit();
Ds1302Init();
LcdWriteCom(0x8D); //写地址 80表示初始地址
LcdWriteData('A');
LcdWriteData('u');
LcdWriteData('t');
while (1)
{
keynum = KeyScan(); //按键扫描
//判断平年闰年
if ((2000 + TIME[0]) % 400 == 0)
year = 0;
else if ((2000 + TIME[0]) % 4 == 0 && (2000 + TIME[0]) % 100 != 0)
year = 0;
else
year = 1;
KeyAction();
if (SetPlace == 9)
{
Ds1302ReadTime();
LcdDisplay();
LcdWriteCom(0x40 + 0x8F); //写地址 80表示初始地址
LcdWriteData('C');
LcdDisplay_temp(Ds18b20ReadTemp());
}
}
}
/*******************************************************************************
* 函数名 : LcdDisplay_temp()
* 函数功能 : 温度显示函数
*******************************************************************************/
void LcdDisplay_temp(int temp) //lcd显示
{
unsigned char datas[] = {0, 0, 0, 0}; //定义数组
float tp;
if (temp < 0) //当温度值为负数
{
LcdWriteCom(0x40 + 0x89); //写地址 80表示初始地址
LcdWriteData('-'); //显示负
//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
temp = temp - 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的就
//算由?.5,还是在小数点后面。
}
else
{
LcdWriteCom(0x40 + 0x89); //写地址 80表示初始地址
LcdWriteData('+'); //显示正
tp = temp; //因为数据处理有小数点所以将温度赋给一个浮点型变量
//如果温度是正的那么,那么正数的原码就是补码它本身
temp = tp * 0.0625 * 100 + 0.5;
//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//算加上0.5,还是在小数点后面。
}
datas[0] = temp % 10000 / 1000;
datas[1] = temp % 1000 / 100;
datas[2] = temp % 100 / 10;
datas[3] = temp % 10;
LcdWriteCom(0x40 + 0x8A); //写地址 80表示初始地址
LcdWriteData('0' + datas[0]); //十位
LcdWriteCom(0x40 + 0x8B); //写地址 80表示初始地址
LcdWriteData('0' + datas[1]); //个位
LcdWriteCom(0x40 + 0x8C); //写地址 80表示初始地址
LcdWriteData('.'); //显示 ‘.’
LcdWriteCom(0x40 + 0x8D); //写地址 80表示初始地址
LcdWriteData('0' + datas[2]); //显示小数点
LcdWriteCom(0x40 + 0x8E); //写地址 80表示初始地址
LcdWriteData('0' + datas[3]); //显示小数点
}
/*******************************************************************************
* 函数名 : LcdDisplay()
* 函数功能 : 显示函数
*******************************************************************************/
void LcdDisplay()
{
LcdWriteCom(0x80 + 0x40);
LcdWriteData('0' + TIME[4] / 16); //时
LcdWriteData('0' + (TIME[4] & 0x0f));
LcdWriteData(':');
LcdWriteData('0' + TIME[5] / 16); //分
LcdWriteData('0' + (TIME[5] & 0x0f));
LcdWriteData(':');
LcdWriteData('0' + TIME[6] / 16); //秒
LcdWriteData('0' + (TIME[6] & 0x0f));
LcdWriteCom(0x80);
LcdWriteData('2');
LcdWriteData('0');
LcdWriteData('0' + TIME[0] / 16); //年
LcdWriteData('0' + (TIME[0] & 0x0f));
LcdWriteData('-');
LcdWriteData('0' + TIME[1] / 16); //月
LcdWriteData('0' + (TIME[1] & 0x0f));
LcdWriteData('-');
LcdWriteData('0' + TIME[2] / 16); //日
LcdWriteData('0' + (TIME[2] & 0x0f));
LcdWriteCom(0x8B);
LcdWriteData('0' + (TIME[3] & 0x07)); //星期
}
/*******************************************************************************
* 函数名 : Delay10ms
* 函数功能 : 延时函数,延时10ms
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void Delay10ms(void) //误差 0us
{
unsigned char a, b, c;
for (c = 1; c > 0; c--)
for (b = 38; b > 0; b--)
for (a = 130; a > 0; a--)
;
}
/*******************************************************************************
*
* 时间设置相关函数
*
*******************************************************************************/
/* 进入时间设置状态 */
void EnterTimeSet()
{
LcdWriteCom(0x8D); //写地址 80表示初始地址
LcdWriteData('S');
LcdWriteData('e');
LcdWriteData('t');
SetPlace = 0; //把设置索引设置为0,即可进入设置状态
RefreshSetShow(); //刷新光标位置
LcdOpenCursor(); //打开光标闪烁效果
}
/* 退出时间设置状态*/
void ExitTimeSet()
{
LcdWriteCom(0x8D); //写地址 80表示初始地址
LcdWriteData('A');
LcdWriteData('u');
LcdWriteData('t');
SetPlace = 9; //把设置索引设置为9,即可退出设置状态
LcdCloseCursor(); //关闭光标显示
Ds1302Init();
LcdWriteCom(0x40 + 0x8F); //写地址 80表示初始地址
LcdWriteData('C');
LcdDisplay_temp(Ds18b20ReadTemp());
}
/* 递增当前设置位的值 */
void IncSetTime()
{
TIME[SetPlace]++;
if ((TIME[SetPlace] & 0x0f) > 9) //换成BCD码
{
TIME[SetPlace] = TIME[SetPlace] + 6;
}
if ((TIME[SetPlace] >= 0x9A) && (SetPlace == 0)) //年只能到2099
{
TIME[SetPlace] = 0;
}
if ((TIME[SetPlace] >= 0x13) && (SetPlace == 1)) //月只能到12
{
TIME[SetPlace] = 1;
}
//不同月份的天数不同:
if (TIME[1] == 1 || TIME[1] == 3 || TIME[1] == 5 || TIME[1] == 7 || TIME[1] == 8 || TIME[1] == 10 || TIME[1] == 12) //月份为大
{
if((TIME[SetPlace] >= 0x32) && (SetPlace == 2)) //日只能到31
{
TIME[SetPlace] = 1;
}
}
if (TIME[1] == 4 || TIME[1] == 6 || TIME[1] == 9 || TIME[1] == 11) //月份为小
{
if ((TIME[SetPlace] >= 0x31) && (SetPlace == 2)) //日只能到30
{
TIME[SetPlace] = 1;
}
}
if ((TIME[1] == 2) && (SetPlace == 2)) //月份为2月
{
if ((TIME[SetPlace] >= 0x30) && (year == 0)) //闰年日只能到29
{
TIME[SetPlace] = 1;
}
if ((TIME[SetPlace] >= 0x29) && (year == 1)) //平年日只能到28
{
TIME[SetPlace] = 1;
}
}
if ((TIME[SetPlace] >= 0x08) && (SetPlace == 3)) //周只能到7
{
TIME[SetPlace] = 1;
}
if ((TIME[SetPlace] >= 0x24) && (SetPlace == 4)) //时只能到23
{
TIME[SetPlace] = 0;
}
if ((TIME[SetPlace] >= 0x60) && (SetPlace == 5)) //分只能到60
{
TIME[SetPlace] = 0;
}
if ((TIME[SetPlace] >= 0x60) && (SetPlace == 6)) //秒只能到60
{
TIME[SetPlace] = 0;
}
LcdDisplay(); //刷新时间显示
RefreshSetShow(); //刷新光标显示
}
/* 递减当前设置位的值 */
void DecSetTime()
{
TIME[SetPlace]--;
if ((TIME[SetPlace] & 0xf0) < 0x00) //换成BCD码
{
TIME[SetPlace] = TIME[SetPlace] - 0x10;
}
if ((TIME[SetPlace] & 0x0f) > 9) //换成BCD码
{
TIME[SetPlace] = TIME[SetPlace] - 6;
}
if (('0' +(TIME[0]/16)=='?') && (SetPlace == 0)) //年只能到2099
{
TIME[SetPlace] = 0x99;
}
if ((TIME[SetPlace] <= 0x00) && (SetPlace == 1)) //月只能到12
{
TIME[SetPlace] = 0x12;
}
//不�
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
C51万年历设计(LCD1602).rar (30个子文件)
C51万年历设计(LCD1602)
实物图.jpg 429KB
程序
pro.hex 10KB
main.__i 62B
pro.uvgui.Narziss 89KB
ds1302.c 3KB
ds1302.OBJ 6KB
lcd.h 1KB
STARTUP.OBJ 749B
main.OBJ 19KB
STARTUP.A51 6KB
ds1302.h 534B
temp.OBJ 5KB
pro.uvgui.HP 170KB
pro 31KB
pro.uvgui.Administrator 67KB
lcd.c 4KB
STARTUP.LST 14KB
pro.uvproj 14KB
temp.h 310B
pro.build_log.htm 964B
pro.uvopt 7KB
ds1302.LST 6KB
temp.LST 7KB
lcd.OBJ 5KB
temp.c 4KB
main.LST 19KB
main.c 10KB
pro.lnp 80B
lcd.LST 7KB
pro.M51 39KB
共 30 条
- 1
资源评论
朴樕
- 粉丝: 177
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功