基于DS1302和LCD1602的可调数字钟

合集下载

DS1302与液晶1602简单时钟

DS1302与液晶1602简单时钟

《单片机原理实验》考试报告题目:DS1302和1602时钟姓名:学号:班级:专业:电子信息工程指导老师:提交时间:DS1302和1602时钟***(**学院电子信息工程 ***班 **********)摘要:关键词:DS1302 ,液晶1602,89C51。

1.引言我们在日常生活中常常用到时钟来记录时间,有时候还不能准确的记录下时间,这就要用到芯片DS1302了。

时间还远远不够,因为人性化的设计自然是要清楚的显示年、月、日、星期、时间。

而在此用到的DS1302非常好的与时间进行同步,并且在掉电时不会对时间有影响,较理的考虑到了人们的思维模式,从而简单的控制了时钟,结合了常理的理论。

2.原理DS1302引脚X1 X2 32.768KHz 晶振管脚GND 地CE 复位脚I/O 数据输入/输出引脚SCLK 串行时钟Vcc1,Vcc2 电源供电管脚各引脚的功能为:Vcc1:主电源;Vcc2:备份电源。

当Vcc2>Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电。

SCLK:串行时钟,输入,控制数据的输入与输出;I/O:三线接口时的双向数据线;CE:输入信号,在读、写数据期间,必须为高。

该引脚有两个功能:第一,CE开始控制字访问移位寄存器的控制逻辑;其次,CE提供结束单字节或多字节数据传输的方法。

DS1302控制字:控制字的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入到DS1302中。

位6:如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1(A4~A0):指示操作单元的地址;位0(最低有效位):如为0,表示要进行写操作,为1表示进行读操作。

控制字总是从最低位开始输出。

在控制字指令输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从最低位(0位)开始。

同样,在紧跟8位的控制字指令后的下一个SCLK脉冲的下降沿,读出DS1302的数据,读出的数据也是从最低位到最高位。

用DS1302+LCD1602制作的时钟

