当前位置: 首页 > news >正文

【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_lcd[10];
#include "lcd12864bu.h"
/******************显示时间函数***************************/
void dis_shijian()    //显示时间
{
 write_shu16(0,0*8,shi,0);
 write_shuzi(1,0*2,2*8,fuhao[1],0);        
 write_shu16(0,3*8,fen,0);    
 write_shuzi(1,0*2,5*8,fuhao[1],0);        
 write_shu16(0,6*8,miao,0);

 write_yhanzi(2,0,5*16,qita[6]-1);   //星期
 //write_shu16(0,14*8,week,0);
 if(week==0)
 {
  write_yhanzi(1,0,7*16,xingqi[0]);
 }
 if(week==1)
 {
  write_yhanzi(1,0,7*16,xingqi[1]);  
 }
 if(week==2)
 {
  write_yhanzi(1,0,7*16,xingqi[2]);   
 }
 if(week==3)
 {
  write_yhanzi(1,0,7*16,xingqi[3]);   
 }
 if(week==4)
 {
  write_yhanzi(1,0,7*16,xingqi[4]);   
 }
 if(week==5)
 {
  write_yhanzi(1,0,7*16,xingqi[5]);   
 }
 if(week==6)
 {
  write_yhanzi(1,0,7*16,xingqi[6]);   
 }
 write_shu16(1*2,0*8,0x20,0);
 write_shu16(1*2,2*8,nian,0);
 write_shuzi(1,1*2,4*8,fuhao[0],0);    
 write_shu16(1*2,5*8,yue,0);
 write_shuzi(1,1*2,7*8,fuhao[0],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,xingqi[week]);            
}

