当前位置:首页 期刊杂志

基于STC89C52万年历的仿真与设计

时间:2024-07-28

郭占苗

(西安航空职业技术学院 电子工程学院, 西安 710089)

基于STC89C52万年历的仿真与设计

郭占苗

(西安航空职业技术学院 电子工程学院, 西安 710089)

基于STC89C52设计一款具有时间、星期、年月日和温度显示的万年历,主要由DS1302实现时分秒、年月日和星期的计时功能,DS18B20实现温度采集功能,该万年历除复位按键外,还设置有4个按键,可以对时间进行“加”“减”设置,同时还具备定时功能,定时时间到则蜂鸣器报警,在LCD1602液晶屏上进行实时显示,实现人机交互。利用Keil软件编写C程序,通过Proteus仿真以减少焊接盲目性,最后进行实物电路制作,实现设计、仿真与制作的一体化,具有理论与实践结合的现实意义。

STC89C52; 万年历; 温度显示; 调时; Proteus仿真

0 引言

万年历能够显示时间、日期、星期和温度等信息,是很重要的一种计时工具,STC89C52单片机具有体积小、性价比高、功能强、可靠性高等特点,在各个领域广泛使用,设计一款由STC89C52为控制模块的万年历,实现了秒、分、时、日、月、年和温度等数字是精准显示,可运用独立按键设置闹钟、进行调时,与传统机械时钟相比,它具有走时和温度显示精准、简单清晰、成本低廉、使用寿命长等优点,给人们的学习和生活带来极大地方便,已得到广泛使用[1]。

1 万年历系统总体设计

系统由STC89C52片机控制模块、按键模块、LCD液晶显示模块、蜂鸣器报警定时模块和DS18B20温度采集模块构成。主要控制单元采用STC89C52单片机,系统总体结构图如图1所示,当温度传感器DS18B20接收到外界环境温度的信号,将其转换成数字信号后送入单片机,单片机将信号处理后在液晶上显示出来,同时,LCD1602还显示DS1302时钟芯片传送的时间信息,通过按键设置可以实现调整时间,闹钟定时报警等功能。

图1 万年历总体结构图

2 时钟模块设计

时间显示主要采用时钟芯片DS1302来实现,可实现秒、分、小时、日期、月、年等信息。芯片的1脚(VCC2)是主电源引脚,接正5 V电源,8脚(VCC1)备用电源接纽扣电池(CR2032),以确保断电情况下,时钟持续运行,X1和X2接32.768KHZ的晶振,6脚(I/O)、7脚(SCLK)和5脚(CE)依次接单片机的P1.1、P1.0和P1.2端口[2]。

2.1 DS1302初始化

根据DS1302的时钟寄存器进行DS1302芯片的初始化,开机显示“2106-01-19 week2 12:00:00”,初始化子函数如下:

void ds1302_init()

{ RST=0; SCLK=0; write_1302(0x8e,0x00); //允许写,禁止写保护 write_1302(0x80,0x00); //向寄存器80H写入初始秒数据00 write_1302(0x82,0x00); //向寄存器82H写入初始分数据00 write_1302(0x84,0x12); //向寄存器84H写入初始小时数据12 write_1302(0x8a,0x02); //向寄存器8aH写入初始星期数据2 write_1302(0x86,0x19); //向寄存器86H写入初始日期数据19 write_1302(0x88,0x01); //向寄存器88H写入初始月份数据01 write_1302(0x8c,0x16); //向寄存器8cH写入初始年份数据16 write_1302(0x8e,0x80); //打开写保护

}

注意,DS1302用的是BCD码,液晶显示是十进制,通过“Decimal=bcd>>4; return(Decimal=Decimal*10+(bcd&=0x0F));”语句实现将压缩的BCD码分离显示为十进制的功能。

2.2 DS1302读写字节

根据DS1302写时序,编写DS1302写字节、读单字节程序。写单字节时,先将I/O准备好,SCLK上升沿时读取数据,下降沿时信号变化[3],DS1302写单字节函数如下:

void write_byte(uchar dat)

{ uchar a;

ACC=dat;

RST=1; //高电平使能

for(a=8;a>0;a--)

{ IO=ACC0; //IO准备好

SCLK=0;

SCLK=1; //DS1302的时钟SCLK上升沿时,读取数据

ACC=ACC>>1;

} }