用DS1302+LCD1602制作的时钟
void Read_RTC(void) //读取 日历
{
uchar i,*p;
p = RTC_RADD; //地址传递
for(i = 0 ; i < 7 ; i++) //分7次读取 秒分时日月周年
{
SJ[i] = Read_Ds1302(*p);
p++;
}
}
/*************************************************/
}
/*****************************************************/
/****LCD定位******************************************/
void LOCATE(uchar H , uchar L)
{
if(H == 1) //如果是第一行
{
LCD_RS = rs; //写指令/数据选择:低电平写指令,高电平写数据
LCD_RW = 0; //读写选择:低电平写,高电平读
LCD_E = 0; //关使能
LCD_DAT = c_d; //把指令/数据写入P1口
delay(5); //延时5ms
{
if(SDA)
temp |= 0x80; //每次传输低字节
SCK = 0;
temp>>=1; //右移一位
_nop_();
_nop_();
_nop_();
SCK = 1;
}
RST = 0;
_nop_(); //以下为DS1302复位的稳定时间

基于LCD1602和DS1302的时间显示程序

基于LCD1602和DS1302的时间显示程序

/*========================================================== ==使用1602液晶显示DS1302+S51时钟+温度显示zhaojun 2007/06/29=========================================================== ===声明:1. 1602驱动程序照搬明皓的,非常好用2. DS1302驱动程序是参考网友修改而来NS1602R(16*2)模拟口线接线方式连接线图:---------------------------------------------------| LCM-----51 | LCM-----51|LCM------51 || ----------------------------------------------- || DB0-----P0.0 | DB4-----P0.4 | RS-------P2.0 || DB1-----P0.1 | DB5-----P0.5 | RW-------P2.1 || DB2-----P0.2 | DB6-----P0.6 | E--------P2.2 || DB3-----P0.3 | DB7-----P0.7 | VLCD接1K电阻到GND |---------------------------------------------------DS1302 接线图Vcc2 CLK I/O /RST| | | |---------------| 8 7 6 5 || DS1302 || || 1 2 3 4 |---------------| | | |VCC1 GND1. 脚接+5V 2,3. 脚32768HZ晶振4. 脚接地5. 脚接S51的P1.2 6. 脚接S51的P1.1 7. 接S51的P1.08. 脚接后备电源,可以接老计算机主板上的3.6V电池,也可以通过二级管隔离接一个大容量电解电容电压在2.5V以上即可维持按键说明:1. 共三个键,低电平有效2. P1.4 和P1.5 同时按:初始化3. P1.6 端口按键:选择要调整的项目4. P1.5 端口按键:增加;P1.4端口按键:减少[注:AT89S51使用12M晶振]源代码:=================定义与申明=========================================================== ==*/#include "regx51.h"#include "string.h"#include "intrins.h"#define uchar unsigned char#define uint unsigned inttypedef unsigned char byte;typedef unsigned int word;//*********** 1602引脚定义引脚#define LCM_RS P2_0 // 数据/命令选择信号#define LCM_RW P2_1 // 读/写选择信号#define LCM_E P2_2 // 使能信号//*********** DS1302 时间显示定义部分sbit T_CLK=P1^0; //串行时钟输入sbit T_IO =P1^1; //串行数据端口sbit T_RST=P1^2; //复位端口//*********** 18B20温度显示定义部分sbit DQ=P3^3; //18B20 接P33口sbit ACC0=ACC^0;sbit ACC7=ACC^7;#define LCM_Data P0 //显示数据端口#define Busy 0x80 //用于检测LCM状态字中的Busy标识uchar id,timecount; //全局变量bit flag,sflag; //flag是时钟冒号闪烁标志,sflag是温度负号显示标志bit sec,min,hour,year,mon,day,weekk; //闪烁标志位//*********************函数申明void Disp_line1(void); // 显示屏幕第一行void Disp_line2(void); // 显示屏幕第二行void id_case1_key(); // id为1时的下一级选择void Set(uchar,uchar); // 根据选择调整相应项目void RTInputByte(uchar); /* 输入1Byte */uchar RTOutputByte(void); /* 输出1Byte */void W1302(uchar, uchar); // 向DS1302写入一个字节uchar R1302(uchar); // 从DS1302读出一个字节void Set1302(uchar * ); // 设置时间//******* 1602LCD驱动********************************************************** void WriteDataLCM(uchar WDLCM); //写数据void WriteCommandLCM(uchar WCLCM,BuysC); //写指令uchar ReadStatusLCM(void); //读状态void LCMInit(void); //LCM初始化void DisplayOneChar(uchar X, uchar Y, uchar DData); //按指定位置显示一个字符void DisplayListChar(uchar X, uchar Y, uchar code *DData); //按指定位置显示一串字符void Delay5Ms(void); //5ms延时void Delay400Ms(void); //400ms延时Read_Temperature(char,char);//温度显示void mychar(void); //显示自定义字符void adjust_res(char res); //res 分别等于0x1f, 0x3f, 0x5f 温度读数分辨率分别对应// 0.5, 0.25, 0.125//初始化后设置为:07年07月04日星期3 12点00分00秒// 12:00:00 XX. C// 07/07/04 Week.3unsigned char inittime[7]={0x00,0x00,0x12,0x04,0x07,0x03,0x07};// 秒分钟小时日月星期年uchar code week[]={"Week."};//星期显示//========================= 主函数======================================================= /*****************************************************函数名:main()功能:主函数说明:入口参数:无返回值:无*****************************************************/void main(void){Delay400Ms(); //启动等待,等LCM讲入工作状态LCMInit(); //LCM初始化Delay5Ms(); //延时片刻(可不要)mychar(); //显示自定义字符TMOD=0x01; //选择定时模式TH0=(65535-50000)/256;//取定时初值TL0=(65535-50000)%256;EA=1; //开中断TR0=1;ET0=1;W1302(0x90,0xa5); //打开充电二级管一个二级管串联一个2K电阻W1302(0x8e,0x80); //写保护,禁止写操作adjust_res(0x5f); //调整18B20的分辨率0x1f:0.5; 0x3f:0.25; 0x5f:0.125 while(1){if ((P1_4|P1_5)==0) // 初始化同时按下P1_4、P1_5{Delay5Ms(); // 适当延时,消除抖动if ((P1_4|P1_5)==0) Set1302(inittime); // 显示初始值}if (P1_6==0) // 设置和选择项目键{Delay5Ms(); // 适当延时,消除抖动if(P1_6==0){id++;if(id>7) id=0;} // 7个可调节项目循环调节while(P1_6==0);}switch(id) // 跳转到对应的项目进行设置{case 0:sec=0;Disp_line1(); Disp_line2();break;case 1: //调节年year=1;//设置年闪烁标志位Disp_line1(); Disp_line2();id_case1_key();break;case 2: //调节月year=0;mon=1;//设置月闪烁标志位Disp_line1(); Disp_line2();id_case1_key();break;case 3: //调节日mon=0;day=1;//设置日闪烁标志位Disp_line1(); Disp_line2();id_case1_key();break;case 4: //调节星期day=0;weekk=1;//设置星期闪烁标志位Disp_line1(); Disp_line2();id_case1_key();break;case 5: //调节小时weekk=0;hour=1;//设置小时闪烁标志位Disp_line1(); Disp_line2();id_case1_key();break;case 6: //调节分钟hour=0;min=1;//设置分钟闪烁标志位Disp_line1(); Disp_line2();id_case1_key();break;case 7: //调节秒min=0;sec=1;//设置秒钟闪烁标志位Disp_line1(); Disp_line2();id_case1_key();break;}}}//================================== 定时中断============================================= /*****************************************************函数名:void t0()功能:时间工作时,冒号闪烁说明:T0中断入口,方式1入口参数:无返回值:无*****************************************************/void t0(void) interrupt 1 using 0{TH0=(65535-50000)/256; //取50ms定时初值TL0=(65535-50000)%256;timecount++;if(timecount>9){timecount=0; //计时到,从先开始flag=~flag; //标志位取反}}//==================================== 项目设置=========================================== /*****************************************************函数名:void id_case1_key()功能:项目设置加减控制说明:P1.5和P1.4 <==> +和-入口参数:无返回值:无*****************************************************/ //id为1时的下一级选择void id_case1_key(){if (P1_5==0) //P1_5有按下,则数值增加(+){Delay5Ms(); //适当延时,消除抖动if(P1_5==0) Set(id,0); //根据选择调整相应项目if(id!=7) while(P1_5==0);}if (P1_4==0) //P1_4有按下,则数值减少(-){Delay5Ms(); //适当延时,消除抖动if(P1_4==0) Set(id,1); //根据选择调整相应项目if(id!=7) while(P1_4==0);}}/***************************************************** 函数名:void Set()功能:项目设置说明:sel_1=0时,数值加;sel_1=1时,数值减入口参数:sel和sel_1返回值:无*****************************************************/ //根据选择调整相应项目并写入DS1302void Set(uchar sel,uchar sel_1){signed char address,item;signed char max,mini;//偶数指令是写,奇数指令是读//最大值与最小值限定if(sel==7) {address=0x80; max=00;mini=0;} //秒if(sel==6) {address=0x82; max=59;mini=0;} //分钟if(sel==5) {address=0x84; max=23;mini=0;} //小时if(sel==3) {address=0x86; max=31;mini=1;} //日if(sel==2) {address=0x88; max=12;mini=1;} //月if(sel==1) {address=0x8c; max=99;mini=0;} //年if(sel==4) {address=0x8a; max=07;mini=1;} //星期//先从1302中读出数据,把数据转换成十进制进行加减设置;后从先转换回来写入1302中item=R1302(address+1)/16*10+R1302(address+1)%16;//从1302中读出1字节,再转换成十进制if (sel_1==0) item++; else item--; //sel_1=0则加,sel_1=1则减if(item>max) item=mini; //大于最大值,则赋最小值(循环)if(item<mini) item=max; //小于最小值,则赋最大值(循环)W1302(0x8e,0x00); //允许写操作W1302(address,item/10*16+item%10);//把调节好的十进制数据转换成十六进制后写入1302中W1302(0x8e,0x80); //写保护,禁止写操作}//========================================================== =============================/*****************************************************函数名:void Disp_line1()功能:显示时间和温度(XX:XX:XX XX.X C)说明:第一行显示数据处理入口参数:无返回值:无*****************************************************///屏幕显示第一行: 时间和温度显示void Disp_line1(void){Read_Temperature(10,0); //温度显示//冒号闪烁if(flag==0){DisplayOneChar(3,0,0x3a); DisplayOneChar(6,0,0x3a);} else{DisplayOneChar(3,0,0x20); DisplayOneChar(6,0,0x20);}if(sec==1) //秒闪烁标志位{if(flag==1){DisplayOneChar(7,0,R1302(0x81)/16+0x30); //显示秒十位DisplayOneChar(8,0,R1302(0x81)%16+0x30); //显示秒个位}else{DisplayOneChar(7,0,0x20); //显示秒十位DisplayOneChar(8,0,0x20); //显示秒个位}}else{DisplayOneChar(7,0,R1302(0x81)/16+0x30); //显示秒十位DisplayOneChar(8,0,R1302(0x81)%16+0x30); //显示秒个位}if(min==1) //分钟闪烁标志位{if(flag==1){DisplayOneChar(4,0,R1302(0x83)/16+0x30); //显示分钟十位DisplayOneChar(5,0,R1302(0x83)%16+0x30); //显示分钟个位}else{DisplayOneChar(4,0,0x20); //显示分钟十位DisplayOneChar(5,0,0x20); //显示分钟个位}}else{DisplayOneChar(4,0,R1302(0x83)/16+0x30); //显示分钟十位DisplayOneChar(5,0,R1302(0x83)%16+0x30); //显示分钟个位}if(hour==1) //小时闪烁标志位{if(flag==1){DisplayOneChar(1,0,R1302(0x85)/16+0x30);//显示小时十位DisplayOneChar(2,0,R1302(0x85)%16+0x30);//显示小时个位}else{DisplayOneChar(1,0,0x20); //显示小时十位DisplayOneChar(2,0,0x20); //显示小时个位}}else{DisplayOneChar(1,0,R1302(0x85)/16+0x30);//显示小时十位DisplayOneChar(2,0,R1302(0x85)%16+0x30);//显示小时个位}}/*****************************************************函数名:void Disp_line2()功能:显示日期和星期(XX/XX/XX Week.X)说明:第二行显示数据处理入口参数:无返回值:无*****************************************************/// 屏幕显示第二行日期和星期void Disp_line2(void){DisplayOneChar(3,1,0x2f); //显示固定字符DisplayOneChar(6,1,0x2f);DisplayListChar(10,1,week);if(year==1) //年闪烁标志位{if(flag==1){DisplayOneChar(1,1,R1302(0x8d)/16+0x30);//显示年十位DisplayOneChar(2,1,R1302(0x8d)%16+0x30);//显示年个位}else{DisplayOneChar(1,1,0x20); //显示年十位DisplayOneChar(2,1,0x20); //显示年个位}}else{DisplayOneChar(1,1,R1302(0x8d)/16+0x30);//显示年十位DisplayOneChar(2,1,R1302(0x8d)%16+0x30);//显示年个位}if(mon==1) //月闪烁标志位{if(flag==1){DisplayOneChar(4,1,R1302(0x89)/16+0x30);//显示月十位DisplayOneChar(5,1,R1302(0x89)%16+0x30);//显示月个位}else{DisplayOneChar(4,1,0x20); //显示月十位DisplayOneChar(5,1,0x20); //显示月个位}}{DisplayOneChar(4,1,R1302(0x89)/16+0x30);//显示月十位DisplayOneChar(5,1,R1302(0x89)%16+0x30);//显示月个位}if(day==1) //日闪烁标志位{if(flag==1){DisplayOneChar(7,1,R1302(0x87)/16+0x30);//显示日十位DisplayOneChar(8,1,R1302(0x87)%16+0x30);//显示日个位}else{DisplayOneChar(7,1,0x20); //显示日十位DisplayOneChar(8,1,0x20); //显示日个位}}else{DisplayOneChar(7,1,R1302(0x87)/16+0x30);//显示日十位DisplayOneChar(8,1,R1302(0x87)%16+0x30);//显示日个位}if(weekk==1) //星期闪烁标志位{if(flag==1){DisplayOneChar(15,1,R1302(0x8b)%16+0x30);//显示星期}else{DisplayOneChar(15,1,0x20); //显示星期}}{DisplayOneChar(15,1,R1302(0x8b)%16+0x30);//显示星期}}//================================ LCM1602控制部分=======================================/*****************************************************函数名:void WriteDataLCM()功能:向LCM1602中写入数据说明:将形参WDLCM中的数据写入LCM中入口参数:WDLCM返回值:无*****************************************************///写数据void WriteDataLCM(uchar WDLCM){ReadStatusLCM(); //检测忙LCM_Data = WDLCM;//写入数据到LCMLCM_RS = 1;LCM_RW = 0;LCM_E = 0; //若晶振速度太高可以在这后加小的延时LCM_E = 0; //延时LCM_E = 1;}/*****************************************************函数名:void WriteCommandLCM()功能:向LCM1602中写入指令说明:向LCM中写入指令;如果BuysC=0时,忽略忙检测,如果BuysC=1时,不忽略忙检测入口参数:WCLCM,BuysC返回值:无*****************************************************///写指令void WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCM(); //根据需要检测忙LCM_Data = WCLCM; //写入指令LCM_RS = 0;LCM_RW = 0;LCM_E = 0;LCM_E = 0;LCM_E = 1;}/*****************************************************函数名:uchar ReadStatusLCM()功能:读状态说明:判断LCM的工作状态;也可以不用此函数,用一段延时程序代替入口参数:无返回值:LCM_Data*****************************************************///读状态uchar ReadStatusLCM(void){LCM_Data = 0xFF; //LCM数据口先置1LCM_RS = 0;LCM_RW = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;while (LCM_Data & Busy); //检测忙信号.如果忙,则不执行return(LCM_Data);//不忙返回读取数据}/*****************************************************函数名:void LCMInit()功能:初始化LCM1602说明:LCM在工作前先要对显示屏初始化,否则模块无法正常工作入口参数:无返回值:五*****************************************************///LCM初始化void LCMInit(void){LCM_Data = 0;WriteCommandLCM(0x38,0); // 三次显示模式设置,不检测忙信号Delay5Ms();WriteCommandLCM(0x38,0); // 0x38指令表示:8位数据显示模式,俩行多显示Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,1); // 显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); // 关闭显示WriteCommandLCM(0x01,1); // 显示清屏WriteCommandLCM(0x06,1); // 显示光标移动设置WriteCommandLCM(0x0C,1); // 显示开及光标设置}/*****************************************************函数名:void DisplayOneChar()功能:按指定坐标中写入数据说明:X-横坐标,Y-纵坐标入口参数:X,Y,DData返回值:*****************************************************///按指定位置显示一个字符void DisplayOneChar(uchar X, uchar Y, uchar DData){Y &= 0x01;X &= 0x0F; //限制X不能大于15,Y不能大于1if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;X |= 0x80; //算出指令码WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码WriteDataLCM(DData);}/*****************************************************函数名:void DisplayListChar()功能:向指定坐标中写入字符串说明:X-横坐标,Y-纵坐标入口参数:X,Y,*DData返回值:*****************************************************///按指定位置显示一串字符***原来的遇到空格0x20就不显示***void DisplayListChar(uchar X, uchar Y, uchar code *DData){uchar ListLength,j;ListLength = strlen(DData);//strlen:读取字符串的长度Y &= 0x1;X &= 0xF; //限制X不能大于15,Y不能大于1if (X <= 0xF) //X坐标应小于0xF{for(j=0;j<ListLength;j++){DisplayOneChar(X, Y, DData[j]); //显示单个字符X++;//横坐标加1,纵坐标不变}}}//=================================== 自定义字符==========================================/*****************************************************函数名:void mychar()功能:自定义字符--CGRAM说明:LCM1602字符库中没有温度符号,自定义温度符号入口参数:无返回值:无定义形式:1602中定义CGRAM的形式如下:---------------------------------------------------------------------------| CGRAM地址设置| 自定义的代码|| DB7 DB6 | DB5 DB4 DB3 | DB2 DB1 DB0 | DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 || 0 1 | 0 0 0 | X X X | 0 0 0 0 * 0 0 0 || 0 1 | 0 0 1 | X X X | 0 0 0 0 * 0 0 1 || ... | ... | ... | ... ... || 0 1 | 1 1 0 | X X X | 0 0 0 0 * 1 1 0 || 0 1 | 1 1 1 | X X X | 0 0 0 0 * 1 1 1 |---------------------------------------------------------------------------1. 1602共能定义8个5x8字符;2. CGRAM地址设置: X X X--DB2 DB1 DB0对应写入地址,1~8行;DB5 DB4 DB3对应自定义字符代码;DB7 DB6为指令码,不可变.3. 自定义的代码: 高4位DB7 DB6 DB5 DB4为0000时它的低3位DB2 DB1 DB0对应于第1-8个,DB3为无关项。

基于51单片机DS1302LCD1602数字时钟显示

基于51单片机DS1302LCD1602数字时钟显示
#include <reg51.h>
#include <intrins.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]="I LIKE MCU!";
sbit RS=P2^0;
dispaly_string(0x00,lcd_buffer1);
dispaly_string(0x40,lcd_buffer2);
}
}
delay(5);
}
void write_a_byte_tods1302(uchar x)
{
uchar i;
for(i=0;i<8;i++)
{
IO=x&0x01;
sclk=1;
sclk=0;
x=x>>1;
}
}
uchar get_a_byte_fromds1302()
{
uchar i,b=0x00;
for(i=0;i<8;i++)
uchar lcd_buffer2[]={"TIME 00:00:00 "};
uchar datetime[7];
void delay(uchar ms)
{
uchar i;
while(ms--)
for(i=0;i<120;i++);
}
//忙检测
uchar busy()
{
uchar test;
RW=1;
{

基于DS1302和LCD1602的数字电子钟设计

基于DS1302和LCD1602的数字电子钟设计

关键词:单片机;DS1302;LCD1602;数字时钟
1
Abstract
This paper mainly introduces the hardware and software design of digital electronic clock which is made up of the AT89S52 MCU ,DS1302 clock chip and LCD1602 module .It can accurately adjust the information of the year,month,day,hour,minutes and seconds.This electronic clock has the characteristics of working accurately,keeping the time date when system losing power, and low power consumptions. Keywords: singlechip;DS1302;LCD1602;Digital clock
图(3)系统硬件连接原理图
8
三.系统软Leabharlann 设计[3]软件是单片机应用系统的灵魂,是整个系统的核心部分。如果把硬件比作人的手臂那么 软件就是人的大脑,手臂的一切动作的执行都要受控于大脑。同样,对 DS1302 时钟芯片和 1602 液晶显示模块的操作都是通过相应的软件程序来控制的。 3.1 DS1302 读写程序 任何一款数字芯片都有自己的操作时序,只有完全按照芯片厂商提供的操作时序进行编 程才可以使其正常工作。DS1302 的读写时序如图(4)所示。 按照此时序图编制的写操作程序如下:
2
一.引言
1.DS1302 时钟芯片简介[1]

以DS1302实时时钟芯片和液晶显示屏CD1602为基础设计的电子钟

以DS1302实时时钟芯片和液晶显示屏CD1602为基础设计的电子钟

以DS1302实时时钟芯片和液晶显示屏CD1602实验目的:1、能够以DS1302实时时钟芯片和液晶显示屏CD1602为基础设计一款电子钟2、熟悉DS1302芯片的工作过程3、熟悉CD1602芯片的工作过程4、能够进行必要的扩展,如用第三DS18B20新品进行温度采集和显示5、熟悉把握51的c程序的编写6、把握用Proteus进行系统设计仿真验证实验仪器、外表名目1、DS1302实时时钟芯片1片2、LCD1602液晶显示屏1个,3、80C52芯片1片5、DS18B20芯片一片6、晶振、电容、电阻、开关各若干等7、proteus仿真软件8、Keil C51、PC机实验设计任务以DS1302实时时钟芯片和液晶显示屏LCD1602为基础设计一个电子钟,要求:时刻和日期可调整,按键采纳3个按键;至少在Proteus上调试通过。

扩展:闹钟和重要日期提醒功能(增加蜂鸣器),闹铃音乐功能实验步骤1、打开Keil软件,新建一个工程文件,选择好芯片,并记得在“Opti ons for Target 1”的Output选项中,将Create HEX Fil选项勾起来。

2、将编写的程序储存成“.C”的形式3、编译储存好的C 文件,并按照提示修改程序中的错误,直到编译成功为止4、打开proteus 软件,画出实验电路图5、在89C52中,载入原先已生成的HEX 文档6、按下运行键,对Proteus 进行软件仿真,观看运行结果 原理、结果及分析一、设计方案原理与设计特点分析 电子钟总的设计模块:各个模块电路原理分析: 1、DS1302时钟采集模块: 1.1电路原理图:1.2 DS1302分析:第一DS1302是DALLAS 公司推出的涓流充电时钟芯片。

内含有一个实时时钟/日历和31字节静态RAM 通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作。

DS1302芯片广脚介绍:X1、X2为32.768KHz 晶振管脚。

基于51单片机DS1302LCD1602数字时钟显示

基于51单片机DS1302LCD1602数字时钟显示
dispaly_string(0x00,lcd_buffer1);
dispaly_string(0x40,lcd_buffer2);
}
}
sbit RW=P2^1;
sbit EN=P2^2;
sbit IO=P1^0;
sbit sclk=P1^1;
sbit rst=P1^2;
uchar *week[]={"SUN","****","MON","TUS","WEN","THU","FRI","SAT"};
uchar lcd_buffer1[]={"DATE 00-00-00 "};
delay(5);
}
void write_a_byte_tods1302(uchar x)
{
uchar i;
for(i=0;i<8;i++)
{
IO=x&0x01;
sclk=1;
sclk=0;
x=x>>1;
}
}
uchar get_a_byte_fromds1302()
{
uchar i,b=0x00;
for(i=0;i<8;i++)
a[1]=d%10+'0';
}
void main()
{
init();
while(1)
{
gettime();
zhuanhuan(datetime[6],lcd_buffer1+5);
zhuanhuan(datetime[4],lcd_buffer1+8);

用DS1302与LCD1602设计可调数字万年历课程设计

用DS1302与LCD1602设计可调数字万年历课程设计

数字开发与实践课程设计题目:用DS1302与LCD1602设计可调式电子日历时钟班级:姓名:学号:学院:年月日用DS1302与LCD1602设计的可调式电子日历时钟一、总体设计1.1、设计目的为巩固所学的单片机知识,把所学理论运用到实践中,用LCD1602与DS1302 设计可调式电子日历时钟。

1.2、设计要求(1)显示:年、月、日、时、分、秒和星期;(2)设置年、月、日、时、分、秒和星期的初始状态;(3)能够用4个按键调整日历时钟的年、月、日、时、分、秒和星期;完成可调式电子日历时钟的硬件和软件的设计,包括单片机的相关内容;日历时钟模块的设计,液晶显示模块的设计,按键模块的设计。

控制程序的编写等。

备注:本程序另外添加了每到上午8:10和下午2:10的闹钟提醒功能。

1.3、系统基本方案选择和论证1.3.1、单片机芯片的选择方案方案一:采用89C51芯片作为硬件核心,采用Flash ROM,内部具有4KB ROM 存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容。

方案二:采用STC12C5A60S2系列单片机是宏晶科技生产的单时钟/机器周期(1T)的单片机,是高速/低功耗/超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。

内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换(250K/S),针对电机控制,强干扰场合。

但造价较高。

1.3.2 、显示模块选择方案和论证:方案一:采用点阵式数码管显示,点阵式数码管是由八行八列的发光二极管组成,对于显示文字比较适合,如采用显示数字显得太浪费,且价格也相对较高。

所以不用此种作为显示。

方案二:采用LED数码管动态扫描,虽然LED数码管价格适中,但要显示多个数字所需要的个数偏多,功耗较大,显示出来的只是拼音,而不是汉字。

所以也不用此种作为显示。

方案三:采用LCD液晶显示屏,液晶显示屏的显示功能强大,可显示大量字符,且视觉效果较好,外形美观。

DS1302+LCD1602时钟

DS1302+LCD1602时钟

DS1302+LCD1602时钟1.实验目的效果:做一个不怕掉电的LCD显示时钟。

学习DS1302时钟芯片的读写,加强字符型液晶LCD1602的应用。

在LCD屏上显示格式:1)按一下SW1进入时间调整,关标会闪烁2)按一下SW2光标会在年份上闪烁,表明可以对年份进行调整,接着按SW3年份将加一,按SW4年份将减一;2)再按一下SW2,光标闪烁移到月份上,同样按SW3月份加一,按SW4月份减一;3)再按一下SW2,光标有下移到星期上,同样按SW3星期加一,按SW4星期减一;4)同样的道理可以调整时,分,秒。

