【51单片机】【protues仿真】基于51单片机公交报站系统

目录

一、主要功能

二、使用步骤

三、硬件资源

四、软件设计

五、实验现象

一、主要功能

主要功能如下:

1、LCD12864显示时间、日期、公交车车站、温度等

2、按键设置时间,显示公交车信息

3、串口播报相应站点信息

4、按键控制上行、下行、手动播报站

5、LED指示上行、下行信息

二、使用步骤

基于51单片机的公交报站系统,lcd屏幕显示时间,温度,站点信息等等,通过按键来控制对应信息报站。

三、硬件资源

1、51单片机核心模块

2、按键模块

3、温度传感器

4、蜂鸣器模块

5、时钟模块

6、LCD12864显示模块

四、软件设计

#include <reg51.h>

#define uint unsigned int

#define uchar unsigned char

#include "value.h"

#include <UART.h>

sbit x_key=P1^3;

sbit s_key=P1^4;

sbit bz_key=P1^5;

sbit gb_key=P1^6;

sbit x_LED=P2^6;

sbit s_LED=P2^7;

sbit key_zhantai=P3^7;

sbit key_gongjiao=P1^7;

uchar x_mode,s_mode;

uchar x_num,s_num;

bit flag_200ms = 1;

uchar flag_c_en;

bit flag_100ms;

sbit dq=P3^2; //18b20 IO口的定义

uint temperature ; //温度变量

uint flag_zhantai ; //站台显示标志位

uint flag_gongjiao ; //公交显示标志位

/************ 延时函数 *****************/

void delay_uint(uint z)

{

while(z--);

}

/********************************************************************

* 名称 : delay_1ms()

* 功能 : 延时1ms函数

* 输入 : q

* 输出 : 无

***********************************************************************/

void delay_1ms(uint q)

{

uint i,j;

for(i=0;i<q;i++)

for(j=0;j<115;j++);

}

uchar dis_lcd10;

#include "lcd12864bu.h"

/******************显示时间函数***************************/

void dis_shijian() //显示时间

{

write_shu16(0,0*8,shi,0);

write_shuzi(1,0*2,2*8,fuhao1,0);

write_shu16(0,3*8,fen,0);

write_shuzi(1,0*2,5*8,fuhao1,0);

write_shu16(0,6*8,miao,0);

write_yhanzi(2,0,5*16,qita6-1); //星期

//write_shu16(0,14*8,week,0);

if(week==0)

{

write_yhanzi(1,0,7*16,xingqi0);

}

if(week==1)

{

write_yhanzi(1,0,7*16,xingqi1);

}

if(week==2)

{

write_yhanzi(1,0,7*16,xingqi2);

}

if(week==3)

{

write_yhanzi(1,0,7*16,xingqi3);

}

if(week==4)

{

write_yhanzi(1,0,7*16,xingqi4);

}

if(week==5)

{

write_yhanzi(1,0,7*16,xingqi5);

}

if(week==6)

{

write_yhanzi(1,0,7*16,xingqi6);

}

write_shu16(1*2,0*8,0x20,0);

write_shu16(1*2,2*8,nian,0);

write_shuzi(1,1*2,4*8,fuhao0,0);

write_shu16(1*2,5*8,yue,0);

write_shuzi(1,1*2,7*8,fuhao0,0);

write_shu16(1*2,8*8,ri,0);

write_shu18b20(1*2,12*8,temperature,0);

write_shuzi(1,1*2,14*8,dian,0);

}

/************初始化显示*****************/

void init_12864_dis() //初始化显示

{

cs1=1; //左屏开显示

cs2=0;

dis_shijian(); //显示时间

}

/***********************18b20初始化函数*****************************/

void init_18b20()

{

bit q;

dq=1; //把总线拿高

delay_uint(1); //15us

dq=0; //给复位脉冲

delay_uint(80); //750us

dq=1; //把总线拿高 等待

delay_uint(10); //110us

q=dq; //读取18b20初始化信号

delay_uint(20); //200us

dq=1; //把总线拿高 释放总线

}

/*************写18b20内的数据***************/

void write_18b20(uchar dat)

