单片机作业学院计算机与控制工程学院专业自动化132学号2013022030姓名王伟基于 51 单片机的称重系统一动态称重所谓动态称重是指通过分析和测量车胎运动中的力,来计算该运动车辆的总重量、轴重、轮重和部分重量数据的过程。
动态称重系统按经过车辆行驶的速度划分,可分为低速动态称重系统与高速动态称重系统。
因为我国高速公路的限速最高是120,所以高速动态称重系统在理论上可对 5 到 120 之间时速通过称量装置的车辆进行动态称重。
而低速动态称重系统则一定要限制通过车辆的行驶速度,要想有较高的测量精度,理论要求车辆在5km/h 以下时速匀速通过。
在我国,车辆动态称重一般都使用低速动态称重来完成,在很多收费站和车辆检测站都有应用,国家也出台了相关的测量标准。
与传统意义上的静态称重相比,动态称重可以在车辆缓慢运动情况下直接进行称重,这样动态称重的高效率、测量时间短、能流畅交通等主要特点就凸显出来了。
动态称重的问世,不但使车辆的管理上有了很大的促进作用,而且还对我国的公路管理和维护起到了至关重要的作用。
二系统总体结构及其功能设计总体结构是以51 单片机为处理器的系统,如图 3.1 所示。
上位机键盘输入A/D转换器放大器ADC0832OP07AT89C51桥式称重传感器RS232转换器单片机WPL110蜂鸣器LED显示图3.1本设计要求能判断出车辆是否超载,如果车辆超载,本系统能够提供该车辆的超载信息并发出警报。
本设计采用STC89C52单片机作为系统的处理核心,利用桥式称重传感器到A/D 转换器中转换为数字信号,再经过单片机处理、传输到接口电路,最后送到上位机,该数据可以与上位机里用键盘事先输入设定的总重量作比较并判断出该车辆是否超载,如果超载,则可通过显示器、蜂鸣器作显示超载信息并报警,当然,键盘的作用除了输入设定值还可以解除和开启警报。
三动态称重系统的组成动态称重系统主要由车辆重量(含超载、偏载检测)检测子系统、货车长、宽、高三维尺寸超限检测子系统、自动触发摄像拍照子系统、车辆类型自动判别子系统、系统配置及系统维护子系统、行驶车辆速度测量子系统、数据统计、报表处理子系统和单据输出打印子系统这几部分组成。
该系统组成完善,部件考虑周全,能很好的完成称重任务。
四动态称重系统的主要功能(1)动态检测出通过车辆的轴数、轴重、轴距、轮数、车速等;(2)能自动检测出车辆的高、宽、长等外围尺寸是否超出最大标准,并能给出超出部位的具体位置和具体数据;(3)拍摄机器在车辆经过时能自行对要被检测的车辆进行拍照,该机器能对车牌号码、车辆种类进行识别,最终作为图像证据;(4)可以将不合格车辆的处理记录、超限情况进行打印,根据车辆超限的程度来计算罚款数额并打印收据或罚款单;(5)检测到的数据全部存入数据库中,并对被监测到的数据进行分析、统计。
便于汇总上报、日常管理和进行查询。
五单片机的选用本设计采用的是INTEL 公司研究开发生产的STC89C52单片机,其内部置有256 字节的内部数据存储器、 8 位中央处理单元、 8K 片内程序存储器、 3 个 16 位定时 / 计数器、 32个双向 I/O 口和一个片内时钟振荡电路,全双工串行通信口, 5 个两级中断结构。
89C52的引脚图如图 4.1 所示。
图4.1 89C52 引脚图本设计使用的是单片机的最小系统,其中电路包括下载口电路、复位电路和晶振电路。
复位电路中,电阻在下接地,电容在上接高电平,中间为 RST。
复位电路工作原理是:通电时,由于电流很大,从而相当于电容被短路,这样 RST引脚上处于高电平,这时的单片机为禁止工作状态。
如果要使单片机正常工作,就要使 RST端电压慢慢下降并到一定程度,也就是RST端为低电平,这就需要通过电源对电容进行充电。
复位电路复位的方式有手动复位、上电复位两种。
所谓上电复位,就是通电瞬间,由于电流很大,从而相当于电容被短路,这样 RST引脚上处于高电平,自动复位;相反,通过对改变电容电流,当电流很小的时候,我们就可以把电容当做开路状态, RST 端就处于低电平,程序就能正常的运行。
而手动复位要在上电复位的基础上,按下复位按键,使 VCC直接与 RST相连,电容处于放电状态,以高电平形成复位;松开复位按键, RST仍旧是高电平,这时充电电流作用于电阻上, VCC给电容进行充电,还是复位状态,充电结束后,RST为低电平,能够正常工作。
A/D 转换器通道 A/D 转换芯片和8 位分辨率。
它的优点有体积小,兼容性强,性价比高,从而深受个人的欢迎和企业的认可,目前在世界上也已经有了较高的使用率。
ADC0832具有能够进行双通道A/D 转换,分辨率高达8 位;当供电电源为5V 时,输入电压能稳定的保持在0~5V 之间;TTL/CMOS与输出输入电平兼容;功耗很低,只有 15mW;转换工作时间只有32 μS,也就是频率仅有 250KHZ 等特点。
其引脚功能图如图 4.6 所示,芯片引脚接口说明如表 4 所示。
CS18Vcc/REFCH027CLKCH136DOADC0832GND45DI图 4.6 引脚排列表 4 ADC0832 引脚说明接口说明CS片选使能,输入低电平能使芯片工作CH1模拟的输入通道1 ,或作为 IN+/- 使用CH0模拟的输入通道0 ,或作为 IN+/- 使用GND接地DO转换数据输出,数据信号输出DI选择通道控制,数据信号输入CLK芯片时钟脉冲输入Vcc/REF5V 参考电压输入和电源输入通常情况下的单片机和 ADC0832的接口的数据线应为 4 条,分别是 CS、CLK、DO、DI 。
由于 ADC0832的数据信号输入输出口与单片机具有双向接口通信,输入输出口也不同时使用,所以可以将数据信号输入输出口并联后当一条数据线进行使用。
它们的硬件接口电路与单片机连接的原理如图 4.7 所示。
最后将以上的惠思登电桥、放大器、ADC0832转换器和 STC89C52单片机连接起来,就组成了系统的采集模块。
VccADC0832AT89C51 CS VccU0CLK P1.1CH0CH1DIP1.2GND DO P1.3图 4.7 ADC0832与单片机的接口电路报警模块本系统要实现一旦检测到车辆超载超限,就会立刻鸣笛报警,通过操作人员的检查处理后,解除报警。
本设计选用蜂鸣器作为发声装置,蜂鸣器可利用三极管来进行放大驱动。
该接口电路如图 4.15 所示:5VR4SpeakerR3P2.7VT1图 4.15报警接口电路5.系统的软件设计5.1 主程序设计当系统上电复位后,系统开始初始化,包括端口等;初始化完毕后,调用串口输出提示语,开始准备串口输出电压;准备完毕后,调用串口输出电压值,开始从串口输出电压值;输出完毕后,调用串口输出换行值;最后开始延时200ms。
根据系统方案,设计出本设计的主程序流程,可以用框图表示。
开始串口初始化串口输出提示语串口输出电压值串口输出换行值延时 200ms图 5.1主程序流程图5.3 ADC0832 软件设计首先要将芯片开始使能,即CS使能端置于低电平,然后通过DI 和 DO的同一数据输入端口,可实现通道功能的选择,再调用通道初始化程序,初始化完毕后,在8 个时钟边沿获得正序和反序8 位数据,最后返回数据。
根据此方案,设计出本设计中A/D 转换程序流程,如图 5.2 所示。
当两位数据都为0 时, CH1作为负输入端 IN- ,而 CH0就作为正输入端IN+来进行相0 和 1 时, CH1作为正输入端 IN+,CH0作为负输入端 IN- 来进行相关输入。
当两位数据为分别为 1 和 0 时, CH0进行单通道转换而 CH1不转换。
ADC0832的功能项如表 7 所示。
开始芯片使能通道选择通道初始化在8 个时钟边沿获得正序 8 位数据在8 个时钟边沿获得反序 8 位数据返回数据图5.2 ADC0832 转换流程图表7 AD0832 功能项MUX Address Channe#SGL/DIF ODD/SIGN0110+11+00+_01_+ADC0832没有工作时, DO/DI 和 CLK的电平可高可低,但CS的输入端口应必须显示高电平,此时芯片处于禁用状态。
当A/D 转换进行时, CS端口必须处于低电平并且一直将低电平保持到转换全部结束。
当芯片转换工作开始,芯片的CLK端口会接收到处理器传送来的一时钟脉冲, DO/DI 并联端口将使用数据输入信号的DI 端口。
第一个时钟脉冲的下沉出现之前,DI 端口一定要是高电平,表示启始信号的发出,在第二、三个脉冲的下沉出现之前,DI 端口要输入两位数据来选择通道。
第三个脉冲出现下沉之后, DI 端口就不再起任何作用,此后DO/DI 并联端口则是被DO端口占领进行读取转换数据。
第四个下沉脉冲出现开始,DO端口输出最高位的转换数据DATA7,接下来每个脉冲下沉之后 DO端口都会输出下一位的转换数据。
直到发出最低位数据DATA0,也就是由第十一个脉冲发出的数据之后,这样一个字节的数据输出就完成了。
再从第十一个脉冲下沉开始从 DATD0开始输出下一个相反数据字节。
然后一直到第十九个脉冲完成数据的输出,这样一次 A/D 转换才结束。
最后,要想将转换后的数据进行相关处理就必须将芯片禁用,也就是将 CS端口输入高电平。
5.4 LCD 显示程序设计首先设置显示模式,设置第( x,y )个字符的 DDRAM的地址,为 15×2 显示,因为液晶显示为 15 列,所以 x 位置的范围是 0 到 15,同理,因为显示 2 行,所以 y 位置的范围是 0 到 1。
显示程序如下:void Lcd_Pos(uchar yPos,uchar xPos){uchar tmp;xPos &= 0x0f;//x位置范围是0~15,因为显示15列yPos &= 0x01;//y位置范围是0~1,因为显示2行if(yPos==0)//显示第一行{tmp = xPos;}else{tmp = xPos + 0x40;//显示第二行}tmp |= 0x80;Write_com(tmp);}5.5 主函数软件主要分成四个部分:串口配置,ADC0832的初始化,等待接受数据和输出数据。
程序如下:void main(void){InitUART(); //串口初始化Lcd_init();Write_String("Weight: ", 0, 0);Write_String("H=", 1, 0);Write_String("L=", 1, 6);Beep = 1;while(1){Process10ms();DispVal(Wh, 1, 2);DispVal(Wl, 1, 8);CheckProcess();if (flagget10s == 1){flagget10s = 0;Get_temp(sum*100);ET0 = 1;TR0 = 1;Disp_Voltage();//采集电压并发送}}}参考文献[1]周杏鹏,传感器与检测技术,清华大学出版社,2010[2]赵燕,传感器原理及应用,北京大学出版社,2009[3]王幸之、钟爱琴、王雷、王闪,AT89 系列单片机原理与接口技术,北京航天大学出版社,2004[4]高玉芹,单片机原理与应用及C51 编程技术,机械工业出版社, 2011[5]张毅刚、彭喜元、彭宇,单片机原理与应用,高等教育出版社,2010[6]刘小成、吴清、夏春明,单片机原理及C51 应用,华东理工大学出版社,2009[7]国务院全国治理车辆超限超载领导工作小组,全国治理车辆超限超载工作简报[Z] , 2004( 1)[8]张勇、吴文兵、谢竹生、张雨,汽车轮重动态检测中的单片机,汽车科技,2004( 3)[9]张积东,单片机 51/98 开发与应用,电子工业出版社,1994[10]周航慈,单片机程序设计基础,北京航空航天大学出版社,1997单片机系统部分硬件原理图单片机程序#include "reg52.h"#include "My_type.h" //数据类型头文件#include <intrins.h>#define nop() _nop_()#define uchar unsigned char#define uint unsigned intsbit Lcd_rs=P2^0;sbit Lcd_rw=P2^1;sbit Lcd_en=P2^2;sbit key1 = P3^5;sbit key2 = P3^6;sbit key3 = P3^7;sbit Beep = P2^7;sbit Led = P2^6;sbit CS=P1^3;//使能sbit CLK=P1^1;//时钟sbit Do=P1^2;//数据输出sbit Di=P1^2;//数据输入#define first_channel0x02 //通道 1#define second_channel 0x03 //通道 2uchar CH = first_channel;#define Fclk11059200UL/* 使用 11.0592M 晶体 */ #define BitRate9600UL/* 波特率定义为 9600*/uint8 Sending;// 发送标志code uint16 AD_Tab[41] = {512, 2048, 2970, 3840, 4659, 5581,6349, 7117, 7782, 8397, 9165, 9830,10291, 11162, 11520, 11981, 12749, 13210, 13926, 14490, 15206, 15821, 16538, 17357,17971, 18842, 19814, 20838, 21760, 22477,23091, 23603, 23962, 24371, 24678, 24883,25037, 25190, 25293, 25395, 25600};uint8 temp_zheng;float temp_xiao;uint8 flag10ms = 0;uint8 flag50ms = 0;uint8 get10s = 0;uint8 flagget10s = 0;uint8 Alarmflag = 1;uint16 sum = 0;uint8 count5ms = 0;uint8 Wh = 40;uint8 Wl = 20;void Delay_lcd1602(uint dly){uint i;for(; dly>0; dly--)for(i=0; i<100; i++);}bit Lcd_busy(){bit result;Lcd_rw = 1;Lcd_rs = 0;Lcd_en = 1;nop();nop();nop();nop();result = (bit)(P0&0x80);Lcd_en = 0;return(result);}void Write_com(uchar com){while(Lcd_busy());//LCD忙等待Lcd_rs = 0;Lcd_rw = 0;P0 = com;Delay_lcd1602(5);Lcd_en = 1;Delay_lcd1602(5);Lcd_en = 0;}void Write_data(uchar date){while(Lcd_busy());//LCD忙等待Lcd_rs = 1;Lcd_rw = 0;P0 = date;Delay_lcd1602(5);Lcd_en = 1;Delay_lcd1602(5);Lcd_en = 0;}void Lcd_init(){Lcd_en = 0;Write_com(0x38);Delay_lcd1602(5);Write_com(0x0c);Delay_lcd1602(5);Write_com(0x04);Delay_lcd1602(5);Write_com(0x01);Delay_lcd1602(5);}void Lcd_Pos(uchar yPos,uchar xPos)// 设置第( xPos,yPos )个字符的 DDRAM地址{uchar tmp;xPos &= 0x0f;//x位置范围是0~15,因为显示15列yPos &= 0x01;//y位置范围是0~1,因为显示2行if(yPos==0)//显示第一行{tmp = xPos;}else{tmp = xPos + 0x40;//显示第二行}tmp |= 0x80;Write_com(tmp);}void Write_char(uchar c,uchar xPos,uchar yPos)//定义Write_Char函数{Lcd_Pos(xPos,yPos);Write_data(c);}void Write_String(uchar *s,uchar xPos,uchar yPos) //定义Write_String函数{uchar i = 0;Lcd_Pos(xPos,yPos);while(*s){Write_data(*(s++));if(++i>16) break;}}void InitUART(void){EA=0;TMOD|=0x21; //定时器1工作在模式2 SCON=0x50; //串口工作在模式1TCON=0x05;TH1=256-Fclk/(BitRate*12*16);TL1=256-Fclk/(BitRate*12*16);TH0 = (65535 - 1000)/256;TL0 = (65535 - 1000)%256;ET0 = 1;TR0 = 1;PCON=0x80;// 串口波特率加倍ES=1;//串行中断允许TR1=1;//启动定时器 1REN=1;//允许接收EA=1;//允许中断}void UartISR(void) interrupt 4{if(RI) //收到数据{RI=0; //清中断请求}else//发送完一字节数据{TI=0;Sending=0; //清正在发送标志}}void PutChar_to_Uart(uint8 d){Sending=1;SBUF=d;while(Sending);}void Prints(uint8 *pd){while((*pd)!='\0'){PutChar_to_Uart(*pd);pd++;}}unsigned char ADconv(void){unsigned char i;unsigned int data_f=0,data_c=0;ET0 = 0;TR0 = 0;Di=1;CS=1;_nop_();CS=0;Di=1; ;//芯片使能之前的初始化。