5)调整完毕按一下SW1,光标闪烁退出,时间调整结束。

DS1302:1)读写时序:2)DS1302相关寄存器:(详细DS1302资料请查看ds1302.pdf文档)2.原理图:DS1302连接原理图LCD1602连接原理图3.实验板上操作:1)用三个短路冒将SCLK-P3.5,I/O-P3.6,CE-P3.7短接起来。

2)将板上的相应拨码开关拨到拨到ON上。

(建议把原来做过数码管显示的那个拨码开关全部拨到OFF那边)3)把LCD1602液晶插到实验板上的LCD1602液晶插槽上。

(提示:程序烧进单片机后,液晶上没有显示,请调节板子上左上角那个电位器)4)按一下SW1进入时间调整,关标会闪烁按一下SW2光标会在年份上闪烁,表明可以对年份进行调整,接着按SW3年份将加一,按SW4年份将减一;再按一下SW2,光标闪烁移到月份上,同样按SW3月份加一,按SW4月份减一;再按一下SW2,光标有下移到星期上,同样按SW3星期加一,按SW4星期减一;同样的道理可以调整时,分,秒。

调整完毕按一下SW1,光标闪烁退出,时间调整结束。

4.实物连接图如下:5.C语言程序:#include "A T89X51.h"#include "intrins.h"#define HIGH 1#define LOW 0#define TRUE 1#define ZERO 0#define MSB 0x80#define LSB 0x01// ds1302 PreDefinition#define DS1302_WP0x8E#define DS1302_RESET RST=LOW;SCL=LOW;RST=HIGH#define DS1302_WP_ENABLE Write_Ds1302(DS1302_WP,0X00)#define DS1302_WP_DISENABLE Write_Ds1302(DS1302_WP,0x00) #define LCDPORT P0sbit SCL = P3^5;// DS1302 Serial-Clock Input pin 5sbit SDA = P3^6;// DS1302 Serial-Data Input pin 6sbit RST = P3^7;// DS1302 Chip-Seclet Input pin 7sbit RS=P1^0;sbit RW=P1^1;sbit EN=P1^2;code unsigned char set_rtc_code[7]={0x07,0x03,0x29,0x02,0x21,0x07,0x40};code unsigned char write_rtc_address[7]={0x8c,0x88,0x86,0x8a,0x84,0x82,0x80};code unsigned char read_rtc_address[7]={0x8d,0x89,0x87,0x8b,0x85,0x83,0x81}; unsigned char read_rtc_code[7]; //DS1302读出信息(年份,星期,时间)暂存数组,/********1ms延时子程序***********/delay_nms(unsigned int n){unsigned int i;unsigned char j;for(i=0;i<n;i++)for(j=0;j<120;j++); //空操作}//*************LCD1602驱动程序***************************//void lcd_delay(unsigned char delaytime){while(delaytime)delaytime--;}void write_lcd_command(unsigned char write_command){lcd_delay(40);RS=0;RW=0;LCDPORT=write_command;EN=1;EN=0;}void write_lcd_data(unsigned char write_data){lcd_delay(40);RS=1;RW=0;LCDPORT=write_data;EN=1;EN=0;}void LCD_write_char( unsigned x,unsigned char y,unsigned char dat) //x表示行,y表示该行的位置(也就是列){//LCD_set_xy( x, y );switch(x){case 0:write_lcd_command(0x80+y);break;case 1:write_lcd_command(0xc0+y);break;}// LCD_en_dat(dat);write_lcd_data(dat|0x30); //dat或上0x30,就时把数字0123456789转换成ASIIC码}void lcd_displaystr(unsigned char x,unsigned char y,unsigned char code *str){switch(x){case 0:write_lcd_command(0x80+y);break;case 1:write_lcd_command(0xc0+y);break;}while (*str){write_lcd_data(*str);str++;}}void initial_lcd1602(void) //初始化LCD1602{unsigned char i;EN=0;for(i=200;i>0;i--)lcd_delay(248);write_lcd_command(0x38);for(i=4;i>0;i--)lcd_delay(248);write_lcd_command(0x38);for(i=4;i>0;i--)lcd_delay(248);write_lcd_command(0x0f);for(i=4;i>0;i--)lcd_delay(248);write_lcd_command(0x06);for(i=4;i>0;i--)lcd_delay(248);write_lcd_command(0x01);for(i=4;i>0;i--)lcd_delay(248);}//********************lcd1602驱动程序到此完********************/////////////////////////////////////////////////////////////////////////**************ds1302读写程序*************************//void Write_Ds1302_Byte(unsigned char temp) //写一个字节{unsigned char i;for (i=0;i<8;i++){SCL=LOW;SDA=temp&LSB;temp>>=1;SCL=HIGH;}}/****************************************************************************/ void Write_Ds1302( unsigned char address,unsigned char dat ) //写ds1302{DS1302_RESET;Write_Ds1302_Byte(address);Write_Ds1302_Byte(dat);RST=LOW;}/****************************************************************************/ unsigned char Read_Ds1302 ( unsigned char address ) //读ds1302{unsigned char i,temp=0x00,temp_temp;DS1302_RESET;Write_Ds1302_Byte(address);for (i=0;i<8;i++){if(SDA)temp|=0x80;SCL=LOW;temp>>=1;SCL=HIGH;}RST=LOW;temp_temp=temp/16;temp=temp%16;temp=temp+temp_temp*10;return (temp);}/****************************************************************************/ void Read_RTC(void) //读出DS1302里的相关信息,存放在read_rtd_code[]数组中{unsigned char i,*p;p=read_rtc_address;for(i=0;i<7;i++){read_rtc_code[i]=Read_Ds1302(*p);p++;}}/***********************************************************************/void Set_RTC(void) //初始化设置DS1302{unsigned char i,*p;p=write_rtc_address;for(i=0;i<7;i++){Write_Ds1302(*p,set_rtc_code[i]);p++;}}/******************************************************/void initial_ds1302(void) //初始化ds1302{DS1302_WP_ENABLE;Set_RTC();}/**************ds1302读写程序到此完************************//////////////////////////////////////////////////////系统初始化void system_initial(void){initial_ds1302();initial_lcd1602();}/****************************************************************************/void main(void){unsigned char count,staus;system_initial();//输出显示lcd_displaystr(0,0x00,"20");delay_nms(10);lcd_displaystr(0,0x04,"-");delay_nms(10);lcd_displaystr(0,0x07,"-");lcd_displaystr(0,0x0b,"Week:");lcd_displaystr(1,0x00,"Time:");lcd_displaystr(1,0x07,":");lcd_displaystr(1,0x0a,":");while(1){//按键扫描,实现对时间的调整,对应实验板的独立按钮//开始时间设置,staus=1if(P2_0==0){delay_nms(10);if(P2_0==0){staus^=1;count=0;while(P2_0==0);}}if(P2_1==0){delay_nms(10);if(P2_1==0){count++; //光标移位if(count==8)count=1;while(P2_1==0);}}if(P2_2==0) //加按钮{delay_nms(10);if(P2_2==0){switch(count){case 0x01:read_rtc_code[0]++;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[0],(read_rtc_code[0]+(read_rtc_code[0]/10)*6));LCD_write_char(0,0x02,(read_rtc_code[0]/10)); //年十位LCD_write_char(0,0x03,(read_rtc_code[0]%10)); //年个位break;case 0x02:read_rtc_code[1]++;if(read_rtc_code[1]==13)read_rtc_code[1]=1;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[1],(read_rtc_code[1]+(read_rtc_code[1]/10)*6));LCD_write_char(0,0x05,(read_rtc_code[1]/10)); //月十位LCD_write_char(0,0x06,(read_rtc_code[1]%10)); //月个位break;case 0x03:read_rtc_code[2]++;if(read_rtc_code[2]==31)read_rtc_code[2]=1;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[2],(read_rtc_code[2]+(read_rtc_code[2]/10)*6));LCD_write_char(0,0x08,(read_rtc_code[2]/10)); //日十位LCD_write_char(0,0x09,(read_rtc_code[2]%10)); //日个位break;case 0x04:read_rtc_code[3]++;if(read_rtc_code[3]==8)read_rtc_code[3]=1;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[3],(read_rtc_code[3]+(read_rtc_code[3]/10)*6));LCD_write_char(0,0x0f,(read_rtc_code[3]%10)); //星期break;case 0x05:read_rtc_code[4]++;if(read_rtc_code[4]==25)read_rtc_code[4]=0;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[4],(read_rtc_code[4]+(read_rtc_code[4]/10)*6));LCD_write_char(1,0x05,(read_rtc_code[4]/10)); //时十位LCD_write_char(1,0x06,(read_rtc_code[4]%10)); //时个位break;case 0x06:read_rtc_code[5]++;if(read_rtc_code[5]==60)read_rtc_code[5]=0;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[5],(read_rtc_code[5]+(read_rtc_code[5]/10)*6));LCD_write_char(1,0x08,(read_rtc_code[5]/10)); //分十位LCD_write_char(1,0x09,(read_rtc_code[5]%10)); //分个位break;case 0x07:read_rtc_code[6]++;if(read_rtc_code[6]==60)read_rtc_code[6]=0;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[6],(read_rtc_code[6]+(read_rtc_code[6]/10)*6));LCD_write_char(1,0x0b,(read_rtc_code[6]/10)); //秒十位LCD_write_char(1,0x0c,(read_rtc_code[6]%10)); //秒个位break;default:break;}while(P2_2==0);}}if(P2_3==0) //减按钮{delay_nms(10);if(P2_3==0){switch(count){case 0x01:if(read_rtc_code[0]==0){lcd_displaystr(0,0x00,"19");read_rtc_code[0]=99;}elseread_rtc_code[0]--;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[0],(read_rtc_code[0]+(read_rtc_code[0]/10)*6));LCD_write_char(0,0x02,(read_rtc_code[0]/10)); //年十位LCD_write_char(0,0x03,(read_rtc_code[0]%10)); //年个位break;case 0x02:if(read_rtc_code[1]==1)read_rtc_code[1]=12;elseread_rtc_code[1]--;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[1],(read_rtc_code[1]+(read_rtc_code[1]/10)*6));LCD_write_char(0,0x05,(read_rtc_code[1]/10)); //月十位LCD_write_char(0,0x06,(read_rtc_code[1]%10)); //月个位break;case 0x03:if(read_rtc_code[2]==1)read_rtc_code[2]=30;elseread_rtc_code[2]--;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[2],(read_rtc_code[2]+(read_rtc_code[2]/10)*6));LCD_write_char(0,0x08,(read_rtc_code[2]/10)); //日十位LCD_write_char(0,0x09,(read_rtc_code[2]%10)); //日个位break;case 0x04:if(read_rtc_code[3]==1)read_rtc_code[3]=7;elseread_rtc_code[3]--;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[3],(read_rtc_code[3]+(read_rtc_code[3]/10)*6));LCD_write_char(0,0x0f,(read_rtc_code[3]%10)); //星期break;case 0x05:if(read_rtc_code[4]==0)read_rtc_code[4]=24;elseread_rtc_code[4]--;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[4],(read_rtc_code[4]+(read_rtc_code[4]/10)*6));LCD_write_char(1,0x05,(read_rtc_code[4]/10)); //时十位LCD_write_char(1,0x06,(read_rtc_code[4]%10)); //时个位break;case 0x06:if(read_rtc_code[5]==00)read_rtc_code[5]=59;elseread_rtc_code[5]--;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[5],(read_rtc_code[5]+(read_rtc_code[5]/10)*6));LCD_write_char(1,0x08,(read_rtc_code[5]/10)); //分十位LCD_write_char(1,0x09,(read_rtc_code[5]%10)); //分个位break;case 0x07:if(read_rtc_code[6]==0)read_rtc_code[6]=59;elseread_rtc_code[6]--;DS1302_WP_ENABLE;Write_Ds1302(write_rtc_address[6],(read_rtc_code[6]+(read_rtc_code[6]/10)*6));LCD_write_char(1,0x0b,(read_rtc_code[6]/10)); //秒十位LCD_write_char(1,0x0c,(read_rtc_code[6]%10)); //秒个位break;default:break;}while(P2_3==0);}}if(staus==0){//读出DS1302寄存器里的时间信息RST=HIGH;Read_RTC();LCD_write_char(0,0x02,(read_rtc_code[0]/10)); //年十位LCD_write_char(0,0x03,(read_rtc_code[0]%10)); //年个位LCD_write_char(0,0x05,(read_rtc_code[1]/10)); //月十位LCD_write_char(0,0x06,(read_rtc_code[1]%10)); //月个位LCD_write_char(0,0x08,(read_rtc_code[2]/10)); //日十位LCD_write_char(0,0x09,(read_rtc_code[2]%10)); //日个位LCD_write_char(0,0x0f,(read_rtc_code[3]%10)); //星期LCD_write_char(1,0x05,(read_rtc_code[4]/10)); //时十位LCD_write_char(1,0x06,(read_rtc_code[4]%10)); //时个位LCD_write_char(1,0x08,(read_rtc_code[5]/10)); //分十位LCD_write_char(1,0x09,(read_rtc_code[5]%10)); //分个位LCD_write_char(1,0x0b,(read_rtc_code[6]/10)); //秒十位LCD_write_char(1,0x0c,(read_rtc_code[6]%10)); //秒个位}else{RST=LOW;switch(count){case 0x01:write_lcd_command(0x83);break;case 0x02:write_lcd_command(0x86);break;case 0x03:write_lcd_command(0x89);break;case 0x04:write_lcd_command(0x8f);break;case 0x05:write_lcd_command(0xc6);break;case 0x06:write_lcd_command(0xc9);break;case 0x07:write_lcd_command(0xcc);break;default:break;}}}}。