{

uchar i;

for(i=0;i<8;i++)

{ //写数据是低位开始

dq=0; //把总线拿低写时间隙开始

dq=dat&0x01; //向18b20总线写数据了

delay_uint(5); // 60us

dq=1; //释放总线

dat>>=1;

}

}

/*************读取18b20内的数据***************/

uchar read_18b20()

{

uchar i,value;

for(i=0;i<8;i++)

{

dq=0; //把总线拿低读时间隙开始

value>>= 1; //读数据是低位开始

dq=1; //释放总线

if(dq==1) //开始读写数据

value|=0x80;

delay_uint(5); //60us 读一个时间隙最少要保持60us的时间

}

return value; //返回数据

}

/*************读取温度的值 读出来的是小数***************/

uint read_temp()

{

uint value;

uchar low; //在读取温度的时候如果中断的太频繁了,就应该把中断给关了,否则会影响到18b20的时序

init_18b20(); //初始化18b20

write_18b20(0xcc); //跳过64位ROM

write_18b20(0x44); //启动一次温度转换命令

delay_uint(50); //500us

init_18b20(); //初始化18b20

write_18b20(0xcc); //跳过64位ROM

write_18b20(0xbe); //发出读取暂存器命令

EA=0;

low=read_18b20(); //读温度低字节

value=read_18b20(); //读温度高字节

EA =1;

value<<=8; //把温度的高位左移8位

value|=low; //把读出的温度低位放到value的低八位中

value*=0.625; //转换到温度值 小数

return value; //返回读出的温度 带小数

}

/******************显示时间函数***************************/

void dis_shijian_set() //显示时间

{

write_shu16(0*2,0*8,0x20,0);

write_shu16(1*2,2*8,shi,0);

write_shu16(1*2,6*8,fen,0);

write_shu16(1*2,10*8,miao,0);

write_shu16(0*2,2*8,nian,0);

write_shu16(0*2,6*8,yue,0);

write_shu16(0*2,10*8,ri,0);

write_yhanzi(1,4,5*16,xingqiweek);

}

/******************时间芯片显示函数**********************/

void ds1302_dis()

{

uchar miao_1;

if(menu_1 == 0)

{

read_time();

if(miao_1 != miao)

{

miao_1 = miao;

dis_shijian(); //显示时间

}

}

}

/********************独立按键程序*****************/

uchar key_can; //按键值

void key() //独立按键程序

{

static uchar key_new;

key_can=20; //按键值还原

P3|=0x78; //对应的按键IO口输出为1

if((P3&0x78)!=0x78) //按键按下

{

delay_1ms(1); //按键消抖动

if(((P3&0x78)!=0x78)&&(key_new==1))

{ //确认是按键按下

key_new=0;

switch(P3&0x78)

{

case 0x70:key_can=1;break; //得到按键值

case 0x68:key_can=2;break; //得到按键值

case 0x58:key_can=3;break; //得到按键值

case 0x38:key_can=4;break; //得到按键值

}

}

}

else

key_new=1;

}

/**********************设置函数************************/

void key_with()

{

if(key_can==4) //退出键

{

qingling();

init_12864_dis(); //初始化显示

flag_200ms=1;

menu_1=0;

}

if(key_can==1) //设置键

{

menu_1 ++;

flag_200ms=1;

if(menu_1==1)

{

x_num=0;

s_num=0;

x_mode=0;

s_mode=0;

qingling();

init_12864_set1();

}

if(menu_1>7)

menu_1 = 1;

}

if(menu_1!=0)

{

if(menu_1==1) //设置年

{

if(key_can==2) //加

set_ds1302time(1,&nian,0x99);

if(key_can==3) //减

set_ds1302time(0,&nian,0x99);

}

if(menu_1==2) //设置月

{

if(key_can==2) //加

set_ds1302time(1,&yue,0x13);

if(key_can==3) //减

set_ds1302time(0,&yue,0x13);

}

if(menu_1==3) //设置日

{

if(key_can==2) //加

set_ds1302time(1,&ri,0x32);

if(key_can==3) //减

set_ds1302time(0,&ri,0x32);

}

if(menu_1==4) //设置时

{

if(key_can==4) //加

set_ds1302time(1,&shi,0x24);

if(key_can==3) //减

set_ds1302time(0,&shi,0x24);

}

if(menu_1==5) //设置分

{

if(key_can==2) //加

set_ds1302time(1,&fen,0x60);

if(key_can==3) //减

set_ds1302time(0,&fen,0x60);

}

if(menu_1==6) //设置秒

{

if(key_can==2) //加

set_ds1302time(1,&miao,0x60);

if(key_can==3) //减

set_ds1302time(0,&miao,0x60);

}

if(menu_1==7) //设置星期

{

if(key_can==2) //加

set_ds1302time(1,&week,0x8);

if(key_can==3) //减

set_ds1302time(0,&week,0x8);

}

dis_shijian_set(); //显示时间

switch(menu_1) // 光标显示

{

case 1:write_shu16(0*2,2*8,nian,1);break;

case 2:write_shu16(0*2,6*8,yue,1);break;

case 3:write_shu16(0*2,10*8,ri,1);break;

case 4:write_shu16(1*2,2*8,shi,1);break;

case 5:write_shu16(1*2,6*8,fen,1);break;

case 6:write_shu16(1*2,10*8,miao,1);break;

case 7:write_yhanzi(1,4,5*16,xingqiweek);break;

}

write_time(); //把时间写进去

}

}