DS1302读一个字节函数时,要先读出数据,然后再产生上升沿“SCLK=1”,否则时间可能显示有误,最后返回一个数据值“return (ACC);”,主要程序如下:

uchar read_byte()

{ uchar a;

RST=1;

for(a=8;a>0;a--)

{

ACC7=IO; //读字节

SCLK=1;

SCLK=0; //下降沿,信号变化

ACC=ACC>>1;

}

return (ACC);

}

3 温度采集设计

温度传感器DS18B20,能够将温度转换成数字信号,测温范围是:-55-+125°,其中DQ接P3.3引脚,其余接电源和地。虽然硬件电路简单,但是由于DS18B20是一条口线通信,所以协议较复杂,时序要求严格[4]。首先根据检测脉冲时序编写检测存在脉冲函数如下:

void ow _reset ( )

{ char presence=1;

while(presence)

{ while(presence)

{

DQ=1;_nop_();_nop_();

DQ=0; //从高拉倒低

delay2(50); //550 us(时序图要求480-960 us)

DQ=1;

delay2(6); //66 us(要求15-60us,60us后肯定释放总线)

presence=DQ; //presence=0 复位成功,继续下一步

}

delay2(45); //延时500 us

presence=~DQ;

}

DQ=1; //拉高电平

}

然后向“1-wire”总线写一个字节,再按照时序要求从总线上读取1个字节,最后将温度数值显示在LCD1602液晶上,读温度主要函数如下:

uint read_temp()

{ ow_reset(); //总线复位,检测存在脉冲

delay2(200);

write_byt(0xcc); //发命令,跳过ROM,因为只有一个18B20

write_byt(0x44); //发转换命令,启动温度转换

ow_reset(); // 检测存在脉冲

delay2(1);

write_byt(0xcc); //发命令

write_byt(0xbe); //读暂存寄存器

temp_data[0]=read_byt(); //读温度值的低字节

temp_data[1]=read_byt(); //读温度值的高字节

temp1=temp_data[1];

temp1<<=8; //高字节移到高8位

temp1=temp1|temp_data[0]; // 两字节合成一个整型变量

return temp1; //返回温度值

}

因为DS18B20可以检测负温度,在程序编写时,由查DS18B20温度数据转化表可得,只要判断temp1>(2047-63489)即为负温度,通过语句“display[8]=display[9]/100; display[4]=display[9]/10%10; display[2]=display[9]%10;”实现温度数字不同位数分离后显示。

4 LCD1602液晶显示设计

4.1 LCD1602读写函数

编程时,为了操作方便,对液晶显示第一行、第二行进行宏定义,数据地址指针设置“80H+”,即:第一行定义为“#define yh 0x80”,第二行 定义为“#define er 0x80+0x40”。查阅LCD1602手册中指令说明,进行液晶的初始化[5]:

void lcd_init()

{ write_1602com(0x38); //设置液晶工作模式

write_1602com(0x0c); //开显示不显示光标;显示开/关及光标显示

write_1602com(0x06); //整屏不移动,光标自动右移加1

write_1602com(0x01); //数据指针清零,所有显示清零

}

根据LCD1602的读写时序:读状态 RS=0,R/W=1,E=1(判断忙完毕后释放总线);读数据RS=1,R/W=1,E=1;写指令RS=0,R/W=0,D0~D7=指令码,E=高脉冲和写数据RS=1,R/W=0 ,D0~D7=数据,E=高脉冲编写1602液晶的读写指令/数据函数,以下是液晶写入指令和数据函数:

/*------液晶写入指令函数------*/

void write_1602com(uchar com)

{ rs=0; //数据/指令选择置为指令; RS=0

rw=0; //读写选择置为写 ;R/W=0

P0=com; //送入指令; P0=指令码

delay(1);

en=1; //拉高使能端,为下降沿做准备

delay(1);

en=0; //EN由高变低,产生下降沿,液晶执行命令,即,EN=高脉冲

}

/*-----液晶写入数据函数--------*/

void write_1602dat(uchar dat)

{ rs=1; //数据/指令选择置为数据; RS=1

rw=0; //读写选择置为写;R/W=0

P0=dat; //送入数据;P0=数据

delay(1);

en=1; //EN置高电平,为下降沿做准备

delay(1);

en=0; //EN由高变低,产生下降沿,液晶执行命令,即,EN=高脉冲

}