基于DS1302和LCD1602的万年历-闹钟-时钟-用开发版直接显示的程序---副本

基于DS1302和LCD1602的万年历-闹钟-时钟-用开发版直接显示的程序---副本

实时时钟芯片DS1302应用,DS18B20应用实例——可调时钟,LCD1602显示:(时间+温度)说明:需要按程序中定义的接口。

按自己接口,只要在程序中修改接口定义即可。

1、DS1302引脚排列:如下图引脚说明:1)Vcc1:后备电源,VCC2:主电源。

在主电源关闭的情况下,也能保持时钟的连续运行。

DS1302由Vcc1或Vcc2两者中的较大者供电。

当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。

当Vcc2小于Vcc1时,DS1302由Vcc1供电。

2)X1、X2:振荡源,外接32.768kHz 晶振。

3)RST:复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。

RST输入有两种功能:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。

当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。

如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。

上电运行时,在Vcc>2.0V之前,RST必须保持低电平。

只有在SCLK为低电平时,才能将RST置为高电平。

4)I/O为串行数据输入输出端(双向)。

5)SCLK为时钟输入端。

2、DS1302的控制字节DS1302 的控制字如下图所示。

控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。

3、数据输入输出(I/O)在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。

同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。

数字时钟DS1302+LCD1602