/*********************定时器0、定时器1初始化******************/

void time0_init()

{

EA=1; //开总中断

TMOD=0X11; //定时器0、定时器1工作方式1

ET0=1; //开定时器0中断

TR0=1; //允许定时器0定时

}

void baozhan()

{

if(key_zhantai==0)

{

delay_1ms(20);

if(key_zhantai==0)

{

qingling();

x_mode=1;

s_mode=0;

x_num=0;

s_num=0;

x_LED=0;

s_LED=0;

write_yhanzi(1,4,0*16,yihaozhan0); //一

write_yhanzi(1,4,1*16,yihaozhan1); //号

write_yhanzi(1,4,2*16,yihaozhan2); //站

write_yhanzi(1,4,4*16,erhaozhan0); //二

write_yhanzi(1,4,5*16,erhaozhan1); //号

write_yhanzi(1,4,6*16,erhaozhan2); //站

write_yhanzi(1,6,0*16,sanhaozhan0); //三

write_yhanzi(1,6,1*16,sanhaozhan1); //号

write_yhanzi(1,6,2*16,sanhaozhan2); //站

write_yhanzi(1,6,4*16,sinhaozhan0); //四

write_yhanzi(1,6,5*16,sinhaozhan1); //号

write_yhanzi(1,6,6*16,sinhaozhan2); //站

}

while(!key_zhantai);

}

if(x_key==0 || key_gongjiao==0)

{

delay_1ms(20);

if(x_key==0 || key_gongjiao==0)

{

qingling();

x_mode=1;

s_mode=0;

x_num=0;

s_num=0;

x_LED=0;

s_LED=1;

write_yhanzi(1,4,0*16,daoda0); //到

write_yhanzi(1,4,1*16,daoda1); //达

write_shuzi(1,2*2,4*8,fuhao1,0);//:

write_yhanzi(1,6,0*16,xiayizhan0); //下

write_yhanzi(1,6,1*16,xiayizhan1); //站

write_shuzi(1,3*2,4*8,fuhao1,0); //:

}

while((!x_key) || (!key_gongjiao));

}

if(s_key==0 || key_gongjiao==0)

{

delay_1ms(20);

if(s_key==0 || key_gongjiao==0)

{

qingling();

x_mode=0;

s_mode=1;

x_num=0;

s_num=0;

x_LED=1;

s_LED=0;

write_yhanzi(1,4,0*16,daoda0); //到

write_yhanzi(1,4,1*16,daoda1); //达

write_shuzi(1,2*2,4*8,fuhao1,0);//:

write_yhanzi(1,6,0*16,xiayizhan0); //下

write_yhanzi(1,6,1*16,xiayizhan1); //站

write_shuzi(1,3*2,4*8,fuhao1,0); //:

}

while((!s_key) || (!key_gongjiao));

}

if((bz_key==0)&&(x_mode==1))

{

delay(20);

if((bz_key==0)&&(x_mode==1))

{

x_num++;

x_num%=6;

}

while(!bz_key);

}

if((bz_key==0)&&(s_mode==1))

{

delay(20);

if((bz_key==0)&&(s_mode==1))

{

s_num++;

s_num%=6;

}

while(!bz_key);

}

if(gb_key==0)

{

delay_1ms(20);

if(gb_key==0)

{

x_mode=0;

s_mode=0;

x_num=0;

s_num=0;

x_LED=1;

s_LED=1;

qingling();

}

}

}