/******************时间芯片显示函数**********************/       
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,xingqi[week]);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,yihaozhan[0]);   //一
  write_yhanzi(1,4,1*16,yihaozhan[1]);   //号
  write_yhanzi(1,4,2*16,yihaozhan[2]);   //站 

  write_yhanzi(1,4,4*16,erhaozhan[0]);   //二
  write_yhanzi(1,4,5*16,erhaozhan[1]);   //号
  write_yhanzi(1,4,6*16,erhaozhan[2]);   //站
    
    write_yhanzi(1,6,0*16,sanhaozhan[0]);   //三
  write_yhanzi(1,6,1*16,sanhaozhan[1]);   //号
  write_yhanzi(1,6,2*16,sanhaozhan[2]);   //站

  write_yhanzi(1,6,4*16,sinhaozhan[0]);   //四
  write_yhanzi(1,6,5*16,sinhaozhan[1]);   //号
  write_yhanzi(1,6,6*16,sinhaozhan[2]);   //站
  }
  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,daoda[0]);   //到
   write_yhanzi(1,4,1*16,daoda[1]);   //达
   write_shuzi(1,2*2,4*8,fuhao[1],0);//:

   write_yhanzi(1,6,0*16,xiayizhan[0]);   //下
   write_yhanzi(1,6,1*16,xiayizhan[1]);   //站
   write_shuzi(1,3*2,4*8,fuhao[1],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,daoda[0]);   //到
   write_yhanzi(1,4,1*16,daoda[1]);   //达
   write_shuzi(1,2*2,4*8,fuhao[1],0);//:

   write_yhanzi(1,6,0*16,xiayizhan[0]);   //下
   write_yhanzi(1,6,1*16,xiayizhan[1]);   //站
   write_shuzi(1,3*2,4*8,fuhao[1],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,yihaozhan[0]);   //一
  write_yhanzi(1,4,4*16,yihaozhan[1]);   //号
  write_yhanzi(1,4,5*16,yihaozhan[2]);   //站 

  write_yhanzi(1,6,3*16,erhaozhan[0]);   //二
  write_yhanzi(1,6,4*16,erhaozhan[1]);   //号
  write_yhanzi(1,6,5*16,erhaozhan[2]);   //站
          delay(500);
    
 }
 if(x_num==2)
 {
  write_yhanzi(1,4,3*16,erhaozhan[0]);   //二
  write_yhanzi(1,4,4*16,erhaozhan[1]);   //号
  write_yhanzi(1,4,5*16,erhaozhan[2]);   //站

  write_yhanzi(1,6,3*16,sanhaozhan[0]);   //三
  write_yhanzi(1,6,4*16,sanhaozhan[1]);   //号
  write_yhanzi(1,6,5*16,sanhaozhan[2]);   //站

 }

 if(x_num==3)
 {
  write_yhanzi(1,4,3*16,sanhaozhan[0]);   //三
  write_yhanzi(1,4,4*16,sanhaozhan[1]);   //号
  write_yhanzi(1,4,5*16,sanhaozhan[2]);   //站

  write_yhanzi(1,6,3*16,sinhaozhan[0]);   //四
  write_yhanzi(1,6,4*16,sinhaozhan[1]);   //号
  write_yhanzi(1,6,5*16,sinhaozhan[2]);   //站

 }
 if(x_num==4)
 {
  write_yhanzi(1,4,3*16,sinhaozhan[0]);   //四
  write_yhanzi(1,4,4*16,sinhaozhan[1]);   //号
  write_yhanzi(1,4,5*16,sinhaozhan[2]);   //站

  write_yhanzi(1,6,3*16,zhongdianzhan[0]);   //终
  write_yhanzi(1,6,4*16,zhongdianzhan[1]);   //点
  write_yhanzi(1,6,5*16,zhongdianzhan[2]);   //站

 }
 if(x_num==5)
 {
  write_yhanzi(1,4,3*16,zhongdianzhan[0]);   //终
  write_yhanzi(1,4,4*16,zhongdianzhan[1]);   //点
  write_yhanzi(1,4,5*16,zhongdianzhan[2]);   //站

  write_yhanzi(1,6,0*16,ganxiechengzuo[0]);   //感
  write_yhanzi(1,6,1*16,ganxiechengzuo[1]);   //谢
  write_yhanzi(1,6,2*16,ganxiechengzuo[2]);   //乘
  write_yhanzi(1,6,3*16,ganxiechengzuo[3]);   //坐
  write_yhanzi(1,6,4*16,ganxiechengzuo[4]);   //本
  write_yhanzi(1,6,5*16,ganxiechengzuo[5]);   //公
  write_yhanzi(1,6,6*16,ganxiechengzuo[6]);   //车
  


 }
 /******************************上行报站显示***********/
 if(s_num==1)
 {
      write_yhanzi(1,6,0*16,xiayizhan[0]);   //下
   write_yhanzi(1,6,1*16,xiayizhan[1]);   //站
   write_shuzi(1,3*2,4*8,fuhao[1],0); //:
     
  write_yhanzi(1,4,3*16,sinhaozhan[0]);   //四
  write_yhanzi(1,4,4*16,sinhaozhan[1]);   //号
  write_yhanzi(1,4,5*16,sinhaozhan[2]);   //站 

  write_yhanzi(1,6,3*16,sanhaozhan[0]);   //三
  write_yhanzi(1,6,4*16,sanhaozhan[1]);   //号
  write_yhanzi(1,6,5*16,sanhaozhan[2]);   //站

 }
 if(s_num==2)
 {
  write_yhanzi(1,4,3*16,sanhaozhan[0]);   //三
  write_yhanzi(1,4,4*16,sanhaozhan[1]);   //号
  write_yhanzi(1,4,5*16,sanhaozhan[2]);   //站

  write_yhanzi(1,6,3*16,erhaozhan[0]);   //二
  write_yhanzi(1,6,4*16,erhaozhan[1]);   //号
  write_yhanzi(1,6,5*16,erhaozhan[2]);   //站
 }
 if(s_num==3)
 {
  write_yhanzi(1,4,3*16,erhaozhan[0]);   //二
  write_yhanzi(1,4,4*16,erhaozhan[1]);   //号
  write_yhanzi(1,4,5*16,erhaozhan[2]);   //站

  write_yhanzi(1,6,3*16,yihaozhan[0]);   //一
  write_yhanzi(1,6,4*16,yihaozhan[1]);   //号
  write_yhanzi(1,6,5*16,yihaozhan[2]);   //站 
 }
 if(s_num==4)
 {
  write_yhanzi(1,4,3*16,yihaozhan[0]);   //一
  write_yhanzi(1,4,4*16,yihaozhan[1]);   //号
  write_yhanzi(1,4,5*16,yihaozhan[2]);   //站 

  write_yhanzi(1,6,3*16,zhongdianzhan[0]);   //终
  write_yhanzi(1,6,4*16,zhongdianzhan[1]);   //点
  write_yhanzi(1,6,5*16,zhongdianzhan[2]);   //站
 }
 if(s_num==5)
 {
  write_yhanzi(1,4,3*16,zhongdianzhan[0]);   //终
  write_yhanzi(1,4,4*16,zhongdianzhan[1]);   //点
  write_yhanzi(1,4,5*16,zhongdianzhan[2]);   //站

  write_yhanzi(1,6,0*16,ganxiechengzuo[0]);   //感
  write_yhanzi(1,6,1*16,ganxiechengzuo[1]);   //谢
  write_yhanzi(1,6,2*16,ganxiechengzuo[2]);   //乘
  write_yhanzi(1,6,3*16,ganxiechengzuo[3]);   //坐
  write_yhanzi(1,6,4*16,ganxiechengzuo[4]);   //本
  write_yhanzi(1,6,5*16,ganxiechengzuo[5]);   //公
  write_yhanzi(1,6,6*16,ganxiechengzuo[6]);   //车
 }
}

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();    //时钟显示函数,同时显示温度函数也在里面
  }
 }
}