数字时钟DS1302+LCD1602
TAB3: DB 04H,05H,06H,07H
;//////程序结束//////////////////////////////////////
END
;***********************************************************
;程序名称:DS1302+LCD1602简单时钟
;主控芯片:89c51,12MHZ
;编者心得:datasheet很重要,如果datasheet看不懂,找个例程配合着研究
;移用核心:整个框架就是这样,可根据具体需要进行修改
MOV A,B
ADD A,#30H ;转换到ASCII码
MOV B,A
MOV A,R5
MOV P0,A
SETB RS
CLR RW
CLR E
MOV R7,#14H
DJNZ R7,$
SETB E
MOV P0,B
MOV B,R2 ;数据写完没有.
CJNE A,B,AGAIN
RET
;//////转换DS1302数据并写到LCD1602////////////////
WRITE1: MOV B,#10H;拆字节
DIV AB
ADD A,#30H
MOV R5,A
AJMP REPEAT
;//////写lcd1602指令子程序/////////////////////////////
ENABLE: CLR RS
CLR RW
CLR E
ACALL DELAY
SETB E
RET
;//////写lcd1602数据子程序/////////////////////////////

DS1302时钟LCD1602显示

DS1302时钟LCD1602显示

/**************************************************************** ** DS1302时钟******************************************************************/ #include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//--定义矩阵键盘使用的IO口--//#define GPIO_DIG P0#define GPIO_KEY P1//---定义lcd1602使用的IO口---//#define DB P0//--定义全局变量--//uchar error[]="Error!!!" ;//存放字符串“Error!!!”char KeyValue=-1;//用来存放读取到的键值uchar flag=0;//用来检测是否更改过时间uchar tt0=0;//中断里面的参数uchar beeflag=0;//看看有没有开闹钟//---定义蜂鸣器使用的IO口---//sbit bee=P2^3;//定义LCD1602使用的IO口//sbit LCDE=P2^7;sbit RS=P2^6;sbit RW=P2^5;//---定义ds1302使用的IO口---//sbit DSIO=P3^4; //数据传输口sbit RST=P3^5; //进行传输时,RST必须置高sbit SCLK=P3^6; //上沿读数据,下沿写数据//---DS1302写入和读取时分秒的地址命令---////---秒分时日月周年最低位读写位;-------//uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};//---键盘写入地址-------//uchar kyewrite[] = {0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8d,0xc0,0xc1,0xc3,0xc4,0xc6,0xc7};//用于判断增减//char addorm[]={0x01,0x10,-0x01,-0x10};//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。

