哈尔滨工业大学(威海)校园测速Proteus仿真
实验目的
大学校园,是学生和教师生活、学习和工作的地方,校园内的道路属于人员密集区域,既要保证校园内的交通通行便利,又要保证教师和学生的安全,就要在学校校园内设定车辆限速,为了规范车辆的速度,需要测速系统进行监督。故设计这样一款基于超声波的校园车辆测速系统。
使用的模块器件
STC80C52单片机
STC89C51是采用8051核的ISP(In System Programming)在系统可编程芯片,最高工作时钟频率为80MHz,片内含4K Bytes的可反复擦写1000次的Flash只读程序存储器,器件兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位*处理器和ISP Flash存储单元,具有在系统可编程(ISP)特性,配合PC端的控制程序即可将用户的程序代码下载到单片机内部,省去了购买通用编程器,而且速度更快。
STC89C51系列单片机是单时钟/机器周期(1T)的兼容8051 内核单片机,是高速/ 低功耗的新一代8051 单片机,全新的流水线/精简指令集结构,内部集成MAX810 专用复位电路。
图 1 STC80C51
HC-SR04超声波测距模块
HC-SR04模块是一款利用超声波测量距离的模块,测量距离精确,能和国外的SRF05,SRF02等超声波模块相媲美。模块高精度,盲区2cm。
采用IO触发测距,给出至少10us的高电平信号,模块自动发送8个40kHz的方波,自动检测是否有信号返回,若有信号返回,通过IO输出一高电平,高电平持续的时间就是超声波从发射到接收的时间。
图 2 超声波模块
LCD(128*128)模块
该模块是一个128*128分辨率的LCD点阵屏,可以显示图片、文字、视频,采用T6963芯片进行控制。
图 3 LCD模块
系统设计思路
由超声波模块采集当前车辆的位置,间隔一个固定时间,再次采集车辆的位置信息,将两次采集到的位置信息作差,再除以当前温度下的声速,即可得到当前车辆的速度,将车速显示到液晶屏幕上。液晶屏幕轮询显示哈工大校徽、限速警示和当前速度三种图形。
设计参数和指标
1、能够测量0—100km/h的车速区间
2、能够测量5米以内的车辆
程序流程图
图 4 程序流程图
实验结果和分析
实验仿真电路图
仿真现象
图 6 哈工大校徽
图 7 减速慢行提示图
图 8 显示实时速度
图 9 无车时显示无速度
附录:
核心代码:
main.c
/*****************************************************
*@filename: main.c
*@description: 实现校园车辆测速并显示
*@author: ZhangRun
*@version: v1.0
*@date: 2021/6/17
*@note:
****************************************************/
#include "reg51.h"
#include "intrins.h"
#include "absacc.h"
#include "lcd128128.h"
#include "delay.h"
#include "speed.h"
/*****************************************************
*@param:
*@return:
*@function:
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
void main()
{
lcd_init();
speed_init();//HC-SR04初始化
while(1)
{
display();
}
}
lcd128128.c
/*****************************************************
*@filename: lcd128128.c
*@description: 显示页面控制
*@author: ZhangRun
*@version: v1.0
*@date: 2021/6/17
*@note:
****************************************************/
#include "lcd128128.h"
#include "zimo.h"
uint_16 lcdadress; //lcd地址
uint_8 lcdh,lcdl; //lcd地址高低
/*****************************************************
*@param:
*@return:
*@function: LCD初始化
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
void busycheck()
{
uint_8 state;
P0=0XFF;
do
{
cd=1; // 选择指令通道,准备读取通道状态
rd=0; //读有效
state=P0;
rd=1;
}
while((state&0x03)!=0x03);
}
/*****************************************************
*@param:
*@return:
*@function: LCD初始化
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
void setadr(void) //设定地址子程序
{
lcdh=lcdadress/256;
lcdl=lcdadress-lcdh*256;
wrcode2(lcdl,lcdh,0x24);
}
/*****************************************************
*@param:
*@return:
*@function: LCD初始化
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
void wrcode0(uint_8 h) //无参数指令写入子程序
{
busycheck();
cd=1; //选择指令通道
P0=h;
wr=0;
wr=1;
}
/*****************************************************
*@param:
*@return:
*@function: LCD初始化
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
void wrcode1(uint_8 i,uint_8 h) //单参数指令写入子程序
{
wrdata(i);
wrcode0(h);
}
/*****************************************************
*@param:
*@return:
*@function: LCD初始化
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
void wrcode2(uint_8 i,uint_8 j,uint_8 h)//双参数指令写入子程序
{
wrdata(i); //第一个参数写入
wrdata(j); //第二个参数写入
wrcode0(h);
}
/*****************************************************
*@param:
*@return:
*@function: LCD初始化
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
void wrdata(uint_8 j)
{
busycheck();
cd=0; //选择数据通道
P0=j;
wr=0;
wr=1;
}
/*****************************************************
*@param:
*@return:
*@function: LCD初始化
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
void disptupian(uint_8 *p,uint_8 x,uint_8 y,uint_8 base,uint_8 pianyi)
{
int i,j;
for(i=0;i<y;i++)
{
lcdadress=base*30+pianyi+i*30+0x0800;
setadr();
for(j=0;j<x;j++)
{
wrcode1(*p,0xc0);
p++;
}
}
}
/*****************************************************
*@param:
*@return:
*@function: LCD初始化
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
void lcd_init()//LCD初始化
{
uint_16 i;
wrcode2(0x04,0x00,0x22);
wrcode2(0x00,0x00,0x40); //文本区首地址设置(D1,D2,40H),0X0000
wrcode2(0x1e,0x00,0x41); //文本区宽度设置(D1,D2,41H),16字节每行
wrcode2(0x00,0x08,0x42); //图形区首地址设置(D1,D2,42H),0x0800
wrcode2(0x1e,0x00,0x43); //图形区宽度(D1,D2,43H),30字节每行
wrcode0(0x80); //显示方式设置,内部字符发生器有效,逻辑或合成
wrcode0(0x9c); //显示开关指令,
wrcode0(0xa3); //光标形状选择,8点*7行
wrcode2(0x00,0x08,0x24); //移地址指针(D1,D2,24H),清图形区
wrcode0(0xb0); //自动写设置,准备清零
for(i=0;i<2048;i++) //128*128共2048个字节,清屏
{
wrdata(0x00);
}
wrcode0(0xb2);
}
void display()
{
DistanceValue= DistanceStatistics();
disptupian(HIT,16,128,0,0);
delay1ms(1000);
disptupian(tupian,16,128,0,0); //清空
disptupian(jiansu,16,32,0,0);
disptupian(xiansu,16,96,32,0);
delay1ms(1000);
disptupian(tupian,16,128,0,0); //清空
DistanceValue2=DistanceStatistics();
speed=(int)((DistanceValue2-DistanceValue)/115);
disptupian(nindesudu,16,32,0,0);
switch(speed)
{
case 0:
disptupian(shu0,8,96,32,8);break;
case 1:
disptupian(shu1,8,96,32,8);break;
case 2:
disptupian(shu2,8,96,32,8);break;
case 3:
disptupian(shu3,8,96,32,8);break;
case 4:
disptupian(shu4,8,96,32,8);break;
case 5:
disptupian(shu5,8,96,32,8);break;
case 6:
disptupian(shu6,8,96,32,8);break;
case 7:
disptupian(shu7,8,96,32,8);break;
case 8:
disptupian(shu8,8,96,32,8);break;
case 9:
disptupian(shu9,8,96,32,8);break;
case 10:
disptupian(shu1,8,96,32,0);
disptupian(shu0,8,96,32,8);break;
case 11:
disptupian(shu1,8,96,32,0);
disptupian(shu1,8,96,32,8);break;
case 12:
disptupian(shu1,8,96,32,0);
disptupian(shu2,8,96,32,8);break;
case 13:
disptupian(shu1,8,96,32,0);
disptupian(shu3,8,96,32,8);break;
case 14:
disptupian(shu1,8,96,32,0);
disptupian(shu4,8,96,32,8);break;
case 15:
disptupian(shu1,8,96,32,0);
disptupian(shu5,8,96,32,8);break;
case 16:
disptupian(shu1,8,96,32,0);
disptupian(shu6,8,96,32,8);break;
case 17:
disptupian(shu1,8,96,32,0);
disptupian(shu7,8,96,32,8);break;
case 18:
disptupian(shu1,8,96,32,0);
disptupian(shu8,8,96,32,8);break;
case 19:
disptupian(shu1,8,96,32,0);
disptupian(shu9,8,96,32,8);break;
case 20:
disptupian(shu2,8,96,32,0);
disptupian(shu0,8,96,32,8);break;
case 21:
disptupian(shu2,8,96,32,0);
disptupian(shu1,8,96,32,8);break;
case 22:
disptupian(shu2,8,96,32,0);
disptupian(shu2,8,96,32,8);break;
case 23:
disptupian(shu2,8,96,32,0);
disptupian(shu3,8,96,32,8);break;
case 24:
disptupian(shu2,8,96,32,0);
disptupian(shu4,8,96,32,8);break;
case 25:
disptupian(shu2,8,96,32,0);
disptupian(shu5,8,96,32,8);break;
case 26:
disptupian(shu2,8,96,32,0);
disptupian(shu6,8,96,32,8);break;
case 27:
disptupian(shu2,8,96,32,0);
disptupian(shu7,8,96,32,8);break;
case 28:
disptupian(shu2,8,96,32,0);
disptupian(shu8,8,96,32,8);break;
case 29:
disptupian(shu2,8,96,32,0);
disptupian(shu9,8,96,32,8);break;
case 30:
disptupian(shu3,8,96,32,0);
disptupian(shu0,8,96,32,8);break;
case 31:
disptupian(shu3,8,96,32,0);
disptupian(shu1,8,96,32,8);break;
case 32:
disptupian(shu3,8,96,32,0);
disptupian(shu2,8,96,32,8);break;
case 33:
disptupian(shu3,8,96,32,0);
disptupian(shu3,8,96,32,8);break;
case 34:
disptupian(shu3,8,96,32,0);
disptupian(shu4,8,96,32,8);break;
case 35:
disptupian(shu3,8,96,32,0);
disptupian(shu5,8,96,32,8);break;
case 36:
disptupian(shu3,8,96,32,0);
disptupian(shu6,8,96,32,8);break;
case 37:
disptupian(shu3,8,96,32,0);
disptupian(shu7,8,96,32,8);break;
case 38:
disptupian(shu3,8,96,32,0);
disptupian(shu8,8,96,32,8);break;
case 39:
disptupian(shu3,8,96,32,0);
disptupian(shu9,8,96,32,8);break;
case 40:
disptupian(shu4,8,96,32,0);
disptupian(shu0,8,96,32,8);break;
case 41:
disptupian(shu4,8,96,32,0);
disptupian(shu1,8,96,32,8);break;
case 42:
disptupian(shu4,8,96,32,0);
disptupian(shu2,8,96,32,8);break;
case 43:
disptupian(shu4,8,96,32,0);
disptupian(shu3,8,96,32,8);break;
case 44:
disptupian(shu4,8,96,32,0);
disptupian(shu4,8,96,32,8);break;
case 45:
disptupian(shu4,8,96,32,0);
disptupian(shu5,8,96,32,8);break;
case 46:
disptupian(shu4,8,96,32,0);
disptupian(shu6,8,96,32,8);break;
case 47:
disptupian(shu4,8,96,32,0);
disptupian(shu7,8,96,32,8);break;
case 48:
disptupian(shu4,8,96,32,0);
disptupian(shu8,8,96,32,8);break;
case 49:
disptupian(shu4,8,96,32,0);
disptupian(shu9,8,96,32,8);break;
case 50:
disptupian(shu5,8,96,32,0);
disptupian(shu0,8,96,32,8);break;
case 51:
disptupian(shu5,8,96,32,0);
disptupian(shu1,8,96,32,8);break;
case 52:
disptupian(shu5,8,96,32,0);
disptupian(shu2,8,96,32,8);break;
case 53:
disptupian(shu5,8,96,32,0);
disptupian(shu3,8,96,32,8);break;
case 54:
disptupian(shu5,8,96,32,0);
disptupian(shu4,8,96,32,8);break;
case 55:
disptupian(shu5,8,96,32,0);
disptupian(shu5,8,96,32,8);break;
case 56:
disptupian(shu5,8,96,32,0);
disptupian(shu6,8,96,32,8);break;
case 57:
disptupian(shu5,8,96,32,0);
disptupian(shu7,8,96,32,8);break;
case 58:
disptupian(shu5,8,96,32,0);
disptupian(shu8,8,96,32,8);break;
case 59:
disptupian(shu5,8,96,32,0);
disptupian(shu9,8,96,32,8);break;
case 60:
disptupian(shu6,8,96,32,0);
disptupian(shu0,8,96,32,8);break;
case 61:
disptupian(shu6,8,96,32,0);
disptupian(shu1,8,96,32,8);break;
case 62:
disptupian(shu6,8,96,32,0);
disptupian(shu2,8,96,32,8);break;
case 63:
disptupian(shu6,8,96,32,0);
disptupian(shu3,8,96,32,8);break;
case 64:
disptupian(shu6,8,96,32,0);
disptupian(shu4,8,96,32,8);break;
case 65:
disptupian(shu6,8,96,32,0);
disptupian(shu5,8,96,32,8);break;
case 66:
disptupian(shu6,8,96,32,0);
disptupian(shu6,8,96,32,8);break;
case 67:
disptupian(shu6,8,96,32,0);
disptupian(shu7,8,96,32,8);break;
case 68:
disptupian(shu6,8,96,32,0);
disptupian(shu8,8,96,32,8);break;
case 69:
disptupian(shu6,8,96,32,0);
disptupian(shu9,8,96,32,8);break;
case 70:
disptupian(shu7,8,96,32,0);
disptupian(shu0,8,96,32,8);break;
case 71:
disptupian(shu7,8,96,32,0);
disptupian(shu1,8,96,32,8);break;
case 72:
disptupian(shu7,8,96,32,0);
disptupian(shu2,8,96,32,8);break;
case 73:
disptupian(shu7,8,96,32,0);
disptupian(shu3,8,96,32,8);break;
case 74:
disptupian(shu7,8,96,32,0);
disptupian(shu4,8,96,32,8);break;
case 75:
disptupian(shu7,8,96,32,0);
disptupian(shu5,8,96,32,8);break;
case 76:
disptupian(shu7,8,96,32,0);
disptupian(shu6,8,96,32,8);break;
case 77:
disptupian(shu7,8,96,32,0);
disptupian(shu7,8,96,32,8);break;
case 78:
disptupian(shu7,8,96,32,0);
disptupian(shu8,8,96,32,8);break;
case 79:
disptupian(shu7,8,96,32,0);
disptupian(shu9,8,96,32,8);break;
case 80:
disptupian(shu8,8,96,32,0);
disptupian(shu0,8,96,32,8);break;
case 81:
disptupian(shu8,8,96,32,0);
disptupian(shu1,8,96,32,8);break;
case 82:
disptupian(shu8,8,96,32,0);
disptupian(shu2,8,96,32,8);break;
case 83:
disptupian(shu8,8,96,32,0);
disptupian(shu3,8,96,32,8);break;
case 84:
disptupian(shu8,8,96,32,0);
disptupian(shu4,8,96,32,8);break;
case 85:
disptupian(shu8,8,96,32,0);
disptupian(shu5,8,96,32,8);break;
case 86:
disptupian(shu8,8,96,32,0);
disptupian(shu6,8,96,32,8);break;
case 87:
disptupian(shu8,8,96,32,0);
disptupian(shu7,8,96,32,8);break;
case 88:
disptupian(shu8,8,96,32,0);
disptupian(shu8,8,96,32,8);break;
case 89:
disptupian(shu8,8,96,32,0);
disptupian(shu9,8,96,32,8);break;
case 90:
disptupian(shu9,8,96,32,0);
disptupian(shu0,8,96,32,8);break;
case 91:
disptupian(shu9,8,96,32,0);
disptupian(shu1,8,96,32,8);break;
case 92:
disptupian(shu9,8,96,32,0);
disptupian(shu2,8,96,32,8);break;
case 93:
disptupian(shu9,8,96,32,0);
disptupian(shu3,8,96,32,8);break;
case 94:
disptupian(shu9,8,96,32,0);
disptupian(shu4,8,96,32,8);break;
case 95:
disptupian(shu9,8,96,32,0);
disptupian(shu5,8,96,32,8);break;
case 96:
disptupian(shu9,8,96,32,0);
disptupian(shu6,8,96,32,8);break;
case 97:
disptupian(shu9,8,96,32,0);
disptupian(shu7,8,96,32,8);break;
case 98:
disptupian(shu9,8,96,32,0);
disptupian(shu8,8,96,32,8);break;
case 99:
disptupian(shu9,8,96,32,0);
disptupian(shu9,8,96,32,8);break;
default:
disptupian(shu1,8,96,32,0);
disptupian(shu9,8,96,32,8);break;
}
delay1ms(2000);
}
speed.c
/*****************************************************
*@filename: main.c
*@description: 测速
*@author: ZhangRun
*@version: v1.0
*@date: 2021/6/17
*@note:
****************************************************/
#include "speed.h"
int count = 0;
float DistanceValue = 0.0; //测量的距离值
float DistanceValue2 = 0.0;
uint_8 speed;
float SPEEDSOUND; //声速
/*****************************************************
*@param:
*@return:
*@function: 测量距离
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
float MeasuringDistance()
{
TH0=0; //最大定时时间约65ms
TL0=0;
Trig=1; //生成20us的脉冲宽度的触发信号
Delay20us();
Trig=0;
while(!Echo); //等待回响信号变高电平
TR0=1; //启动定时器0
while(Echo); //等待回响信号变低电平
TR0=0; //关闭定时器0
return (SPEEDSOUND*(TH0*256.0+TL0))/2000; //返回距离值(mm)
}
/*****************************************************
*@param:
*@return:
*@function: HCSR04初始化
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
void speed_init()
{
SPEEDSOUND=334.1+25*0.61;
Trig=0;
Echo=0;
TMOD=0x01;
}
/*****************************************************
*@param:
*@return:
*@function: 测距的数值排序求平均
*@author: ZhangRun
*@date: 2021/6/17
*@note:
****************************************************/
float DistanceStatistics()
{
uint_8 i;
float disData;
for(i=0;i<7;i++) //连续测距
{
disData+=MeasuringDistance();
delay1ms(1);
}
return disData/7.0;
}