基于51单片机公交报站系统
(仿真+程序)
功能介绍
具体功能:
1.用LCD12864播报站台,显示当前站台和下一站;
2.一共写入五个站台循环播放;
3.按键按下显示下一站;
演示视频:
基于51单片机公交报站系统—5个地名
添加图片注释,不超过 140 字(可选)
程序
/*********************
公交报站系统
/***公众号:木子单片机****
************************************/
#include <AT89X52.h>
#include <intrins.h>
#include<math.h>
#include"ZB.h"
#define uchar unsigned char
#define uint unsigned int
#define LCD_databus P0 //LCD12864的8位数据口
sbit RS=P2^2; //RS为0---命令;1----数据
sbit RW=P2^1; //RW为1---写;0---读
sbit EN=P2^0; //使能端
sbit CS1=P2^4; //片选1低电平有效,控制左半屏
sbit CS2=P2^3; //片选1低电平有效,控制右半屏
sbit KEY=P3^2;
uchar z_n=0;
void Read_busy()//读“忙”函数-----数据线的最高位DB71则busy
{
P0=0x00;
RS=0;
RW=1;
EN=1;
while(P0 & 0x80);
EN=0;
}
void write_LCD_command(uchar value) //写命令函数
{
Read_busy(); //对LCD的每次读写都要读忙
RS=0; //选择命令
RW=0; //读操作
LCD_databus=value;
EN=1; //EN由1----0锁存有效数据
_nop_();
_nop_();
EN=0;
}
void write_LCD_data(uchar value)//写数据函数
{
Read_busy();
RS=1; //选择数据
RW=0;
LCD_databus=value;
EN=1; //EN由1----0锁存有效数据
_nop_();
_nop_();
EN=0;
}
uchar Read_LCD(void) //读数据函数
{
uchar value;
Read_busy();
LCD_databus=0xFF; //先进行一次空读操作
RS=1;
RW=1;
EN=1;
_nop_();
_nop_();
EN=0;
LCD_databus=0xFF; //读取真正的数据
RS=1;
RW=1;
EN=1;
value=LCD_databus;
_nop_();
_nop_();
EN=0;
return value;
}
void Set_page(uchar page) //设置“页”LCD12864共8页,一页是8行点阵点
{
page=0xb8|page; //页的首地址为0xB8
write_LCD_command(page);
}
void Set_line(uchar startline) //设置显示的起始行
{
startline=0xC0|startline; //起始行地址为0xC0
write_LCD_command(startline); //设置从哪行开始:共0--63;一般从0 行开始显示
}
void Set_column(uchar column) //设置显示的列
{
column=column &0x3f; //列的最大值为64
column= 0x40|column; //列的首地址为0x40
write_LCD_command(column); //规定显示的列的位置
}
void SetOnOff(uchar onoff) //显示开关函数:0x3E是关显示,0x3F是开显示
{
onoff=0x3e|onoff; //onoff:1---开显示;0---关显示
write_LCD_command(onoff);
}
void SelectScreen(uchar screen) //选择屏幕
{
switch(screen)
{
case 0: CS1=0;CS2=0;break; //全屏
case 1: CS1=0;CS2=1;break;//左半屏
case 2: CS1=1;CS2=0;break;//右半屏
default:break;
}
}
void ClearScreen(uchar screen) //清屏函数
{
uchar i,j;
SelectScreen(screen); //0--全屏;1---左半屏;2---右半屏
for(i=0;i<8;i++) //控制页数0-7,共8页
{
Set_page(i);
Set_column(0);
for(j=0;j<64;j++) //控制列数0-63,共64列
{
write_LCD_data(0x00); //写入0,地址指针自加1
}
}
}
void InitLCD() //LCD的初始化
{
SetOnOff(1); //开显示
SelectScreen(0);
ClearScreen(0); //清屏
Set_line(0); //开始行:0
}
void Draw_dots(uchar x,uchar y,uchar color)
{
uchar x_byte;
uchar x_bit;
uchar Temp_data; //暂时存放从LCD读出的数据
x_byte=(y>>3); //计算出该点属于哪个字节
x_bit=y-(x_byte<<3); //属于字节的哪一位?
if(x>63) //x>63则显示在右半屏
{
SelectScreen(2);
x=x-64;
}
else //显示在左半屏
{
SelectScreen(1);
}
Set_page(x_byte); //设置行地址
Set_column(x); //设置列地址
Temp_data=Read_LCD(); //先读出没打点前LCD中的数据
switch(color)
{
case 0x01 : Temp_data &= ~(1<<x_bit);break; //擦除
case 0x02 : Temp_data ^= (1<<x_bit); break; //反白
case 0x03 : Temp_data |= (1<<x_bit); break; //画点
default : break;
}
Set_page(x_byte);
Set_column(x);
write_LCD_data(Temp_data); //将处理后的数据送到LCD中显示
}
void Display_HZ(uchar ss,uchar page,uchar column,uchar *p)
{
uchar i;
SelectScreen(ss);
Set_page(page); //写上半页
Set_column(column*16); //控制列
for(i=0;i<16;i++) //控制16列的数据输出
{
write_LCD_data(p[i]); //汉字的上半部分
}
Set_page(page+1); //写下半页
Set_column(column*16); //控制列
for(i=0;i<16;i++) //控制16列的数据输出
{
write_LCD_data(p[i+16]); //汉字的下半部分
}
}
void Display_picture(uchar a[][64])//显示图形--坐标
{
uchar i,j;
for(j=0;j<6;j++)
{
SelectScreen(1);
Set_page(j+2); //从第三页开始显示
Set_column(0);
for(i=0;i<64;i++)
{
write_LCD_data(a[2*j][i]);//每隔一行取一次数组中的数据
}
SelectScreen(2);
Set_page(j+2);
Set_column(0);
for(i=0;i<64;i++)
{
write_LCD_data(a[2*j+1][i]);//每隔一行取一次数组中的数据
}
}
}
void delayms(uint t)
{
uint i,j;
for(i=0;i<t;i++)
for(j=0;j<110;j++);
}
void read_key()
{
if(KEY==0)
{
delayms(15);
if(KEY==0)
{
z_n++;
if(z_n>4) z_n=0;
}
}
}
void dis_zhan(uchar t)
{
if(t==0)
{
Display_HZ(1,3,0,nan);
Display_HZ(1,3,1,shi);
Display_HZ(1,3,2,qu);
Display_HZ(1,3,3,zheng);
Display_HZ(2,3,0,fu);
Display_HZ(1,6,3,jun);
Display_HZ(2,6,0,xiao);
Display_HZ(2,6,1,guang);
Display_HZ(2,6,2,chang);
Display_HZ(2,6,3,kong);
}
else if(t==1)
{
Display_HZ(1,3,0,jun);
Display_HZ(1,3,1,xiao);
Display_HZ(1,3,2,guang);
Display_HZ(1,3,3,chang);
Display_HZ(2,3,0,kong);
Display_HZ(1,6,3,dong);
Display_HZ(2,6,0,feng);
Display_HZ(2,6,1,gong);
Display_HZ(2,6,2,yuan);
Display_HZ(2,6,3,kong);
}
else if(t==2)
{
Display_HZ(1,3,0,dong);
Display_HZ(1,3,1,feng);
Display_HZ(1,3,2,gong);
Display_HZ(1,3,3,yuan);
Display_HZ(2,3,0,kong);
Display_HZ(1,6,3,ke);
Display_HZ(2,6,0,yun);
Display_HZ(2,6,1,zhong);
Display_HZ(2,6,2,xin);
Display_HZ(2,6,3,kong);
}
else if(t==3)
{
Display_HZ(1,3,0,ke);
Display_HZ(1,3,1,yun);
Display_HZ(1,3,2,zhong);
Display_HZ(1,3,3,xin);
Display_HZ(2,3,0,kong);
Display_HZ(1,6,3,shui);
Display_HZ(2,6,0,li);
Display_HZ(2,6,1,ju);
Display_HZ(2,6,2,kong);
Display_HZ(2,6,3,kong);
}
else if(t==4)
{
Display_HZ(1,3,0,shui);
Display_HZ(1,3,1,li);
Display_HZ(1,3,2,ju);
Display_HZ(1,3,3,kong);
Display_HZ(2,3,0,kong);
Display_HZ(1,6,3,nan);
Display_HZ(2,6,0,shi);
Display_HZ(2,6,1,qu);
Display_HZ(2,6,2,zheng);
Display_HZ(2,6,3,fu);
}
}
硬件设计
使用元器件:
单片机:AT89C52;
(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)
添加图片注释,不超过 140 字(可选)
设计资料
01仿真图
本设计使用proteus7.8和proteus8.9两个版本设计!具体如图!
添加图片注释,不超过 140 字(可选)
02程序
本设计使用软件keil5版本编程设计!具体如图!
添加图片注释,不超过 140 字(可选)
03设计资料
资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)等。具体内容如下,全网最全! !
可以关注下方公众号!
点赞分享一起学习成长。