4.2 LCD1602显示设置

DS1302的时钟参数和DS18B20的温度数据最终要由LCD1602进行显示,通过分离出来的个位或十位数值加“30”或空字符转化为ASCII码在液晶上显示[6],显示年月日函数如下,

/*------年月日显示函数------*/

void write_nyr(uchar add,uchar dat)

{ uchar gw,sw;

gw=dat%10; //取得个位数字

sw=dat/10; //取得十位数字

write_1602com(yh+add); //设定显示位置为第一个位置+add

write_1602dat(0x30+sw); //数字+30得到该数字的LCD1602显示码

write_1602dat(0x30+gw); //数字+30得到该数字的LCD1602显示码

}

显示星期数值时,位置在第一行的屏幕显示的最后一个字节“write_1602com(yh+0x0f); ” ,因为 只有7种可能,所以采用“switch”语句完成,例如,“week1”为switch(week)

{case 1:write_1602dat('1'); break;…….},其它星期数雷同,不再赘述。

同理,可编写向LCD1602写温度数据,并指定显示位置显示出温度的整数和小数部分数值。

5 按键与闹钟模块

时间设置时,要先按下设置按键,设置按键共有“秒”、“分”、“时”、“星期”、“日”、“月”、“年”和“返回”共8个功能循环,按键按下一次时,“秒”闪烁,可以对“秒”进行“加”“减”调整,按两次时,“分”闪烁,以此类推,按键按下次数不同,可依次调整DS1302的时间、日期和星期的显示,直到按下第8次退出时间设置[7],光标不闪烁,LCD1602“显示开关及光标设置”指令码为“0x0c”。主要程序如下:

switch(key1)

{ case 1: TR0=0; //关闭定时器

write_1602com(er+0x08); //设置按键按动一次,秒位置显示光标

write_1602com(0x0f); //设置光标为闪烁

temp=(miao)/10*16+(miao)%10; //秒数据写入DS1302

write_1302(0x8e,0x00);

write_1302(0x80,0x80|temp);

write_1302(0x8e,0x80); break;

case 2: write_1602com(er+5); break; //按2次“分”显示光标

case 3: write_1602com(er+2); break; //按3次,“时”显示光标

case 4: write_1602com(yh+0x0f); break; //按4次,“week ” 显示光标

case 5: write_1602com(yh+0x09); break;//按5次,“日”显示光标

case 6: write_1602com(yh+0x06); break;//按6次,“月”显示光标

case 7: write_1602com(yh+0x03); break; //按7次,“年”显示光标

case 8: write_1602com(0x0c); //按8次,设置光标不闪烁

TR0=1; //打开定时器

temp=(miao)/10*16+(miao)%10;

write_1302(0x8e,0x00);

write_1302(0x80,0x00|temp); //秒数据写入DS1302

write_1302(0x8e,0x80); break; }

在上述程序中,按下除“返回”的任意次数时,光标闪烁,再按下“加”或“减”按键时,可以对“秒”进行“加”“减”调整,同理可以实现时分年月日和星期的加减设置,以“秒”加为例,主要代码如下:

switch(key1)

{ case 1:miao++; //设置键按动1次,调秒

if(miao==60)

miao=0;

write_sfm(0x07,miao);

temp=(miao)/10*16+(miao)%10;

write_1302(0x8e,0x00);

write_1302(0x80,temp);

write_1302(0x8e,0x80);

write_1602com(er+0x08);

break;……}

闹钟设置时,要先按下“定时”按键,然后再按“设置”按键,闹钟主要实现对“分”和“时”的设置以及闹钟“开关”3个功能状态。闹钟打开,则在LCD1602上显示“ON”,关闭闹钟则显示“OFF”。

该系统的主函数主要是对各个功能函数进行调用,代码如下:

void main( )

{ lcd_init( ); //调用液晶屏初始化子函数

ds1302_init( ); //调用DS1302时钟的初始化子函数

init( ); //调用定时计数器的设置子函数

buzzer=0; //蜂鸣器长响一次

delay(30);

buzzer=1;

key4=2;

b=1; //背光灯标志位打开

t=0; //背光灯定时器计数清零

while(1) //无限循环下面的语句

{ keyscan( ); //按键扫描

bj( ); //闹钟启动

} }

6 仿真与实物图