void yuyin()

{

/******************************下行报站显示***********/

if(x_num==1)

{

write_yhanzi(1,4,3*16,yihaozhan0); //一

write_yhanzi(1,4,4*16,yihaozhan1); //号

write_yhanzi(1,4,5*16,yihaozhan2); //站

write_yhanzi(1,6,3*16,erhaozhan0); //二

write_yhanzi(1,6,4*16,erhaozhan1); //号

write_yhanzi(1,6,5*16,erhaozhan2); //站

delay(500);

}

if(x_num==2)

{

write_yhanzi(1,4,3*16,erhaozhan0); //二

write_yhanzi(1,4,4*16,erhaozhan1); //号

write_yhanzi(1,4,5*16,erhaozhan2); //站

write_yhanzi(1,6,3*16,sanhaozhan0); //三

write_yhanzi(1,6,4*16,sanhaozhan1); //号

write_yhanzi(1,6,5*16,sanhaozhan2); //站

}

if(x_num==3)

{

write_yhanzi(1,4,3*16,sanhaozhan0); //三

write_yhanzi(1,4,4*16,sanhaozhan1); //号

write_yhanzi(1,4,5*16,sanhaozhan2); //站

write_yhanzi(1,6,3*16,sinhaozhan0); //四

write_yhanzi(1,6,4*16,sinhaozhan1); //号

write_yhanzi(1,6,5*16,sinhaozhan2); //站

}

if(x_num==4)

{

write_yhanzi(1,4,3*16,sinhaozhan0); //四

write_yhanzi(1,4,4*16,sinhaozhan1); //号

write_yhanzi(1,4,5*16,sinhaozhan2); //站

write_yhanzi(1,6,3*16,zhongdianzhan0); //终

write_yhanzi(1,6,4*16,zhongdianzhan1); //点

write_yhanzi(1,6,5*16,zhongdianzhan2); //站

}

if(x_num==5)

{

write_yhanzi(1,4,3*16,zhongdianzhan0); //终

write_yhanzi(1,4,4*16,zhongdianzhan1); //点

write_yhanzi(1,4,5*16,zhongdianzhan2); //站

write_yhanzi(1,6,0*16,ganxiechengzuo0); //感

write_yhanzi(1,6,1*16,ganxiechengzuo1); //谢

write_yhanzi(1,6,2*16,ganxiechengzuo2); //乘

write_yhanzi(1,6,3*16,ganxiechengzuo3); //坐

write_yhanzi(1,6,4*16,ganxiechengzuo4); //本

write_yhanzi(1,6,5*16,ganxiechengzuo5); //公

write_yhanzi(1,6,6*16,ganxiechengzuo6); //车

}

/******************************上行报站显示***********/

if(s_num==1)

{

write_yhanzi(1,6,0*16,xiayizhan0); //下

write_yhanzi(1,6,1*16,xiayizhan1); //站

write_shuzi(1,3*2,4*8,fuhao1,0); //:

write_yhanzi(1,4,3*16,sinhaozhan0); //四

write_yhanzi(1,4,4*16,sinhaozhan1); //号

write_yhanzi(1,4,5*16,sinhaozhan2); //站

write_yhanzi(1,6,3*16,sanhaozhan0); //三

write_yhanzi(1,6,4*16,sanhaozhan1); //号

write_yhanzi(1,6,5*16,sanhaozhan2); //站

}

if(s_num==2)

{

write_yhanzi(1,4,3*16,sanhaozhan0); //三

write_yhanzi(1,4,4*16,sanhaozhan1); //号

write_yhanzi(1,4,5*16,sanhaozhan2); //站

write_yhanzi(1,6,3*16,erhaozhan0); //二

write_yhanzi(1,6,4*16,erhaozhan1); //号

write_yhanzi(1,6,5*16,erhaozhan2); //站

}

if(s_num==3)

{

write_yhanzi(1,4,3*16,erhaozhan0); //二

write_yhanzi(1,4,4*16,erhaozhan1); //号

write_yhanzi(1,4,5*16,erhaozhan2); //站

write_yhanzi(1,6,3*16,yihaozhan0); //一

write_yhanzi(1,6,4*16,yihaozhan1); //号

write_yhanzi(1,6,5*16,yihaozhan2); //站

}

if(s_num==4)

{

write_yhanzi(1,4,3*16,yihaozhan0); //一

write_yhanzi(1,4,4*16,yihaozhan1); //号

write_yhanzi(1,4,5*16,yihaozhan2); //站

write_yhanzi(1,6,3*16,zhongdianzhan0); //终

write_yhanzi(1,6,4*16,zhongdianzhan1); //点

write_yhanzi(1,6,5*16,zhongdianzhan2); //站

}

if(s_num==5)

{

write_yhanzi(1,4,3*16,zhongdianzhan0); //终

write_yhanzi(1,4,4*16,zhongdianzhan1); //点

write_yhanzi(1,4,5*16,zhongdianzhan2); //站

write_yhanzi(1,6,0*16,ganxiechengzuo0); //感

write_yhanzi(1,6,1*16,ganxiechengzuo1); //谢

write_yhanzi(1,6,2*16,ganxiechengzuo2); //乘

write_yhanzi(1,6,3*16,ganxiechengzuo3); //坐

write_yhanzi(1,6,4*16,ganxiechengzuo4); //本

write_yhanzi(1,6,5*16,ganxiechengzuo5); //公

write_yhanzi(1,6,6*16,ganxiechengzuo6); //车

}

}