五、实验现象

演示视频:


文章转载自:

http://TBH5rzX2.tqbyw.cn
http://Vk9xSDvA.tqbyw.cn
http://qMHA5sv2.tqbyw.cn
http://CL2miYSQ.tqbyw.cn
http://ffHKKYhm.tqbyw.cn
http://QCSPEZrR.tqbyw.cn
http://piRgyBdn.tqbyw.cn
http://HG8GtLCG.tqbyw.cn
http://XVfzrcHP.tqbyw.cn
http://8bqjhn8e.tqbyw.cn
http://UcD9kDlp.tqbyw.cn
http://3cUNCWwu.tqbyw.cn
http://qreJM7N5.tqbyw.cn
http://qKFSzv27.tqbyw.cn
http://PGX2tUV5.tqbyw.cn
http://G90jCLk5.tqbyw.cn
http://GuiAhCjV.tqbyw.cn
http://pJcvNWxE.tqbyw.cn
http://Nk4Abn5D.tqbyw.cn
http://UxOLLZiu.tqbyw.cn
http://jcMx6LPC.tqbyw.cn
http://4E2DNZay.tqbyw.cn
http://9VSp6tBI.tqbyw.cn
http://hGK5ecJK.tqbyw.cn
http://VStQnRaL.tqbyw.cn
http://CCaCoIig.tqbyw.cn
http://ShawF0YP.tqbyw.cn
http://piuE10tM.tqbyw.cn
http://sPt4O6GL.tqbyw.cn
http://YP2Ye6Yc.tqbyw.cn
http://www.dtcms.com/a/374322.html

相关文章:

  • linux常用命令(2)——系统管理
  • Yarn介绍与HA搭建
  • 记个笔记:Cocos打包安卓使用安卓通信模块
  • 基于Python的云原生TodoList Demo 项目,验证云原生核心特性
  • 2025年- H121-Lc28. 找出字符串中第一个匹配项的下标(数组)--Java版
  • 【底层机制】auto 关键字的底层实现机制
  • 【代码随想录算法训练营——Day6(Day5周日休息)】哈希表——242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和
  • leedcode 算法刷题第二八天
  • KafKa教程
  • 如何在 Ubuntu 22.04 中安装 Docker 引擎和 Linux 版 Docker Desktop 桌面软件
  • 基于RK3568/RK3588+全隔离串口+多电力协议接入电力网关机,用于新能源光伏风能等电站监测运维
  • 软件测试用例(沉淀中)
  • 华清远见25072班网络编程学习day1
  • 【Python办公】[ 网络剪切板 ]免费图床工具GUI界面打包(电脑上传-手机扫码下载)
  • [吾爱原创] 【游戏】王富贵的果菜园
  • Linux系统:线程同步与生产消费模型
  • 深入理解 IP 协议
  • NTP配置为客户端广播监听模式
  • QPS和RPM的全称
  • 打印机已联网,但打印机显示“未连接”,解决方案
  • 【Github | Git】如何彻底删除 SSH 密钥公钥:删除本地密钥公钥 删除GitHub密钥公钥
  • ARM 体系结构与存储器
  • <android>反编译魔改安卓系统应用并替换
  • 面试题:Redis要点总结(进阶)
  • Web安全基石:深入理解与防御SQL注入漏洞
  • PAT 1005 Spell It Right
  • 老子与coding
  • 机器学习之聚类算法
  • bash:trtexec:command not found
  • 今日分享:C++ Stack和queue(栈与队列)