目录
一、主要功能
基于51单片机,采用DS1302时钟模块读取时间,通过LCD12864显示实时时间,然后两个按键,一个按下表示到站,一个按下表示没到站。
到达站点,蜂鸣器发出声音,屏幕显示到站,通过串口发送信息
如果没到站,屏幕显示未到站,通过串口发送信息
二、硬件资源
基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。
编辑
三、程序编程
#include <reg51.h>#include "DS18B20.h"#include "DS1302.h"#include "LCD12864.h"#include <stdio.h>sbit beep=P2^7;char a;
sbit key1 = P3^6;
sbit key2 = P3^7;void ajpd();/***按键触发标志位***/bit flag=1; //进入/退出设置标志void ckdy();// 定义一个结构体来存储时间信息typedef struct { int year; int month; int day; int hour; int minute; int second; int weekend;
} TimeInfo;TimeInfo convert\_to\_time_info(int time\[\]);/***按键触发实现函数***/void delay10(void) //延时10ms{ unsigned char i,j; for(i=0; i<255; i++) for(j=0; j<200; j++);
}void delay5ms(void) //误差 0us{ unsigned char a,b; for(b=19; b>0; b--) for(a=130; a>0; a--);
}//设置时ds1302寄存器值循环 如秒寄存器59时加一变为00unsigned char conver(unsigned char a,unsigned char b,unsigned char c){ if((a&0x0f)==0x0a) a=a+6; if(a==b) a=c; return a;
}void digplay() { //时间
ShowNumber16_32(2,0,TIME\[2\]>>4&0x03); //时 十位
ShowNumber16_32(2,16, TIME\[2\]&0x0f);//时 个位
ShowNumber16_32(2,48,TIME\[1\]>>4&0x07);//分 十位
ShowNumber16_32(2,64, TIME\[1\]&0x0f);//分 个位
ShowNumber16_32(2,96,TIME\[0\]>>4&0x07);//秒 十位
ShowNumber16_32(2,112, TIME\[0\]&0x0f);//秒 个位
//日期
ShowNumber(0,0,2); ShowNumber(0,8,0); ShowNumber(0,16,TIME\[6\]>>4&0x0f); ShowNumber(0,24, TIME\[6\]&0x0f);//年
ShowNumber(0,40,TIME\[4\]>>4&0x01); ShowNumber(0,48, TIME\[4\]&0x0f);//月
ShowNumber(0,64,TIME\[3\]>>4&0x03); ShowNumber(0,72, TIME\[3\]&0x0f);//日
ShowChina(0,112,(TIME\[5\]&0x07)-1);//周}void digplaystart() {//开机显示
uchar i=0; ShowChina(2,64-16\*1.5,19); ShowChina(2,64-16\*0.5,20); ShowChina(2,64+16\*0.5,21); ShowChina(2,64+16\*1.5,22); for (i=0; i<10; i++) { ShowNumber(4,32+8*i,16); delay5ms(); delay5ms();
} ClearScreen(0);//清屏}void Com0_Init(void){
TMOD =0x20; //设T0为方式1,GATE=1;
SCON=0x50; //开启串口
TH1=0xFD; //波特率是9600bps
TL1=0xFD;
TR1=1; //开启定时器
TI=1;
EA=1;
}
TimeInfo time_info; // 在 main 函数外部声明 TimeInfo 结构体实例void main(void){ InitLCD(); //初始化LCD12864
Com0_Init();//串口初始化
digplaystart(); delay5ms(); ShowNumber(0,32,11);//-
ShowNumber(0,56,11);//-
ShowChina(0,96,7);//汉字周
ShowNumber16_32(2,32,10);//:
ShowNumber16_32(2,80,10);//:
beep = 0; while(1)
{
if(flag==1) Ds1302ReadTime(); //读取DS1302的时间
else
{ Ds1302WriteTime();
}
ajpd();//按键判断
digplay();
time\_info = convert\_to\_time\_info(TIME); // 将 TIME 数组中的时间信息转换为 TimeInfo 结构体
}
}// 函数将 TIME 数组中的时间信息转换为 TimeInfo 结构体TimeInfo convert\_to\_time_info(int time\[\]) {
TimeInfo info;
info.year = 2000+(TIME\[6\] >> 4 & 0x0f) * 10 + (TIME\[6\] & 0x0f);
info.month = (TIME\[4\]>>4&0x01)*10 + (TIME\[4\]&0x0f);
info.day = (TIME\[3\]>>4&0x03)*10 + (TIME\[3\]&0x0f);
info.hour = (TIME\[2\]>>4&0x03)*10 + (TIME\[2\]&0x0f);
info.minute = (TIME\[1\]>>4&0x07)*10 + (TIME\[1\]&0x0f);
info.second = (TIME\[0\]>>4&0x07)*10 + (TIME\[0\]&0x0f); return info;
}void ajpd(){ if(!key1)
{// InitLCD();
ShowChina(6,0,26);//已
ShowChina(6,16,23);//到
ShowChina(6,32,24);//站
beep = 1; // 使用 PRINTF 函数打印时间信息
printf("当前时间是:%04d-%02d-%02d %02d:%02d:%02d ",
time\_info.year, time\_info.month, time_info.day,
time\_info.hour, time\_info.minute, time_info.second); printf("周四\\n"); printf("已到站\\n"); while(!key1);
}
if(!key2)
{// InitLCD();
ShowChina(6,0,25);//未
ShowChina(6,16,23);//到
ShowChina(6,32,24);//站
beep = 0; // 使用 PRINTF 函数打印时间信息
printf("当前时间是:%04d-%02d-%02d %02d:%02d:%02d ",
time\_info.year, time\_info.month, time_info.day,
time\_info.hour, time\_info.minute, time_info.second); printf("周四\\n"); printf("未到站\\n"); while(!key2);
}
}
四、实现现象
具体动态效果看B站演示视频:
基于51单片机的公交车报站
全部资料(源程序、仿真文件、安装包、演示视频、串口演示视频和串口资料):
链接:https://pan.baidu.com/s/11AnOZLdbq16o84nyJ52ZRQ?pwd=1i0i
提取码:1i0i