一、设计要求
(1)基本部分:作品要利用CPU最小系统外至少5部分硬件电路以同时实现功能,包括但不限于LED、KB、BP、LCD、EEPROM、UART;
(2)创优部分:包括但不限于驱动外接模块、实现算法逻辑、自创硬件;
二、作品介绍
该电子万年历使用AT89C52为核心,采用LCD1602液晶屏显示,动态显示时间,同时以蜂鸣器作为闹钟声音,融合超声波测距模块(HC-SRO4)实现对闹钟的关闭;具体功能如下:
1、显示年月日周,显示格式为“年-月-日 周”;
2、显示时分秒,显示格式为“时-分-秒”;
3、通过按键控制来设置时间以及闹钟,并显示闹钟;
4、显示超声波测距的结果,当闹钟响起,只需要手掌靠近单片机10cm以内即可关闭闹钟;
主体功能原理简介:
1、闹钟模块(蜂鸣器):
充当电子万年历中的闹铃,接通电源后振荡器产生音频信号通过电磁线圈,使电磁线圈产生磁场,振动膜片在电磁线圈和磁铁的相互作用下,周期性振动发声;可通过改变频率控制蜂鸣器音调;
2、控制模块(独立按键):
这里使用独立按键来对电子万年历进行控制,按下K3停止计时进入设置状态,K1移动设置点,K2使设置点所在的时间加一,K4使用设置点的时间单位来设置闹钟,比如K1移动到小时,按下K2小时数加一,按下K4会设置一个1小时的闹钟,再次按下K3恢复计时;
独立按键的原理是按下接通电路,松开断开电路,但这个过程的信号波形并不是完美的矩形波,在按下与松开这俩个过程均存在一定的抖动;
3、液晶显示模块(LCD1602):
这里使用LCD1602液晶显示模块来显示时间,闹钟,以及超声波测距的距离,并实时更新变化;
在液晶模块的初始化中需要先设置其显示模式,并且在液晶模块显示字符时光标是自动右移的,无须人工干预;要显示字符时要求先输入显示字符的地址,并且液晶显示屏中第一个字符的地址为40H,若要输入第二行,则需要将需要显示字符的地址位置加80H,即第二行第一个字符应该写入的数据是(40H+80H);
在其初始化过程中,若要写入命令,则需要将使能端RS电平拉低,若是写入数据,则将RS电平设置为高电平;
LCD1602一些关键指令设置:
4、时钟模块(DS1302):
这里时钟模块主要负责计时,按照开始设定的时间,通电后就开始走动;内含31个字节静态RAM;采用串行数据传送方式,数据以BCD的形式传送,因此在程序中要将字符数据转换成BCD码的形式,即加上0X30;在I/O数据输入输出过程中,控制指令输入下一个SCLK时钟的上升沿时,数据被写入DS1302数据输入从0开始;也同样在控制指令字之后的下一个SCLK脉冲的下降沿读取DS1302的数据,读取也是从低位0到高位7;
并且需要注意的是,一次读写操作至少读写俩个字符,一个是控制字节,一个是命令,告诉单片机是读还是写;
5、超声波模块(HC-SRO4):
超声波模块主要负责测试开发板与周围障碍物距离,便于控制闹钟的关闭,而不需要使用按键去控制,这样显得更加方便和智能;
给它提高一个10uS以上得脉冲触发信号该模块内部将发出8个40kHZ周期电平并检测回波;然后通过发送信号与收到回波的时间间隔来计算距离;
C语言代码:
#include"reg52.h"
#include"intrins.h"
#超声波接线说明 Trig ------- P2^1;Echo ------- P2^0;VCC -------- +5v; GND -------- GND
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
//---秒分时日月周年 最低位读写位;-------//
u8 code READ_RTC_ADDR[7] = {
0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
u8 code WRITE_RTC_ADDR[7] = {
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
u8 TIME[7] = {
1, 0, 0x18, 0x26, 0x12, 0x00, 0x20};
u8 CLOCK=0;
unsigned char code ASCII[15] = {
'0','1','2','3','4','5','6','7','8','9','.','-','M'};
//PIN口定义
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;
//---定义ds1302使用的IO口---//
sbit DSIO=P3^4;
sbit RST=P3^5;
sbit SCLK=P3^6;
//超声波接口
sbit Trig = P2^1;
sbit Echo = P2^0;
//管脚接线
sbit beep=P1^5;
sbit K1=P3^1;
sbit K2=P3^0;
sbit K3=P3^2;
sbit K4=P3^3;
u8 SetState,SetPlace;
u16 dis=0;
u8 noise_time0,noise_time1;
unsigned long S=0;
bit flag =0;
u8 disbuff[4] ={
0,0,0,0};
//闹钟标志
u8 rang_flag=0;
u8 r_flag=0;
u8 r1_flag=0;
//延时函数
void delay(u16 i) //当i=1,大约延时10us
{
while(i--);
}
//DS1302写入命令(地址加数据)
void Ds1302Write(u8 addr, u8 dat)
{
u8 n;
RST = 0;
_nop_();
SCLK = 0;//先将SCLK置低电平。
_nop_();
RST = 1; //然后将RST(CE)置高电平。
_nop_()