万年历仿真图如图2所示,程序中时间设置按键“key1”和单片机“P1^6”相连,时间加键“key2”和“P1^5”连接,时间减键“key3”和“P1^7”连接,闹钟定时键“key4”和“P1^3”连接,蜂鸣器接在单片机“P3^7”,通过三极管9012驱动,端口低电平蜂鸣器报警;LCD1602的使能引脚“E”、数据/命令选择端“RS”和读/写选择端“R/W”分别和接到单片机的“P2^2”、“P2^0”和“P2^1”端口[8],实物制作时,注意引脚连接次序。此外,LCD1602的2脚(电源正极)和15脚(背光正极)都接+5V,1脚(电源负极)接地,16脚(背光负极)接“P2^6”,仿真图中由于液晶没有显示第16引脚,所以没有画出,在焊接电路时接“P2^6”,通过编程实现其显示超过60秒后背光灯变暗[9],如图3所示,3脚“液晶显示偏压信号”接103(10K)电位器,调节液晶显示清晰度,调整到约1.5K。LCD1602的7-14脚接P0口(P0^0-P0^7),焊接时,考虑到整体效果布局,将部分元件装配到了焊接面,将单片机芯片安装在液晶下面,同时,为了使用方便,该万年历的电源除可用直流稳压电源供电,也设计了USB接口。

图2 万年历仿真电路

图3 万年历实物制作

7 结束语

系统设计以STC89C52为主控制单元,通过C语言编程进行软件设计,便于扩展和维护,功能设计较全面,可显示时间、 日期、 星期、 温度和闹钟等功能,具有读取方便、显示直观、成本低廉等优点,同时,由于各模块相互独立,也彰显了程序模块化设计的优越性,最后进行了实物制作以检验程序和仿真电路的可行性。

[1] 杨程凯,唐绪伟. 一种电子万年历的设计与实现[J]. 电子技术与软件工程, 2014(29):150.

[2] 苏畅. 基于单片机控制的LCD显示万年历制作[J]. 长江大学学报(自科版),2013(22):77-79.

[3] 李杨.基于AT89S52单片机的电子万年历设计与实现[J]. 无线互联科技,2014(9):171-174.

[4] 陈佳,高维松.基于桌面的多功能万年历设计与开发[J]. 软件导刊,2013(2):72-73.

[5] 何乃味.基于LED点阵显示的电子万年历的设计与实现[J]. 安徽电子信息职业技术学院学报, 2014(1): 9-13.

[6] 曹姣.基于单片机的多功能电子万年历设计[J]. 伺服控制,2012(7): 78-80.

[7] 查荣.基于单片机的多功能万年历设计[J]. 机械制造与自动化,2012(3): 137-139.

[8] 林志谋. 基于单片机的红外遥控和温度指示的万年历设计[J]. 清远职业技术学院学报,2015(3):83-86.

[9] 刘洪利,赵萍. 基于1-Wire总线的万年历设计[J]. 上海电力学院学报,2012(7):246-248.

System Simulation and Implementation of Permanent Calendar Based on STC89C52

Guo Zhanmiao

(Institute of Electronic Engineering, Xi’an Aeronautical Polytechnic Institute, Xi’an 710089, China)

Based on STC89C52, the paper designs a permanent calendar system which can display time, date, week and temperature. DS1302 is a kind of permanent calendar chip that can reckon time,including of seconds, minutes, hours, year, month,day week and so on. Besides, the DS18B20 has the function of temperature acquisition. There are four buttons in the permanent calendar system besides the reset button, one could add or subtract time, set alarm and buzzer warning by operating the buttons. All the phenomena can be real-time displayed and achieved human-computer interaction function via the LCD 1602. The author has written the C program by using the Keil software, simulated circuit diagram to reduce the blindness of welding by Proteus, and made physical circuit realize the integration of design, simulation and production. The design realizes the combination of theory and practice of practical significance.

STC89C52; Permanent calendar; Temperature display; Timing; Proteus simulation

西安航空职业技术学院院级教改课题(14xhjg012)

郭占苗(1981-) ,女,内蒙古集宁人,西安航空职业技术学院,电子工程学院,讲师,硕士,研究方向:电子实训的教学与研究,西安 710098

1007-757X(2017)02-0030-05

TP399

A

2016.00.00)

免责声明

我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!