毕业论文用DS1302与1602LCD设计的可调式电子日历时钟的设计与实现 .jsp

毕业论文用DS1302与1602LCD设计的可调式电子日历时钟的设计与实现 .jsp

中州大学信息工程学院毕业设计(论文)2009 — 2010学年第二学期题目:用DS1302与1602设计的可调式电子日历时钟的设计与实现学生姓名(学号)邱进进(200702131071171)指导教师刘爱荣职称教授评阅教师职称时间中州大学信息工程学院毕业设计(论文)任务书指导教师:刘爱荣职称:教授学生人数:1人学生姓名(学号、专业):07电子班邱进进毕业设计(论文)题目(来源、类型)用DS1302与1602LCD设计的可调式电子日历时钟的设计与实现毕业设计(论文)工作内容与基本要求(目标、任务、途径、方法、成果形式,应掌握的原始资料(数据)、参考资料(文献)以及设计技术要求、注意事项等)(纸张不够可加页)基本要求:(1)显示:年、月、日、时、分、秒;(2)具有年、月、日、时、分、秒的设置功能。

成果形式:(主要包括毕业论文,系统设计技术文档,软件等):设计功能演示;论文电子文档及程序提交光盘;按学院格式要求打印论文3份上交。

参考资料有:单片机的C语言应用程序设计(马忠梅、)新编单片机应用程序设计(张毅刚)教研室审批意见:审批人签名:中州大学信息工程学院毕业设计(论文)开题报告课题名称(来源、类型):用DS1302与1602LCD设计的可调式电子日历时钟的设计与实现指导教师:刘爱荣学生姓名:邱进进200702131071171专业:07电子信息工程技术开题报告内容:(调研资料的准备,设计/论文的目的、要求、思路与预期成果;任务完成的阶段内容及时间安排;完成设计(论文)所具备的条件因素等。

)1.目的:实现日历和时钟的显示并且能够调整2.要求:完成可调式电子日历时钟的硬件和软件的设计,包括单片机的相关内容;日历时钟模块的设计,液晶显示模块的设计,按键模块的设计。

