资源描述
《专业设计实训(二)》
可调数字电子钟的设计与制作
实训手册
姓 名: 贺凤
学 号: 20081893
班 级: 08电信(职高)
实训地点: 理工楼
指导教师: 占华林
通信与电子学院编制
11年 6月 11日
一、 设计目的
1. 熟悉集成电路的引脚安排
2. 掌握个芯片的逻辑功能及使用方法
3. 了解实验台
4. 了解数字钟的组成及工作原理
5. 熟悉数字钟的设计与制作
二、 设计要求
时间以24小时为一个周期:显示时和分;有校时功能,可以分别对时及分进行单独校时,使其校正到标准时间;直接由单片机内部定时来表针时间的基准信号。
三、 设计原理
1、1602液晶显示屏
管脚功能
引脚说明
1602字符型LCD通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线 VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样,其中:
引脚
符号
功能说明
1
VSS
一般接地
2
VDD
接电源(+5V)
3
V0
液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。
4
RS
RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
5
R/W
R/W为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作。
6
E
E(或EN)端为使能(enable)端,下降沿使能。
7
DB0
低4位三态、 双向数据总线 0位(最低位)
8
DB1
低4位三态、 双向数据总线 1位
9
DB2
低4位三态、 双向数据总线 2位
10
DB3
低4位三态、 双向数据总线 3位
11
DB4
高4位三态、 双向数据总线 4位
12
DB5
高4位三态、 双向数据总线 5位
13
DB6
高4位三态、 双向数据总线 6位
14
DB7
高4位三态、 双向数据总线 7位(最高位)(也是busy flag)
15
BLA
背光电源正极
16
BLK
背光 电源负极
寄存器选择控制表
RS
R/W
操作说明
0
0
写入指令寄存器(清除屏等)
0
1
读busy flag(DB7),以及读取位址计数器(DB0~DB6)值
1
0
写入数据寄存器(显示各字型等)
1
1
从数据寄存器读取数据
注:关于E=H脉冲——开始时初始化E为0,然后置E为1,再清0. busy flag(DB7):在此位为被清除为0时,LCD将无法再处理其他的指令要求。
写操作时序:
读操作时序
1 RTC结构特点
实时时钟的基本功能是保持跟踪时间和日期等信息,但许多RTC还提供有多种附加功能,如:看门狗定时器、系统复位、非易失存储器(NV RAM)、序列号、方波输出、涓流充电等。因此,在进行电路设计时,选择RTC芯片出了需要考虑其时间和日期跟踪功能外,通常还需要针对具体应用来对
RTC的功能、成本、尺寸等要求进行综合考虑。
1.1 接口方式
从接口要求入手选择RTC可以大大缩小芯片的选择范围。RTC芯片提供有多种接口方式,其中并行接口可实现存储器的快速访问或有较大的存储容量,适合于那些对价格、尺寸要求不是很荷刻的系统,许多采用并行接口的实时时钟芯片还与晶振和电池封装在一起构成一个完整的时钟模块,从而简化了硬件设计。并行接口包括复用总线(数据与地址总线复用)和独立的地址、数据总线。一般用于时间保持的NV RAM都采用与SRAM相同的控制信号,并可以方便地与常用的微处理器容量。另外,有些Phantom实时时钟还将时钟数据隐含在备用电池支持的RAM内,以便利用64位软件协议来访问时钟数据。
一般情况下,串行接口时钟芯片都具有外形尺寸较小、成本低廉等优势,但这类芯片的通信速率一般较低,因而比较适合便携式产品。这类芯片通常包括1-Wire接口、2线、3线、4线或SPI接口,而许多处理器也包括2线或SPI接口,当然,也有些处理器(如8051及其派生产品)则支持复用的地址和数据总线
有些时间保持NV RAM模块利用时钟来控制IC和SRAM,出厂时,振荡器处于禁止状态、SRAM与电池断开,只有模块在主电源供电并第一,使用时应确保环境温度不要超出+85℃。
1.1晶振与精度
晶体振荡器在固定频率振荡器中能够提供较高的精度,绝大多数RTC采用32.768kHz的晶体,晶体振荡器输出经过分频后会产生1Hz的基准来刷新时间和日期。RTC的精度主要取决于晶振的精度,温度变化时,音叉晶振所具有的抛物线型的频率响应特性曲线如图1所示,23ppm的温漂大约每月产生1分钟的时钟误差。晶振一般在特定的电容负载下,其调谐振荡在正确的频点,而当晶振调谐于12.5pF负载的RTC电路中时,使用6pF负载的晶振将会使时钟变快。Dallas Semiconductor提供的所有RTC均采用内部偏置网络,因而晶振可直接连接到RTC的X1、X2引脚,而不需要额外的元件。由于RTC的晶振输入电路具有很高的输入阻抗(大约109Ω),因此,它与晶振的连线犹如一个天线,很容易耦合系统其余电路的高频干扰。而干扰信号被耦合到晶振引脚将导致时钟数的增加或减少。考虑到线路板上大多数信号的频率高于32.768kHz,所以,通常会产生额外的时钟脉冲计数。因此,晶振应尽可能靠近X1、X2引脚安装,同时晶振、X1/X2引脚的下方最好布成地平面。图2是一个推荐的晶振布线图,其数字信号引脚需远离晶振和振荡器引脚,对于那些会产生明显的射频辐射的元件。
1.2时钟格式
在电路设计中使用的时钟格式主要有三种:BCD码、二进制码、未格式化的二进制计数值。其中BCD码比较通用,因为它的时间和日期可以直接显示,且不需要进行数据转换,每8位寄存器表示一个二位数,对于某些特殊的时间和日期,由于不占用全部8位数据,因此,不用位可以充当一些特殊功能(如用作读/写位),也可以在硬件读取时时终保持固定状态(1或0)。二进制码格式与BCD码一样具有独立的秒、分钟、小时、星期、日、月、年寄存器,在一些提供BCD码格式的RTC中,常常也提供可选择的二进制码格式。时间和日期寄存器每秒钟更新一次,日期循环与月、年有关。星期寄存器与其它寄存器的变化关系不大,在子夜更新数据,数据从7至1循环变化,程序中可以用1表示任何一个特定的星期数,只要在整个程序中指定数值保持一致即可。在12小时制与24小时制或BCD码与二进制码之间进行转换时,时间、日期、闹钟寄存器需要重新进行初始化。二进制计数码用一个多字节(一般为32位)寄存器来存储时间信息,时间信息用一个秒计数值表示,并可通过软件将秒计数值转换为合理的时间和日期。
另外,在选择RTC时,还需要考虑千年(Y2K)兼容性问题,Y2K兼容的RTC包含有世纪信息(提供世纪数值或世纪位),并可正确地计算润年,Dallas Semiconductor提供的RTC均兼容于Y2K,而且不存在日期敏感的逻辑。
四、 设计电路图及简单介绍
动态显示:
实物拍摄
正面
反面
利用单片机内部计时来作为时钟的基准时间。首先自己设置下启动时显示屏的一个初始时间,然后随着晶振导致内部计时开始,也就是秒钟开始走。然后根据秒钟走到59就变为0而分钟加一;当分钟走到59就变为0而时钟加一;当时钟走到23就变为0而日期里的day就加一;依此类推,实现实时时钟的运作。
校正时间:通过内部中断实现校正,根据功能键按键的不同,进入到液晶的不同段区间,然后通过改变p1.1或者p1.2按键来进行时间加减的修改。这里修改时间是根据按键扫描,把数据送到液晶管中显示出来,当功能键按键跳出中断时,时钟继续运作,不过此时就是按照我们校准的时间走了。
程序如下:
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit duan=P2^6;
sbit wei=P2^7;
sbit lcdrs=P3^0;
sbit lcden=P3^1;
uchar count;
uchar shi=0, fen=0, miao=0,a=0,b=0;
uchar week=2,day=11,month=5,year=11;
uchar temp;
sbit s1=P1^0;
sbit s2=P1^1;
sbit s3=P1^2;
uchar s1_num;
uchar code *table=" 2011-05-10 03";
uchar code *table1=" 22:15:00";
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_cmd(uchar cmd)
{
lcdrs=0;
lcden=0;
P0=cmd;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date)
{
lcdrs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
duan=0;
wei=0;
lcden=0;
// shi=19;
//fen=24;
//miao=01;
write_cmd(0x38);
write_cmd(0xc);
write_cmd(0x6);
write_cmd(0x1);
write_cmd(0x80);
while(*table!='\0')
{
write_date(*table++);
//delay(5);
}
write_cmd(0x80+0x40);
while(*table1!='\0')
{
write_date(*table1++);
//delay(5);
}
TMOD=0x01;
TH0=((65536-50000)/256);
TL0=((65536-50000)%256);
EA=1;
ET0=1;
TR0=1;
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_cmd(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void write_ymdw(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_cmd(0x80+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void keyscan()
{
if(s1==0)
{
delay(5);
if(s1==0)
{
s1_num++;
while(!s1);
if(s1_num==1)
{
TR0=0;
write_cmd(0x80+0x40+11);
write_cmd(0xf);
}
if(s1_num==2)
{
write_cmd(0x80+0x40+8);
write_cmd(0xf);
}
if(s1_num==3)
{
write_cmd(0x80+0x40+5);
write_cmd(0xf);
}
if(s1_num==4)
{
write_cmd(0x80+14);
write_cmd(0xf);
}
if(s1_num==5)
{
write_cmd(0x80+11);
write_cmd(0xf);
}
if(s1_num==6)
{
write_cmd(0x80+8);
write_cmd(0xf);
}
if(s1_num==7)
{
write_cmd(0x80+5);
write_cmd(0xf);
}
if(s1_num==8)
{
s1_num=0;
write_cmd(0xc);
TR0=1;
}
}
}
if(s1_num!=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
if(s1_num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_cmd(0x80+0x40+10);
}
if(s1_num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_cmd(0x80+0x40+7);
}
if(s1_num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_cmd(0x80+0x40+4);
}
if(s1_num==4)
{
week++;
if(week==8)
week=0;
write_ymdw(13,week);
write_cmd(0x80+14);
}
if(s1_num==5)
{
day++;
if(day==32||((month==2)&&(((day==30)&&(year%4==0))||((day==29)&&(year%4!=0))))||((day==31)&&((month==4)||(month==6)||(month==9)||(month==11))))
day=0;
write_ymdw(10,day);
write_cmd(0x80+11);
}
if(s1_num==6)
{
month++;
if(month==13)
month=0;
write_ymdw(7,month);
write_cmd(0x80+8);
}
if(s1_num==7)
{
year++;
if(year==99)
year=0;
write_ymdw(4,year);
write_cmd(0x80+5);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
if(s1_num==1)
{
miao--;
if(miao==255)
miao=59;
write_cmd(0x80+0x40+10);
write_sfm(10,miao);
// write_cmd(0x80+0x40+11);
}
if(s1_num==2)
{
fen--;
if(fen==255)
fen=59;
// write_cmd(0x80+0x40+7);
write_sfm(7,fen);
write_cmd(0x80+0x40+8);
}
if(s1_num==3)
{
shi--;
if(shi==255)
shi=23;
// write_cmd(0x80+0x40+4);
write_sfm(4,shi);
write_cmd(0x80+0x40+5);
}
}
}
}
}
void desplay ()
{
while(1)
{ keyscan();
if(count==20)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
day++;
week++;
if(week==8)
week=1;
temp=(day==32);
temp=temp||((month==2)&&(((day==30)&&(year%4==0))||((day==29)&&(year%4!=0))));
temp=temp||((day==31)&&((month==4)||(month==6)||(month==9)||(month==11)));
if(temp)
{
day=1;
month++;
if(month==13)
{
month=1;
year++;
if(year==99)
year=0;
write_ymdw(4,year);
}
write_ymdw(7,month);
}
write_ymdw(10,day);
write_ymdw(13,week);
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);
}
if(shi==a&&fen==b)
{P1^5==0;
}
}
}
void main()
{
init();
desplay();
}
void timer0() interrupt 1
{
TH0=((65536-50000)/256);
TL0=((65536-50000)%256);
count++;
}
五、 心得体会
这次我们做的实训一共有四个题目供我们选择,分别是采集信号、计算器、模拟电梯和可调数字钟,我做的是可调数字钟,开始做的时候觉得应该还蛮好做的,因为我对这个程序比较了解,加上上课老师也讲了一些相关知识,所以我觉得这个不管是程序上还是硬件实施上都是比较容易实现的,可是真正做的时候却不如我想象中那样,在焊接这方面基本上没什么问题,因为可调数字钟在软件方面要求比较高,所以相对来说硬件就比较简单,可是硬件完成后,烧好芯片,却没有出现我意想的结果,可我找了半天也不知道哪里出了问题,问了同学,他也说我这个电路没有什么问题,可是就是出不来,我自己也检查了好多遍,后来实在没有办法了,我就再做了一个,终于出来了数据,这个实训也就此画上了句号。
这次实训从老师讲理论课到我们把他做成实物,一个用了三个星期左右,其实时间也还算长了,可是为什么我到最后一两天还是急急忙忙的呢?我觉的主要有以下几个方面:没有提前做好理论工作,没有合理的安排实训时间,所以,不管以后做什么事,一定要做好前提工作,这样一步一步下来,出错的可能性就尽可能的减少了。
展开阅读全文