基于利用时钟芯片DS1302实现万年历,1602LCD显示电子表 - 图文
更新时间:2024-06-06 04:58:01 阅读量: 综合文库 文档下载
电子设计大赛培训第二阶段
第**组报告
《基于利用时钟芯片DS1302实现万年历,1602LCD显示电子表》
成员姓名:*** 学号:****** 成员姓名:HG** 学号:****** 成员姓名:*** 学号:*******
一、主要功能
1、在1602液晶上显示年、月、日、星期、时、分、秒以及实时
温度,并且实时更新显示;
2、通过按键随时调节各显示参数,分别实现光标定位、数值增大、数值减小、闹钟和温度上下限查看的功能;
3.在时间出现乱码的情况下,具有一键初始化时间的功能。
二、电路图
三、实物图
1.开关模块
2、显示模块
3、at89c52模块
4、总体连接图
四、心得体会
本次设计是我们遇到过的较大的设计,所以遇到的问题也比较的多,尤其是以前没有接触过如此复杂的硬件电路以及软件编程,在软、硬件设计和调试中遇到了不少的困难,在同学的帮助才逐一克服了难题,学习到了不少的专业知识。
在整个设计过程之前,我已经在网上找了相关方面的资料,万事开始难,一开始不知道从哪里下手。后来慢慢学会分析系统,将系统模块化,各个模块可以在软件或者硬件上实现。在确保各个模块的硬件电路和与之相搭配的程序能够正常工作后在把它们组成一个系统。在今后的日子里,我会进一步加强自己的动手能力,丰富自己的知识面。
总之,这次设计给我的最大感触就是,在以后的学习中勤动脑,多动手。
附录:
1、元件清单
AT89C52 一块 LCD 一个 排阻 3个 DS1302 一个 DS18B20 一个 开关 5个 晶振 2个
瓷片电容 2个, 30PF 电解电容 一个, 33Uf 插针 若干 杜邦线 若干
2、程序
#include
sbit DS1302_CLK = P1^7; //实时时钟时钟线引脚 sbit DS1302_IO = P1^6; //实时时钟数据线引脚 sbit DS1302_RST = P1^5; //实时时钟复位线引脚 sbit wireless_1 = P3^0; sbit wireless_2 = P3^1; sbit wireless_3 = P3^2; sbit wireless_4 = P3^3; sbit ACC0 = ACC^0; sbit ACC7 = ACC^7;
char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数 sbit Set = P2^0; //模式切换键 sbit Up = P2^1; //加法按钮 sbit Down = P2^2; //减法按钮
sbit out = P2^3; //立刻跳出调整模式按钮 sbit DQ = P1^0; //温度传送数据IO口 char done,count,temp,flag,up_flag,down_flag; uchar temp_value; //温度值 uchar TempBuffer[5],week_value[2];
void show_time(); //液晶显示程序
/***********1602液晶显示部分子程序****************/
//Port Definitions********************************************************** sbit LcdRs sbit LcdRw sbit LcdEn
= P2^5; = P2^6; = P2^7;
//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
sfr DBPort = 0x80; //
内
部
等待函数
************************************************************************** unsigned char LCD_Wait(void) {
LcdRs=0;
LcdRw=1; _nop_(); LcdEn=1; _nop_();
LcdEn=0; return DBPort;
}//向LCD写入命令或数据************************************************************ #define LCD_COMMAND #define LCD_DATA
0 // Command
1 // Data
#define LCD_CLEAR_SCREEN #define LCD_HOMING
0x01 // 清屏
0x02 // 光标返回原点
void LCD_Write(bit style, unsigned char input) { }
//设置显示模式************************************************************ #define LCD_SHOW #define LCD_HIDE
#define LCD_CURSOR
0x02 //显示光标
0x00 //无光标
0x04 //显示开
LcdEn=0; LcdRs=style; LcdRw=0;
_nop_();
DBPort=input; _nop_();//注意顺序 LcdEn=1; LcdEn=0; LCD_Wait();
_nop_();//注意顺序 _nop_();
0x00 //显示关
#define LCD_NO_CURSOR
#define LCD_FLASH
0x01 //光标闪动 0x00 //光标不闪动
#define LCD_NO_FLASH
void LCD_SetDisplay(unsigned char DisplayMode) { }
//设置输入模式************************************************************ #define LCD_AC_UP
0x02
0x00 // default
LCD_Write(LCD_COMMAND, 0x08|DisplayMode);
#define LCD_AC_DOWN
#define LCD_MOVE
0x01 // 画面可平移
0x00 //default
#define LCD_NO_MOVE
void LCD_SetInput(unsigned char InputMode) { }
//初始化LCD************************************************************ void LCD_Initial() {
LcdEn=0;
LCD_Write(LCD_COMMAND, 0x04|InputMode);
LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显
示,5*7点阵 标 动 }
//液晶字符输入的位置************************ void GotoXY(unsigned char x, unsigned char y) { }
//将字符输出到液晶显示 void Print(unsigned char *str) {
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x);
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光
if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
while(*str!='\\0') { }
LCD_Write(LCD_DATA,*str); str++;
/***********DS1302时钟部分子程序******************/ typedef struct __SYSTEMTIME__ {
unsigned char Second; unsigned char Minute; unsigned char Hour; unsigned char Week; unsigned char Day; unsigned char Month; unsigned char Year;
unsigned char DateString[11]; unsigned char TimeString[9];
//定义的时间类型
}SYSTEMTIME;
SYSTEMTIME CurrentTime;
#define AM(X) X
#define PM(X) (X+12)
// 转成24小时制
#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间 #define DS1302_MINUTE 0x82 #define DS1302_HOUR #define DS1302_WEEK #define DS1302_DAY
0x84 0x8A
0x86
#define DS1302_MONTH 0x88 #define DS1302_YEAR
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数) {
unsigned char i; ACC = d; for(i=8; i>0; i--) {
0x8C
DS1302_IO = ACC0; //相当于汇编中的 RRC DS1302_CLK = 1; DS1302_CLK = 0; ACC = ACC >> 1; } }
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数) {
unsigned char i; for(i=8; i>0; i--) {
ACC = ACC >>1; ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; }
return(ACC); }
void Write1302(unsigned char ucAddr, unsigned char ucDa) DS1302地址, ucData: 要写的数据
//ucAddr:
//相当于汇编中的 RRC
{
DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令 DS1302InputByte(ucDa); // 写1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; }
unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据 {
unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令 ucData = DS1302OutputByte(); // 读1Byte数据 DS1302_CLK = 1; DS1302_RST = 0; return(ucData);
}
void DS1302_GetTime(SYSTEMTIME *Time) //获取时钟芯片的时钟数据到自定义的结构型数组 {
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
}
void DateToStr(SYSTEMTIME *Time) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]
{ if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22 {
Time->DateString[0] = '2'; Time->DateString[1] = '0';
Time->DateString[2] = Time->Year/10 + '0'; Time->DateString[3] = Time->Year + '0'; } else {
Time->DateString[0] = ' '; Time->DateString[1] = ' '; Time->DateString[2] = ' '; Time->DateString[3] = ' ';
}
Time->DateString[4] = '/'; if(hide_month<2) {
Time->DateString[5] = Time->Month/10 + '0'; Time->DateString[6] = Time->Month + '0'; } else {
Time->DateString[5] = ' '; Time->DateString[6] = ' '; }
Time->DateString[7] = '/'; if(hide_day<2) {
Time->DateString[8] = Time->Day/10 + '0'; Time->DateString[9] = Time->Day + '0'; } else {
Time->DateString[8] = ' '; Time->DateString[9] = ' '; }
if(hide_week<2) {
week_value[0] = Time->Week + '0'; //星期的数据另外放到
week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示 }
void TimeToStr(SYSTEMTIME *Time) //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[]; { if(hide_hour<2) {
Time->TimeString[0] = Time->Hour/10 + '0'; Time->TimeString[1] = Time->Hour + '0'; } else {
Time->TimeString[0] = ' '; Time->TimeString[1] = ' ';
Time->DateString[10] = '\\0'; //字符串末尾加 '\\0' ,判断结束字符 } else {
week_value[0] = ' '; }
week_value[1] = '\\0';
}
Time->TimeString[2] = ':';
if(hide_min<2)
{
Time->TimeString[3] = Time->Minute/10 + '0'; Time->TimeString[4] = Time->Minute + '0'; } else {
Time->TimeString[3] = ' '; Time->TimeString[4] = ' ';
}
Time->TimeString[5] = ':';
if(hide_sec<2) {
Time->TimeString[6] = Time->Second/10 + '0'; Time->TimeString[7] = Time->Second + '0';
} else {
Time->TimeString[6] = ' ';
Time->TimeString[7] = ' ';
} }
void Initial_DS1302(void) //时钟芯片初始化 {
unsigned char Second=Read1302(DS1302_SECOND); if(Second&0x80)
//判断时钟芯片是否关闭
Time->DateString[8] = '\\0';
{
Write1302(0x8e,0x00); //写入允许
Write1302(0x8c,0x07); //以下写入初始化时间 日期:07/07/25.星期: 3. 时间:
23:59:55
Write1302(0x88,0x07); Write1302(0x86,0x25); Write1302(0x8a,0x07); Write1302(0x84,0x23); Write1302(0x82,0x59); Write1302(0x80,0x55);
Write1302(0x8e,0x80); //禁止写入 }
}
/***********ds18b20子程序*************************/
/***********ds18b20延迟子函数(晶振12MHz )*******/
void delay_18B20(unsigned int i) { }
/**********ds18b20初始化函数**********************/
void Init_DS18B20(void) {
unsigned char x=0;
DQ = 1; //DQ复位 delay_18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低 delay_18B20(80); //精确延时 大于 480us DQ = 1; //拉高总线 delay_18B20(14); while(i--);
败 }
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失
delay_18B20(20);
/***********ds18b20读一个字节**************/
unsigned char ReadOneChar(void) {
uchar i=0; uchar dat = 0; for (i=8;i>0;i--) { }
DQ = 0; // 给脉冲信号 dat>>=1;
DQ = 1; // 给脉冲信号 if(DQ) dat|=0x80; delay_18B20(4);
return(dat); }
/*************ds18b20写一个字节****************/
void WriteOneChar(uchar dat) {
unsigned char i=0; for (i=8; i>0; i--) { } }
/**************读取ds18b20当前温度************/
void ReadTemp(void) {
unsigned char a=0; unsigned char b=0;
DQ = 0; DQ = dat&0x01; delay_18B20(5); DQ = 1; dat>>=1;
unsigned char t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作 WriteOneChar(0x44); // 启动温度转换
delay_18B20(100); // this message is wery important
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)就是温度 delay_18B20(100);
a=ReadOneChar(); //读取温度值低位 b=ReadOneChar(); //读取温度值高位
temp_value=b<<4;
temp_value+=(a&0xf0)>>4;
}
void temp_to_str() //温度数据转换成液晶字符显示 {
前两个
TempBuffer[0]=temp_value/10+'0'; //十位 TempBuffer[1]=temp_value+'0'; //个位 TempBuffer[2]=0xdf; //温度符号 TempBuffer[3]='C'; TempBuffer[4]='\\0'; }
void Delay1ms(unsigned int count) { }
/*延时子程序*/ void mdelay(uint delay) {
uint i;
unsigned int i,j; for(i=0;i for(;delay>0;delay--) {for(i=0;i<62;i++) //1ms延时. {;} } } void outkey() //跳出调整模式,返回默认显示 { uchar Second; if(out==0||wireless_1==1) { mdelay(8); count=0; hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_mont h=0,hide_year=0; Second=Read1302(DS1302_SECOND); Write1302(0x8e,0x00); //写入允许 } } //////////////////////////////////////////////////////////////////////////////////////////////////////////// void Upkey()//升序按键 { Up=1; if(Up==0||wireless_2==1) Write1302(0x80,Second&0x7f); Write1302(0x8E,0x80); //禁止写入 done=0; while(out==0); while(wireless_1==1); { mdelay(8); switch(count) {case 1: temp=Read1302(DS1302_SECOND); //读取秒数 //读取分数 读取小时数 temp=temp+1; //秒数加1 up_flag=1; //数据调整后更新标志 if((temp&0x7f)>0x59) //超过59秒,清零 temp=0; break; case 2: temp=Read1302(DS1302_MINUTE); temp=temp+1; //分数加1 up_flag=1; if(temp>0x59) //超过59分,清零 temp=0; break; case 3: temp=Read1302(DS1302_HOUR); // temp=temp+1; //小时数加1 up_flag=1; 读取星期数 取日数 if(temp>0x23) //超过23小时,清零 temp=0; break; case 4: temp=Read1302(DS1302_WEEK); // temp=temp+1; //星期数加1 up_flag=1; if(temp>0x7) temp=1; break; case 5: temp=Read1302(DS1302_DAY); //读 temp=temp+1; //日数加1 up_flag=1; if(temp>0x31) temp=1; break; case 6: temp=Read1302(DS1302_MONTH); //读取月数 temp=temp+1; //月数加1 up_flag=1; if(temp>0x12) 读取年数 } temp=1; break; case 7: temp=Read1302(DS1302_YEAR); temp=temp+1; //年数加1 up_flag=1; if(temp>0x85) temp=0; break; default:break; } while(Up==0); while(wireless_2==1); } // //////////////////////////////////////////////////////////////////////////////////////////////////////////// void Downkey()//降序按键 { Down=1; if(Down==0||wireless_3==1) { mdelay(8); switch(count) {case 1: temp=Read1302(DS1302_SECOND); //读取秒数 temp=temp-1; //秒数减1 down_flag=1; //数据调整后更新标志 if(temp==0x7f) //小于0秒,返回59秒 temp=0x59; break; case 2: temp=Read1302(DS1302_MINUTE); //读取分数 temp=temp-1; //分数减1 down_flag=1; if(temp==-1) temp=0x59; //小于0秒,返回59秒 break; case 3: 读取小时数 读取星期数 temp=Read1302(DS1302_HOUR); // temp=temp-1; //小时数减1 down_flag=1; if(temp==-1) temp=0x23; break; case 4: temp=Read1302(DS1302_WEEK); // temp=temp-1; //星期数减1 down_flag=1; if(temp==0) temp=0x7;; break; case 5: temp=Read1302(DS1302_DAY); //读 取日数 temp=temp-1; //日数减1 down_flag=1; //读取月数 读取年数 if(temp==0) temp=31; break; case 6: temp=Read1302(DS1302_MONTH); temp=temp-1; //月数减1 down_flag=1; if(temp==0) temp=12; break; case 7: temp=Read1302(DS1302_YEAR); temp=temp-1; //年数减1 down_flag=1; if(temp==-1) temp=0x85; break; // } default:break; } while(Down==0); while(wireless_3==1); } void Setkey()//模式选择按键 { Set=1; if(Set==0||wireless_4==1) { mdelay(8); count=count+1; done=1; //Setkey按一次,count就加1 //进入调整模式 while(Set==0); while(wireless_4==1); } } void keydone()//按键功能执行 { uchar Second; if(flag==0) //关闭时钟,停止计时 { Write1302(0x8e,0x00); //写入允许 temp=Read1302(0x80); Write1302(0x80,temp|0x80); Write1302(0x8e,0x80); //禁止写入 flag=1; } Setkey(); switch(count) {case 1:do { //扫描跳出按钮 //count=1,调整秒 //扫描模式切换按键 outkey(); 据 { Upkey(); //扫描加按钮 Downkey(); //扫描减按钮 if(up_flag==1||down_flag==1) //数据更新,重新写入新的数 Write1302(0x8e,0x00); //写入允许 Write1302(0x80,temp|0x80); //写入新的秒数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; } hide_sec++; //位闪计数 if(hide_sec>3) hide_sec=0; show_time(); //液晶显示数据 }while(count==2);break; //count=2,调整分 case 2:do { hide_sec=0; outkey(); Upkey(); Downkey(); if(temp>0x60) temp=0; if(up_flag==1||down_flag==1) { Write1302(0x8e,0x00); //写入允许 Write1302(0x82,temp); //写入新的分数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; } hide_min++; if(hide_min>3) hide_min=0; show_time(); }while(count==3);break; //count=3,调整小时 case 3:do { hide_min=0; outkey(); Upkey(); Downkey(); if(up_flag==1||down_flag==1) { Write1302(0x8e,0x00); //写入允许 Write1302(0x84,temp); //写入新的小时数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; } hide_hour++; if(hide_hour>3) hide_hour=0; show_time(); }while(count==4);break; //count=4,调整星期 case 4:do { hide_hour=0; outkey(); Upkey(); Downkey(); if(up_flag==1||down_flag==1) { Write1302(0x8e,0x00); //写入允许 Write1302(0x8a,temp); //写入新的星期数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; } hide_week++; if(hide_week>3) hide_week=0; show_time(); }while(count==5);break; //count=5,调整日 case 5:do { hide_week=0; outkey(); Upkey(); Downkey(); if(up_flag==1||down_flag==1) { Write1302(0x8e,0x00); //写入允许 Write1302(0x86,temp); //写入新的日数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; } hide_day++; if(hide_day>3) hide_day=0; show_time(); }while(count==6);break; //count=6,调整月 case 6:do { hide_day=0; outkey(); Upkey(); Downkey(); if(up_flag==1||down_flag==1) { Write1302(0x8e,0x00); //写入允许 Write1302(0x88,temp); //写入新的月数 Write1302(0x8e,0x80); //禁止写入 up_flag=0; down_flag=0; } hide_month++; if(hide_month>3) hide_month=0; show_time(); }while(count==7);break; //count=7,调整年 case 7:do { hide_month=0; outkey();
正在阅读:
基于利用时钟芯片DS1302实现万年历,1602LCD显示电子表 - 图文06-06
主动脉夹层16例临床分析01-04
询价单格式报价单格式04-06
专业知识 - 图文11-09
3000万只肉鸭屠宰加工项目01-27
SSAT类比题反义词总结06-22
赤霞珠葡萄品种介绍以及食物配对10-19
高力集团内部刊物管理制度01-18
借款合同,借款合同范本08-01
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 电子表
- 万年历
- 时钟
- 芯片
- 基于
- 利用
- 1602LCD
- 实现
- 图文
- 显示
- DS1302
- 流体输配管网
- labviEW 实验二(1)
- 陕西省澄城县寺前中学高三数学推中试题(2)(无答案) 新人教A版
- 王熙凤与探春管理模式的对比分析
- 统计学试题
- 七年级数学上册 2.6有理数的加减混合运算导学案3(新版)北师大
- 路桥施工中体外索加固的方法探讨
- 若羌中学课堂模式说明
- 初中学校教学工作总结
- 预应力空心板预制施工方案
- 流量红利时代内容运营为王-文档资料
- 发动机进气压力的测试与平衡
- 三年级下册语文单元测试题-第4单元丨语文A版含答案
- 高毒物品作业岗位职业病规范 - 图文
- Linux设备驱动之pci设备的枚举
- 完整的工程结算单书(市政)
- 执行依据的审查与处理
- 低空观光旅游直升机如何选择!
- 天宝TSC3操作步骤
- 选美大赛分赛区指导手册