控制程序的编写等。

3.预期成果:仿真成功,做出实物产品。

(1)显示初始值日历时钟初始值;(2)用按键调整日历时钟。

4.时间安排:第1~2周:熟悉课题的基本要求,查阅相关资料,初步拟定设计的整体方案,完成开题报告。

电子时钟设计-DS1302+1602+可调闹钟+程序清单

电子时钟设计-DS1302+1602+可调闹钟+程序清单

摘要随着单片机技术的飞速发展,在其推动下,现代的电子产品几乎渗透到了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高。

时间就是金钱、时间就是生命、时间就是胜利……,准确的掌握时间和分配时间对人们来说至关重要,时钟是我们生活中必不可少的工具。

电子钟的设计方法有很多种,但是基于单片机并通过LCD显示的电子时钟具有编程灵活、精确度高、便于携带、显示直观等特点。

利用STC89C52单片机对DS1302时钟芯片进行读写操作并通过1602字符液晶显示实时时钟信息,这样便构成了一个单片机电子时钟。

关键词:单片机,电子时钟,STC89C52,蜂鸣器ABSTRACTWith the rapid development of microcomputer technology in its promotion, modern electronics into almost all areas of society, a strong impetus to the development of social productive forces and social improvement in the level of information, but also to further improve the performance of modern electronic products.Time is a money, time is life, time is victory…Accurate grasp of time and allocation of time is crucial to people, The clock is necessary in our life tools . Clock Design There are many ways, however, produced by single chip electronic clock is more flexible programming, and easy expansion of electronic capabilities, high accuracy, easy to carry, display visual and so on.In this paper, through the use of STC89C52 microcontroller by DS1302 clock chips for reading and writing operation and through 1602 character liquid crystal display real-time clock information so that forming a single chip electronic clock.Key Words: Microcontroller,STC89C52,Electronic clock,buzzer目录绪论---------------------------------------------------------------0概述---------------------------------------------0研究目的-----------------------------------------0第1章设计要求与方案论证--------------------------------01.1 设计要求-------------------------------------01.2 系统基本方案选择和论证-----------------------11.2.1 单片机芯片的选择方案和论证---------------------11.2.2 显示模块选择方案和论证—————————————---11.2.3 时钟芯片的选择方案和论证-----------------------21.3 电路设计最终方案决定----------------------------------2第2章主要元件介绍-----------------------------------------32.1 STC89C52以及最小系统介绍--------------------32.1.1 STC89C52主要功能及PDIP封装----------------------22.1.2 STC89C52引脚介绍-----------------------------------22.1.3 STC89C52最小系统-----------------------------------42.2 DS1302时钟芯片以及集成时钟模块介绍----------52.2.1 DS1302概述------------------------------------------62.2.2 DS1302引脚介绍-------------------------------------62.2.3 DS1302使用方法-------------------------------------62.2.4 时钟集成模块内部原理图以及实物图--------------8 2.3 1602字符液晶以及显示模块介绍-----------------错误!未定义书签。

用DS1302与LCD1602可调数字万年历课程设计

用DS1302与LCD1602可调数字万年历课程设计

数字开发与实践课程设计题目:用DS1302与LCD1602设计可调式电子日历时钟班级:姓名:学号:学院:二O一二年六月五日用DS1302与LCD1602设计的可调式电子日历时钟一、总体设计1.1、设计目的为巩固所学的单片机知识,把所学理论运用到实践中,用LCD1602与DS1302 设计可调式电子日历时钟。

1.2、设计要求(1)显示:年、月、日、时、分、秒和星期;(2)设置年、月、日、时、分、秒和星期的初始状态;(3)能够用4个按键调整日历时钟的年、月、日、时、分、秒和星期;完成可调式电子日历时钟的硬件和软件的设计,包括单片机的相关内容;日历时钟模块的设计,液晶显示模块的设计,按键模块的设计。

控制程序的编写等。

备注:本程序另外添加了每到上午8:10和下午2:10的闹钟提醒功能。

1.3、系统基本方案选择和论证1.3.1、单片机芯片的选择方案方案一:采用89C51芯片作为硬件核心,采用Flash ROM,内部具有4KB ROM 存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容。

方案二:采用STC12C5A60S2系列单片机是宏晶科技生产的单时钟/机器周期(1T)的单片机,是高速/低功耗/超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。

内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换(250K/S),针对电机控制,强干扰场合。

但造价较高。

1.3.2 、显示模块选择方案和论证:方案一:采用点阵式数码管显示,点阵式数码管是由八行八列的发光二极管组成,对于显示文字比较适合,如采用显示数字显得太浪费,且价格也相对较高。

所以不用此种作为显示。

方案二:采用LED数码管动态扫描,虽然LED数码管价格适中,但要显示多个数字所需要的个数偏多,功耗较大,显示出来的只是拼音,而不是汉字。

所以也不用此种作为显示。

方案三:采用LCD液晶显示屏,液晶显示屏的显示功能强大,可显示大量字符,且视觉效果较好,外形美观。

基于51单片机与DS1302时钟芯片和LCD1602液晶显示的数字时钟

基于51单片机与DS1302时钟芯片和LCD1602液晶显示的数字时钟

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); }
P3.0/RXD P3.1/TXD P3.2/INT0 P3.3/INT1
P3.4/T0 P3.5/T1 P3.6/WR P3.7/RD
D1 LC
SD E
S V
VD
E V
S R
RW E
0 1 2 3 4 5 67 D D D D D D DD
D N +5V G 39 38
37
36 35
34
33 32
GotoXY(0,0); Print(" tian ma dian zi"); GotoXY(0,1); Print("Time: ");
Word 文档
.
while(1) {
DS1302_GetTime(&CurrentTime); TimeToStr(&CurrentTime); GotoXY(6,1); Print(CurrentTime.TimeString);
unsigned char i; ACC = d; for(i=8; i>0; i--) {
DS1302_IO = ACC0; DS1302_CLK = 1;
// 实时时钟写入一字节 (部函数 ) // 相当于汇编中的 RRC
Word 文档
.
DS1302_CLK = 0; ACC = ACC >> 1; } }
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

学习情境2-可调式数字钟之基于DS1302和LCD1602的可调数字钟☆点名,复习1、DS1302的引脚及其功能,以及DS1302与单片机的硬件连接?2、如何对DS1302读写数据,如何得到DS1302的时钟?☆新课讲授2.3 基于DS1302与LCD1602设计的可调数字钟上堂课程我们学会了使用DS1302,知道了如何在单片机系统中的连接,也详细的学习了如何得到DS1302的时钟,并且我们使用了16个数码管把年月日和时分秒实时地显示出来。

但数码管的显示毕竟有其自身的缺陷,现在在工业控制的各个环节,都使用液晶进行人机联系。

在日常生活中,我们对液晶显示器并不陌生。

液晶显示模块已作为很多电子产品的通用器件,如在计算器、万用表、电子表及很多家用电子产品中都可以看到,显示的主要是数字、专用符号和图形。