void main()

{

x_key=1;

s_key=1;

bz_key=1;

gb_key=1;

x_LED=1;

s_LED=1;

P0=P1=P2=P3=0xff; //单片机IO口初始化为1

init_ds1302();

delay_1ms(5);

init_lcd();

delay_1ms(5);

Clr_Scr();

time0_init();

delay_1ms(5);

init_12864_dis(); //初始化显示

delay_1ms(5);

uart_cfg();

while(1)

{

baozhan(); //显示上站和下站字头

yuyin(); //显示上站和下站是哪一站

key(); //改变key_san的值,判断K1-K4哪个键按下即设置时间的4个键哪个被按下

if(key_can<10)

{

key_with(); //根据key_san的值执行相应程序

}

if(flag_100ms==1)

{

flag_100ms=0;

}

if(flag_200ms==1) //200ms

{

flag_200ms=0;

temperature=read_temp(); //先读出温度的值

ds1302_dis(); //时钟显示函数,同时显示温度函数也在里面

}

}

}

五、实验现象

演示视频:

相关推荐
Mr..Jackey5 小时前
瑞佑 RUI Builder 图形化 UI 设计工具
arm开发·人工智能·单片机·ui·人机交互·ra8889·lcd控制芯片
西城微科方案开发8 小时前
多品类电子秤一体化PCBA整体方案
单片机·嵌入式硬件·电子秤
火花页.9 小时前
【正点原子ZYNQ领航者7020】PS端GPIO中断→按键控制LED实验
单片机·嵌入式硬件
ye150127774559 小时前
4.2V升6V1A同步升压WT3213
单片机·嵌入式硬件·其他·硬件工程
嵌入式小站10 小时前
STM32 可移植教程 02:按键状态机,消抖、长按、释放一行也不用多写(实战篇)
chrome·vscode·stm32·单片机·嵌入式硬件
Szime10 小时前
AD9694 国产替代方案:四通道高速 ADC 在通信与雷达项目中的选型参考
单片机·嵌入式硬件·fpga开发
智者知已应修善业10 小时前
【51单片机8位数码管同时倒计时从9999】2024-1-25
c++·经验分享·笔记·算法·51单片机
fanged11 小时前
Datasheet学习6(光机)
嵌入式硬件
Zyed12 小时前
[STM32]Day15读写FLASH+读取ID
前端·stm32·性能优化
芯岭技术郦12 小时前
高性能的 32 位 ARM® Cortex®-M0+内核PY32F002A
单片机·嵌入式硬件