在单片机的人机交流界面中,一般的输出方式有以下几种:发光管、LED 数码管、液晶显示器。

发光管和LED数码管比较常用,软硬件都比较简单,在单片机系统中应用液晶显示器作为输出器件有以下几个优点:(1)显示质量高,由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点。

因此,液晶显示器画质高且不会闪烁。

(2)数字式接口,液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。

(3)体积小、重量轻,液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多。

(4)功耗低,相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。

2.3.1 LCD1602技术资料2.3.1.1 液晶显示简介1、液晶显示原理:液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。

液晶显示器具有厚度薄、适用于大规模集成电路直接驱动、易于实现全彩色显示的特点,目前已经被广泛应用在便携式电脑、数字摄像机、PDA移动通信工具等众多领域。

2、液晶显示器的分类:液晶显示的分类方法有很多种,通常可按其显示方式分为段式、字符式、点阵式等。

除了黑白显示外,液晶显示器还有多灰度有彩色显示等。

如果根据驱动方式来分,可以分为静态驱动(Static)、单纯矩阵驱动(Simple Matrix)和主动矩阵驱动(Active Matrix)三种。

3、液晶显示器各种图形的显示原理:线段的显示:点阵图形式液晶由M×N个显示单元组成,假设LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成,屏上64×16个显示单元与显示RAM区1024字节相对应,每一字节的内容和显示屏上相应位置的亮暗对应。

例如屏的第一行的亮暗由RAM区的000H——00FH的16字节的内容决定,当(000H)=FFH时,则屏幕的左上角显示一条短亮线,长度为8个点;当(3FFH)=FFH 时,则屏幕的右下角显示一条短亮线;当(000H)=FFH,(001H)=00H,(002H)=00H,……(00EH)=00H,(00FH)=00H时,则在屏幕的顶部显示一条由8段亮线和8条暗线组成的虚线。

这就是LCD显示的基本原理。

字符的显示:用LCD显示一个字符时比较复杂,因为一个字符由6×8或8×8点阵组成,既要找到和显示屏幕上某几个位置对应的显示RAM区的8字节,还要使每字节的不同位为“1”,其它的为“0”,为“1”的点亮,为“0”的不亮。

这样一来就组成某个字符。

但由于内带字符发生器的控制器来说,显示字符就比较简单了,可以让控制器工作在文本方式,根据在LCD 上开始显示的行列号及每行的列数找出显示RAM对应的地址,设立光标,在此送上该字符对应的代码即可。

汉字的显示:汉字的显示一般采用图形的方式,事先从微机中提取要显示的汉字的点阵码(一般用字模提取软件),每个汉字占32B,分左右两半,各占16B,左边为1、3、5……右边为2、4、6……根据在LCD上开始显示的行列号及每行的列数可找出显示RAM对应的地址,设立光标,送上要显示的汉字的第一字节,光标位置加1,送第二个字节,换行按列对齐,送第三个字节……直到32B显示完就可以LCD上得到一个完整汉字。

2.3.1.2、1602字符型LCD简介字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。

一般1602字符型液晶显示器实物如图(1):图(1)1602字符型液晶显示器实物图1602LCD分为带背光和不带背光两种,其控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别。

1602LCD主要技术参数:显示容量:16×2个字符;芯片工作电压:4.5—5.5V;工作电流:2.0mA(5.0V);模块最佳工作电压:5.0V;字符尺寸:2.95×4.35(W×H)mm 引脚功能说明:1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表1所示:第1脚:VSS为地电源。

第2脚:VDD接5V正电源。

第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。

第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。

第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。

当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。

第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。

第7~14脚:D0~D7为8位双向数据线。

第15脚:背光源正极。

第16脚:背光源负极。

表1 1602LCD引脚接口说明编号符号引脚说明编号符号引脚说明1 VSS 电源地9 D2 数据2 VDD 电源正极10 D3 数据3 VL 液晶显示偏压11 D4 数据4 RS 数据/命令选择12 D5 数据5 R/W 读/写选择13 D6 数据6 E 使能信号14 D7 数据7 D0 数据15 BL A 背光源正极8 D1 数据16 BL K 背光源负极2.3.1.3、1602LCD的指令说明及时序1602液晶模块内部的控制器共有11条控制指令,如表2所示:表2:控制命令表序号指令RS R/W D7 D6 D5 D4 D3 D2 D1 D0 功能1 复位显示器0 0 0 0 0 0 0 0 0 1 清屏,光标归位2 光标返回0 0 0 0 0 0 0 0 1 *设置地址计数器清零,DDRAM数据不变,光标移到左上角3 字符进入模式0 0 0 0 0 0 0 1 I/D S 设置字符进入时的屏幕移位方式4 显示开/关控制0 0 0 0 0 0 1 D C B 设置显示开关,光标开关,闪烁开关5 光标或字符移位0 0 0 0 0 1 S/C R/L * * 设置字符与光标移动6 功能设置0 0 0 0 1 DL N F * * 设置DL,显示行数,字体7 设置字符发生存贮器地址0 0 0 1 字符发生存贮器地址设置6位的CGRAM地址以读/写数据8 设置数据存贮器地址0 0 1 显示数据存贮器地址设置7位的DDRAM地址以读/写数据9 读忙标志或地址0 1 BF 计数器地址读忙标志及地址计数器10 写数据到CGRAM或DDRAM)1 0写入一字节数据,需要先设置RAM地址向CGRAM/DDRAM写入一字节的数据11 从CGRAM或DDRAM读数据1 1读取入一字节数据,需要先设置RAM地址从CGRAM/DDRAM读取一字节的数据I/D =1 递增,I/D=0 递减。

S=0 时显示屏不移动,S=1时,如果I/D =1且有字符写入时显示屏左移,否则右移。

D=1 显示屏开,D=0 显示屏关。

C=1 时光标出现在地址计数器所指的位置,C=0时光标不出现。

B=1 时光标出现闪烁,B=0时光标不闪烁。

S/C=0 时,RL=0则光标左移,否则右移。

S/C=1 时,RL=0则字符和光标左移,否则右移。

DL=1 时数据长度为8位,DL=0 时为使用D7-D4共4位,分两次送一字节。

N=0为单行显示,N=1时为双行显示。

F=1 时为510点阵字体,F=0 时为57点阵字体。

BF=1 时LCD忙,BF=0 时LCD就绪。

1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。

(说明:1为高电平、0为低电平)指令1:清显示,指令码01H,光标复位到地址00H位置。

指令2:光标复位,光标返回到地址00H。

指令3:光标和显示模式设置I/D:光标移动方向,高电平右移,低电平左移S:屏幕上所有文字是否左移或者右移。

高电平表示有效,低电平则无效。

指令4:显示开关控制。

D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示C:控制光标的开与关,高电平表示有光标,低电平表示无光标B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。

指令5:光标或显示移位S/C:高电平时移动显示的文字,低电平时移动光标。

指令6:功能设置命令DL:高电平时为4位总线,低电平时为8位总线N:低电平时为单行显示,高电平时双行显示F: 低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。

指令7:字符发生器RAM地址设置。

指令8:DDRAM地址设置。

指令9:读忙信号和光标地址BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。

指令10:写数据。

指令11:读数据。

与HD44780相兼容的芯片时序表如下:表3:基本操作时序表读状态输入RS=L,R/W=H,E=H 输出D0—D7=状态字写指令输入RS=L,R/W=L,D0—D7=指令码,E=高脉冲输出无读数据输入RS=H,R/W=H,E=H 输出D0—D7=数据写数据输入RS=H,R/W=L,D0—D7=数据,E=高脉冲输出无读写操作时序如图3和4所示:图3 读操作时序图4 写操作时序2.3.1.4 1602LCD的RAM地址映射及标准字库表液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志位,如果该位为低电平,表示不忙,否则此指令失效。

要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,图5是1602的内部显示地址。

图5 1602LCD内部显示地址例如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位D7恒定为高电平1所以实际写入的数据应该是01000000B(40H)+10000000B(80H)=11000000B(C0H)。

相关文档
最新文档