基于51单片机的波特率自动识别系统程序

合集下载

80C51系列单片机波特率自动检测的通用程序

80C51系列单片机波特率自动检测的通用程序

80C51系列单片机波特率自动检测的通用程序 An Automatic B aud R ate Detection Pro gram for the80C51Single2Chip Computer●万新恒龚建明 Wan XinhengG ong Jianming1 引言在串行异步通讯中,常常希望从机端的波特率能随主机端的不同设置进行自动调整,这在分布式多种波特率通讯系统中可省去波特率硬件设置开关切换的不便。

软件实现波特率自动检测的设计思想常见的有以下两种:一种是当主机启动通讯程序以后,逐一选择波特率向从机发某一固定调试字符(如ASCII1),不断地重复接收和检验过程直至无误。

二是利用串行异步设计标准中文件导引区和记录字符中停止位的逻辑“1”信号,采用软件定时的方法确定出解调参数,然后,以该参数为基准,与随后采样的数据位信号中的周期值相比较以判别出数据位信号中的逻辑“1”或“0”,并将其还原成二进制数以完成整个调解进程[1]。

本文介绍另一种简单可靠的软件实现波特率自动检测的方法,并给出了程序清单及详尽的注解。

该软件方法提高了波特率解调的简捷性和兼容性。

2 编程方法通讯开始时,从串行口RXD输入一个引导字符(如ASCII a)作为测试字符,当检测到起始位(下降沿)时启动计数器T0,在随后串行数据的每一个上升沿,“捕获”计数器的值并保存,当计数器溢出时,最后的“捕获”值则表示串行接收字符从起始位到停止位的持续计数值。

然后,将此计数值与波特率索引表中每种标准波特率所对应的数据相比较,从而检测出正确的波特率。

对每一种波特率,通过下式计算出所对应的最大计数器预置值,存入表格BdTab中:最大定时器预置值=晶振频率(MHz)波特率×512以82N21通讯(8位数据位,无奇偶校检, 1位停止位)为例,上式推导如下:最大定时器预置值=最小识别时间机器周期最小识别时间=识别位数×字节时间9机器周期=12/晶振频率字节时间=9/波特率3 程序清单通用程序清单及详尽的注解如下:;预定义RX BIT P3.0;串行数据接收端CharH DATA30h;保存TH0值CharL DATA31h;保存TL0值BdRt DATA32h;保存波特率最终检测值Display EQU P1;显示调试结果;复位及中断向量万新恒,现在华中理工大学固体电子学系工作。

基于51单片机的CAN通讯协议C语言程序

基于51单片机的CAN通讯协议C语言程序
// 函数类别 SJA100etmode
// 入口函数 无
// 出口函数 无
// 全局变量 SJA_workmode
// 操作寄存器 控制寄存器(地址00)
// 函数功能 设置SJA工作在复位模式
#define SJA_RIE 0 //接收中断
//-----------------------定义地址指针,指向基址--------------------------------------------------------
bit bdata SJA_workmode=1; //SJA_workmode=1SJA工作在工作模式
//SJA_workmode=0工作在复位模式
#define base_Adr 0x00
//-----------------------定义总线定时寄存器的值--------------------------------------------------------
#define SJA_BTR0 0x00 //该值需要用户根据实际需要的波特率进行计算
//------------------------------------------------------------------------------------------------------
// 函数类别 SJA1000基本操作
// 函数名称 CANREG_write
}BASICCAN_FRAME,receive_BUF,send_BUF;
//BASICCAN_BUFstruct send_BUF;
//------------------------------------------------------------------------------------------------------

基于51单片机串口波特率自适应方法

基于51单片机串口波特率自适应方法

基于51单⽚机串⼝波特率⾃适应⽅法 在单⽚机中,UART是常⽤的通信⽅式。

最近在研究Bootloader需要设置UART的波特率⾃适应,通过查阅资料参考了⽹友的⽅法,故借此分享我的⽅法。

⼀般的,串⼝⾃适应波特率有以下2种⽅法。

⼀是通过具有独⽴的同步字符。

使⽤串⾏通讯前,要先进⾏同步操作,即接收端通过对⽐接收到的字符与同步字符的差异调整波特率,或者通过定时器测量同步字符的位宽计算波特率。

即将串⼝接收IO电平状态进⾏定时器计时,计算出最⼩脉宽时长,即⼀帧时长,就可算出其波特率值,这种⽅式需要特定的同步字符(如:0x55、0xAA等)或者增加检测的周期。

⼆是不需要独⽴的同步字符。

即不管波特率如何,可以直接通讯。

通讯命令前导字符固定,⽐如⼀些短消息模块使⽤AT指令集,每条指令都是以AT开始的,这样虽然是命令但是有同步的作⽤,不过要求必须在真实命令到来前调整波特率,这种⽅式需要的时间周期长,因为单⽚机需要不断调整波特率去接收判断传输的字符直到通讯成功,且判断必须快速准确。

由于⽅便需要,以下实验采⽤的是⽅法⼀,使⽤单⽚机SC95F8617作为串⼝实验对象。

实验条件:内部定时器⼀个。

实验⽅法:通过定时器,连续检测UART输⼊引脚RXD上的电平变化,得到RXD上最⼩的脉宽时长计算出波特率,以达到波特率⾃适应。

参考代码如下,最后返回的就是波特率数值,其中发送的同步字符为0x55:1#define SystemClock 32000000 //HRC=32MHz2#define UART_TX P21 //TX⼝3#define UART_RX P20 //RX⼝4#define UART_TX_INIT {P2CON &= ~(1<<1);P2PH |= (1<<1);} //TX设为输⼊上拉模式5#define UART_RX_INIT {P2CON &= ~(1<<0);P2PH |= (1<<0);} //RX设为输⼊上拉模式67//波特率⾃适应8//需要⽤到读IO电平9//通过检测到最⼩的脉宽时间10 unsigned long UART_Baud_Adapt(void)11 {12 unsigned long baudrate =0;13 unsigned long t1=0,t2,t=0;14 unsigned long oldLevel,newLevel;15 unsigned char i=0;16 UART_RX_INIT; //RX设为输⼊模式1718 oldLevel = UART_RX; //读取⼀次RX的电平19while(UART_RX == 1); //等待RX被拉低20 Timer0_Open();21 Timer0_Enable();22for(i=0;i<8;) //连续检测8次电平变化,检测1个字节23 {24 newLevel = UART_RX; // 读RX的电平25if(newLevel != oldLevel) // 如果有电平变化26 {27 t2 = (unsigned long)(TH0<<8)+TL0; // 读定时器中的值28 oldLevel = newLevel; // 更新为新的引脚值29if((t1 == 0)&&(t == 0)) // 第⼀个电平变化30 {31 t1 = t2; // 记录第⼀个时刻点32 }33else// 不是第⼀个电平变化34 {35if(t == 0) // 第⼀段电平36 {37 t = t2-t1; // 记录第⼀段电平所⽤时间38 }39else// 不是第⼀段电平40 {41if((t2-t1)< t)42 {43 t = t2-t1; // 保留电平脉宽的最⼩值44 }45 }46 t1 = t2; // 更新为新的时刻点47 }48 i++; // 电平变化数+149 }50 }51 Timer0_Close();52 baudrate = (unsigned long)(t*403/400); //计算时间53 baudrate = SystemClock/baudrate; //计算波特率54return baudrate;55 }56//Timer0设置57void Timer0_Open(void)58 {59 TMCON = 0X07; //不分频60 TMOD |= 0x01; //0000 0001;Timer0设置⼯作⽅式161 TH0=TL0=0;62 }63//使能Timer064void Timer0_Enable(void)65 {66 ET0 = 1; //定时器0允许67 TR0 = 1; //打开定时器068 }69//关闭Timer070void Timer0_Close(void)71 {72 ET0 = 0; //定时器0关闭73 TR0 = 0; //关闭定时器074 } 通过实际测试多个波特率,结果如下:波特率⾃适应实验对⽐发送同步字符波特率(bps)⾃适应⽅法计算得到的波特率(bps)480047649600958919200194173840038787115200122605256000240601 从上⾯测试数据可以看到这种⽅法计算出的低速波特率还是⽐较接近的,系统时钟越快,理论上计算出来的数据越接近。

基于51单片机的高速公路测速系统和车牌识别分析

基于51单片机的高速公路测速系统和车牌识别分析

基于51单片机的高速公路测速系统和车牌识别分析添加时间: 2010-3-20 11:19:19 文章来源: 文章作者: 点击数:17688摘要鉴于高速公路限速牌不能很好地对司机起到警示作用的作用,本文设计了一套基于MCS-51单片机,包含光电探测装置和显示装置的电子屏幕。

它不仅能方便设置并显示该路段的限制速度,以完成普通电子限速牌的限速提示功能,同时能将测得的车速实时显示,并自动判断是否超速。

另外它低廉的造价和经计算证明较高的精度大大提高了它的可用性。

车辆牌照自动识别系统是近几年发展起来的基于图像和字符识别术的智能化交通管理系统,是目前国内外模式识别应用研究领域的一个热点。

本文对系统中区域提取、图像预处理、字符分割和字符识别等环节涉及的算法、设计做了一个比较详细的论述。

本文在图像预处理中重点介绍一种在图像获取阶段有目的定位关注的物体,讨论了灰度图像二值化的多种算法,利用它在原始图像形成的标识区域特性,在约束条件下,按照识别牌几何特征提出了一种特殊的二值化处理方法。

实验证明该图像识别系统具有较高的可靠性与稳定性,减小了进一步车牌识别中计算量大的问题,从而提高了车牌识别的准确性和快速性。

讨论了灰度图像二值化的多种算法基于数学形态学的图像去除噪声的方法。

基于数学形态学的图像去除噪声是通过对图像的开、闭操作有选择的去噪声。

可以去除直径小于字符笔划半径的孤立噪声点。

还详细地介绍了基于字符形态划分的字符识别方法。

基于字符形态划分的字符识别方法是在对数字字符结构进行充分分析的基础上,对基元检测,归纳字符形态特征,得到的快速字符识别方法。

关键词:光电检测;车速测量;单片机;电子限速牌;车辆牌照;图像处理;基元检测;字符识别基于51单片机的高速公路测速系统和车牌识别分析AbstractIn view of the highway speed limit unlicensed drivers should not very well serve as a warning to the role, this article has designed a single-chip based on the MCS-51, including the photoelectric detection devices and display devices of the electronic screen. It not only can easily set up and display the road speed limit in order to achieve common electronic speed limit signs prompt function, can be simultaneously measured real-time display of speed and automatically determine whether the speeding. In addition it is low cost and the higher the accuracy of calculations greatly enhance its usability. Vehicle License Plate Recognition system is developed in recent years based on the image and character recognition operation of the Intelligent Traffic Management System, the application of pattern recognition at home and abroad are currently a hot area ofresearch. In this paper, the system of regional extraction, image preprocessing, character segmentation and character recognition algorithm, such as aspect involved in the design to do a more detailed exposition. In this paper image pre-processing in the introduction of a focus at image acquisition phase has the purpose of positioning objects of concern, discussed the gray image binarization of a variety of algorithms, use it in the original logo image formation of regional characteristics, in binding conditions, identification card in accordance with the geometric characteristics of a particular binarization approach. Experiments prove that the image recognition system has high reliability and stability, further reduce the vehicle license plate recognition in the calculation of a large quantity of questions, thereby increasing the accuracy of license plate recognition and speed.Discussed the gray image binarization algorithm of multiple images based on mathematical morphology method to remove noise. Images based on mathematical morphology to remove the image noise is through the open and close operation has chosen to noise. Can remove the character strokes of a diameter less than the radius of the isolated noise points. Also detail the division of character-based form of character recognition methods. Morphological character-based division of Character Recognition on the figure are at a full analysis of character structure based on element detection, morphological characteristics summarized characters get Character Recognition Express.Key words:Photoelectric detection; speed measurement; Singlechip; electron speed licensing; vehicle license; image processing; motif detection; Character Recognition目录摘要................................................................................. (I)Abstract........................................................................... . (II)第1章绪论................................................................................. . (2)1.1 车牌字符识别研究课题的背景 (2)1.2 车牌字符识别研究的意义 (2)1.3 车牌字符识别研究的应用现状及发展 (3)1.4 本文主要内容.................................................................................第2章车牌图像预处理 (5)2.1 数字图像处理的相关介绍 (5)2.1.1 数字图像处理概念 (5)2.1.2 图像的数字化表示 (5)2.1.3 本文中图像处理所涉及的相关领域 (6)2.2 图像二值化................................................................................. . (6)2.2.1 彩色图像和灰度图像 (6)2.2.2 基于灰度的图像二值化 (7)2.2.3 图像二值化结果演示 (9)2.3 用数学形态学的方法去除噪声 (10)2.3.1 数学形态学的几种基本运算 (10)2.3.2 经开闭运算前后的图像对比显示 (16)2.4 单个字符图像的分割 (17)2.4.1 我国车牌的特点 (17)2.4.2 对所要识别的车牌的分析 (17)2.4.3 基于列扫描黑色像素积累的字符分割 (18)2.4.4 已经分割后的单个字符演示 (18)2.5 本章小结................................................................................. . (19)第3章基于字符形态划分的字符识别 (19)3.1 字符识别概述................................................................................3.1.1 目前字符识别的一些常规方法 (20)3.2 字符轮廓分析 (21)3.2.1 字符轮廓的划分 (21)3.2.2 字符四方向轮廓公式化表示 (21)3.3 字符轮廓的变化特征 (22)3.4 字符形态划分的结构基元 (22)3.4.1 字符结构基元划分原理 (22)3.4.2 字符形态划分方法的特点 (23)3.5 利用字符结构基元划分的字符识别原理 (24)3.5.1 基元的检测 (24)3.5.2 轮廓的统计特征 (25)3.5.3 用字符形态识别数字字符 (25)3.5.3.1 数字字符的特点 (25)3.5.3.2 数字字符的识别方法 (26)3.5.4 字符识别的matlab算法流程 (27)3.6 本课题整体流程 (29)3.6.1 对本课题流程的总体说明 (29)3.6.2 用MATLAB完成本课题的流程图 (30)3.7 基于字符形态划分的字符识别方法的特点和不足 (30)3.8 本章小节................................................................................. (31)结论................................................................................. . (32)参考文献................................................................................. (33)第1章绪论1.1 车牌字符识别研究课题的背景随着21世纪经济全球化和信息时代的到来,作为信息来源的自动检测、图像识别技术越来越受到人们的重视。

51系列单片机波特率的计算方法(最终版本)

51系列单片机波特率的计算方法(最终版本)

STC单片机串口1用定时器1模式2做波特率发生器的计算方法一、基本原理说明定时器1工作在方式2是一种既省事又精确的产生串行口波特率的方法。

原因是定时器T1工作方式2是一种8位自动重装方式,无需在中断服务程序中送数,没有由于中断引起的误差。

波特率的计算公式:设定时器T1方式2的初值为X,则有:定时器T1的溢出率=计数速率/(256-X)=fosc/(256-X)*12;(注:12分频的单片机)则方式2的波特率=2SMOD*fosc/(256-X)*12*32.二、计算题1.波特率的计算公式:9600Hz(9600bps),4800Hz(4800bps),其他波特率都有误差。

图1此图中波特率是19200BPS、57600BPS时候,存在误差2.溢出率:溢出率应该是每秒溢出的次数。

综合式:波特率=(2SMOD/32)*(T1的溢出率)=(2SMOD/32)*(fosc/(12*(256-TL1)))=(2SMOD*fosc)/(394*(256-TL1))12/fosc=每个机器周期时间(fosc单片机的晶振时钟的频率),8位定时器T1溢出一次所需的时间=(12/fosc)*(256-初值)=溢出一次所需的时间,最后用1除以该数就代表每秒溢出的次数,也称作溢出率。

计数速率=fosc/12(12分频的单片机)溢出速率=1/一次溢出时间=1/((256-TL1初值)*(12/fosc))=fosc/(12*(256-TL1初值))3.计算例题(1)若STC单片机的晶振频率fosc为11.0592MHz,串行口1工作在方式1,定时器T1作为波特率发生器,T1在工作模式2自动重装初值的8位定时方式,已知SMOD=0,要求串行口1的波特率为9600Hz(9600bps),请计算定时器T1的初始值TL1=?。

解答:(a)因SMOD=0,波特率=(2SMOD/32)*(T1的溢出率)=(T1的溢出率)/32=9.6Kbps计算得,T1的溢出率=9.6KHz*32=307.2KHz=0.3072MHz(b)T1的溢出率=fosc/(12*(256-TL1))=11.0592MHz/(12*(256-TL1))=0.3072MHz计算得,TL1=253=0x FDH(c)STC-ISP软件计算结果如下图所示:(d)C语言编写的串口1和定时器1初始化代码如下:void UartInit(void)//9600bps@11.0592MHz{PCON&=0x7F;//波特率不倍速SCON=0x50;//8位数据,可变波特率AUXR&=0xBF;//定时器1时钟为Fosc/12,即12TAUXR&=0xFE;//串口1选择定时器1为波特率发生器TMOD&=0x0F;//清除定时器1模式位TMOD|=0x20;//设定定时器1为8位自动重装方式TL1=0xFD;//设定定时初值TH1=0xFD;//设定定时器重装值ET1=0;//禁止定时器1中断TR1=1;//启动定时器1}电源控制寄存器PCON初值:0X7FH----01111111PCON&=0X7F;比特B7B6B5B4B3B2B1B0名字SMOD SMOD0LVDF POF GF1GF0PD IDL 值01111111 SMOD=0;表示串口1的波特率不加倍;SMOD0、LVDF、POF、GF1、GF0、PD、IDL维持原状态位不变;串口1控制寄存器SC0N初值:0X50H-----01010000SC0N&=0X50;比特B7B6B5B4B3B2B1B0名字SM0/FE SM1SM2REN TB8RB8TI RI 值01010000 SMOD0=0,SM1=1;表示串口1工作在模式1方式;SM2=0;表示串口1在方式1非多机通信方式;REN=1;表示维持原状态位不变;TB8、RB8、TI、RI各位分别置0;辅助寄存器AUXR初值:0XBFH-----10111111AUXR&=0XBF;比特B7B6B5B4B3B2B1B0名字T0X12T1X12UART_M0x6T2R T2_C/T T2x12EXTRAM S1ST2值10111111 T1X12=0;表示定时器1是12分频,其速度是传统8051的速度;T0X12、UART_M0x6、T2R、T2_C/T、T2x12、EXTRAM、S1ST2维持原状态位值不变;辅助寄存器AUXR初值:0XFEH------11111110AUXR&=0XFE;比特B7B6B5B4B3B2B1B0名字T0X12T1X12UART_M0x6T2R T2_C/T T2x12EXTRAM S1ST2值11111110 S1ST2=0;表示定时器1作为串口1的波特率发生器;T0X12、T1X12、UART_M0x6、T2R、T2_C/T、T2x12、EXTRAM维持原状态位值不变;辅助寄存器AUXR初值:0XBEH------10111110AUXR&=0XBE;比特B7B6B5B4B3B2B1B0名字T0X12T1X12UART_M0x6T2R T2_C/T T2x12EXTRAM S1ST2值10111110 T1X12=0;表示定时器1是12分频,其速度是传统8051的速度;S1ST2=0;表示定时器1作为串口1的波特率发生器;T0X12、UART_M0x6、T2R、T2_C/T、T2x12、EXTRAM维持原状态位值不变;定时器工作模式寄存器TMOD寄存器初值:0X0FH-----00001111TMOD&=0X0F比特B7B6B5B4B3B2B1B0名字GATE C/T M1M0GATE C/T M1M0值00001111作用域与定时器1有关与定时器0有关GATE(B7)=0;表示不要求条件INT1引脚为高,并且TR1=1的条件定时,亦即定时不受任何条件限制;C/T=0;该位为0时,表示定时器1工作在定时模式;M1=0,M0=0;表示定时器1-16位自动重新加载模式;B3、B2、B1、B0维持原状态位值不变;定时器工作模式寄存器TMOD初值:0X20H------00100000TMOD|=0X20;比特B7B6B5B4B3B2B1B0名字GATE C/T M1M0GATE C/T M1M0值00100000作用域与定时器1有关与定时器0有关M1=1,M0=0;表示定时器1-8位自动重新加载模式;B7、B6、B4、B3、B2、B1、B0维持原状态位值不变;(2)若STC单片机的晶振频率fosc为11.0592MHz,串行口1工作在方式1,定时器T1作为波特率发生器,T1在工作模式2自动重装初值的8位定时方式,已知SMOD=1,要求串行口1的波特率为9600Hz(9600bps),请计算定时器T1的初始值TL1=?。

51单片机串行通讯中波特率的自动检测

51单片机串行通讯中波特率的自动检测

51 单片机串行通讯中波特率的自动检测本文介绍一种在80C51 串行通讯应用中自动检测波特率的方法。

按照经验,程序起动后所接收到的第1个字符用于测量波特率。

这种方法可以不用设定难于记忆的开关,还可以免去在有关应用中使用多种不同波特率的烦恼。

人们可以设想:一种可靠地实现自动波特检测的方法是可能的,它无须严格限制可被确认的字符。

问题是:在各种的条件下,如何可以在大量允许出现的字符中找出波特率的定时间隔。

显然,最快捷的方法是检测一个单独位时间(single bit time),以确定接收波特率应该是多少。

可是,在RS-232 模式下,许多ASCII 字符并不能测量出一个单独位时间。

对于大多数字符来说,只要波特率存在合理波动(这里的波特率是指标准波特率),从起始位到最后一位“可见”位的数据传输周期就会在一定范围内发生变化。

此外,许多系统采用8 位数据、无奇偶校验的格式传输ASCII 字符。

在这种格式里,普通ASCII 字节不会有MSB 设定,并且,UART总是先发送数据低位(LSB),后发送数据高位(MSB),我们总会看见数据的停止位。

在下面的波特率检测程序中,先等待串行通讯输入管脚的起始信号(下降沿),然后起动定时器T0。

在其后的串行数据的每一个上升沿,将定时器T0的数值捕获并保存。

当定时器T0溢出时,其最后一次捕获的数值即为从串行数据起始位到最后一个上升沿(我们假设是停止位)过程所持续的时间。

CmpTable 表格列出了每一波特率的最大测量时间。

这些数据是经过选择的,所以,4 个数据位时间(加上起始位时间)仍可产生正确的波特率。

使用这种方法时,必须遵守一个假设:这种技术仅取决于所接收到的一个字符,接收这个字符的波特率必须大于最低波特率。

本质上来说,这意味着这个字符必须来自正常敲击键盘时所产生的字符。

在PC上,我们不可能快速、连续地敲击两个字符,以欺骗程序。

但是,PC的功能键具有一个问题,因为它会连续发送两个紧挨着的字符,使程序检测得到错误的波特率。

51单片机串口通信程序。。含详细例子

51单片机串口通信程序。。含详细例子

{ P3_4=0; P3_3=1;
} void RstPro()//编程器复位 {
pw.fpProOver();//直接编程结束 SendData();//通知上位机,表示编程器就绪,可以直接用此函数因为协议号(ComBuf[0])还没被修改,下同 }
void ReadSign()//读特征字 {
} void serial () interrupt 4 using 3 //串口接收中断函数 {
if (RI) { RI = 0 ; ch=SBUF; read_flag= 1 ; //就置位取数标志 }
} main()
{ init_serialcom(); //初始化串口 while ( 1 ) { if (read_flag) //如果取数标志已置位,就将读到的数从串口发出 { read_flag= 0 ; //取数标志清 0 send_char_com(ch); } }
while(RI == 0); RI = 0; c = SBUF; // 从缓冲区中把接收的字符放入 c 中 SBUF = c; // 要发送的字符放入缓冲区 while(TI == 0); TI = 0; } }
4.//////////////// /////////////////////////////////////////////////////////
SendData(); } else break;//等待回应失败 } pw.fpProOver();//操作结束设置为运行状态 ComBuf[0]=0;//通知上位机编程器进入就绪状态 SendData(); }
void Lock()//写锁定位
{
pw.fpLock();
SendData();

基于51单片机的称重系统设计

基于51单片机的称重系统设计

单片机作业学院计算机与控制工程学院专业自动化132学号2013022030姓名王伟基于 51 单片机的称重系统一动态称重所谓动态称重是指通过分析和测量车胎运动中的力,来计算该运动车辆的总重量、轴重、轮重和部分重量数据的过程。

动态称重系统按经过车辆行驶的速度划分,可分为低速动态称重系统与高速动态称重系统。

因为我国高速公路的限速最高是120,所以高速动态称重系统在理论上可对 5 到 120 之间时速通过称量装置的车辆进行动态称重。

而低速动态称重系统则一定要限制通过车辆的行驶速度,要想有较高的测量精度,理论要求车辆在5km/h 以下时速匀速通过。

在我国,车辆动态称重一般都使用低速动态称重来完成,在很多收费站和车辆检测站都有应用,国家也出台了相关的测量标准。

与传统意义上的静态称重相比,动态称重可以在车辆缓慢运动情况下直接进行称重,这样动态称重的高效率、测量时间短、能流畅交通等主要特点就凸显出来了。

动态称重的问世,不但使车辆的管理上有了很大的促进作用,而且还对我国的公路管理和维护起到了至关重要的作用。

二系统总体结构及其功能设计总体结构是以51 单片机为处理器的系统,如图 3.1 所示。

上位机键盘输入A/D转换器放大器ADC0832OP07AT89C51桥式称重传感器RS232转换器单片机WPL110蜂鸣器LED显示图3.1本设计要求能判断出车辆是否超载,如果车辆超载,本系统能够提供该车辆的超载信息并发出警报。

本设计采用STC89C52单片机作为系统的处理核心,利用桥式称重传感器到A/D 转换器中转换为数字信号,再经过单片机处理、传输到接口电路,最后送到上位机,该数据可以与上位机里用键盘事先输入设定的总重量作比较并判断出该车辆是否超载,如果超载,则可通过显示器、蜂鸣器作显示超载信息并报警,当然,键盘的作用除了输入设定值还可以解除和开启警报。

三动态称重系统的组成动态称重系统主要由车辆重量(含超载、偏载检测)检测子系统、货车长、宽、高三维尺寸超限检测子系统、自动触发摄像拍照子系统、车辆类型自动判别子系统、系统配置及系统维护子系统、行驶车辆速度测量子系统、数据统计、报表处理子系统和单据输出打印子系统这几部分组成。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include <reg52.h>#define uint unsigned int#define uchar unsigned char#define disp_off 0x3e //关显示#define disp_on 0x3f //开显示#define disp_x 0xb8 //页地址#define disp_z 0xc0 //行地址#define disp_y 0x40 //列地址#define comm 0 //命令标志#define dat 1 //数据标志#define data_ora P0 //MCU P0<------> LCMsbit cs1=P2^0; //cs1=L,选择左半屏sbit cs2=P2^1; //cs2=L,选择右半屏sbit rs =P2^2; //H:写数据,L:写指令sbit rw =P2^3; //H:读,L:写sbit e =P2^4; //读写使能sbit bf =P0^7; //执行操作标志sbit res=P0^4; //复位初始化标志uchar uart_data,temp,baud_set=0x00;uchar dispnum[90];uchar baud[5]={0x00,0x09,0x06,0x00,0x00};uchar r_dat[4]={0x00,0x10,0x00,0x00};uchar code baudrate[7][5]={{0x00,0x00,0x03,0x00,0x00},{0x00,0x00,0x06,0x00,0x00},{0x00,0x01,0x02,0x00,0x00},{0x00,0x02,0x04,0x00,0x00},{0x00,0x04,0x08,0x00,0x00},{0x00,0x09,0x06,0x00,0x00},{0x01,0x04,0x04,0x00,0x00},}; //波特率大小uchar code hz11[]={/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/ /*-- 文字: 发--*/0x00,0x00,0x00,0xE0,0xA0,0x80,0x80,0xF0,0x80,0xA0,0xB0,0x80,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x1C,0x14,0x13,0x1B,0x0D,0x07,0x0B,0x18,0x18,0x30,0x10,0x00,/*-- 文字: 送--*/0x00,0x80,0xD0,0xB0,0xA0,0x80,0x80,0x70,0x40,0xC0,0x60,0x50,0x40,0x00,0x00,0x00,0x08,0x08,0x08,0x0C,0x0B,0x08,0x09,0x0D,0x1B,0x13,0x13,0x35,0x3D,0x30,0x10,0x08,/*-- 文字: 数--*/0x00,0x00,0x40,0xE0,0x40,0xF0,0xE0,0x70,0x00,0xF0,0x50,0xC0,0x40,0x40,0x00,0x00,0x00,0x02,0x13,0x16,0x1E,0x0B,0x16,0x13,0x11,0x0B,0x06,0x0F,0x18,0x18,0x10,0x00,/*-- 文字: 据--*/0x00,0x00,0x40,0x40,0xF0,0x40,0x40,0xF0,0x60,0x50,0xD0,0x50,0x70,0x60,0x00,0x00,0x00,0x12,0x13,0x31,0x1F,0x11,0x0D,0x07,0x3D,0x15,0x17,0x15,0x3D,0x1D,0x03,0x00,};uchar code hz12[]={/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/ /*-- 文字: 波--*/0x00,0x80,0x20,0x20,0x40,0x40,0xE0,0x20,0x20,0xF0,0x30,0x20,0x20,0xC0,0x00,0x00,0x00,0x19,0x09,0x0D,0x14,0x18,0x27,0x31,0x13,0x0D,0x0D,0x1B,0x18,0x30,0x30,0x10,/*-- 文字: 特--*/0x00,0xC0,0x60,0x40,0xF0,0x60,0x40,0xA0,0xA0,0xF0,0xF0,0xA0,0xA0,0x80,0x80,0x00,0x00,0x02,0x02,0x02,0x3F,0x01,0x01,0x12,0x26,0x2E,0x2A,0x3F,0x1A,0x02,0x00,0x00,/*-- 文字: 率--*/0x00,0x00,0x20,0x60,0x60,0xA0,0x60,0xB0,0x70,0xA0,0xA0,0x60,0x20,0x20,0x00,0x00,0x00,0x04,0x04,0x07,0x05,0x04,0x05,0x3F,0x1F,0x05,0x05,0x05,0x0C,0x0C,0x04,0x00,/*-- 文字: 为--*/0x00,0x00,0x00,0x80,0x80,0xB0,0xA0,0x80,0x80,0xC0,0xE0,0xB0,0x80,0x80,0x00,0x00,0x00,0x10,0x18,0x18,0x0C,0x04,0x02,0x01,0x13,0x36,0x34,0x30,0x1E,0x07,0x00,0x00,};uchar code num[]={/*-- 隶书12; 此字体下对应的点阵为:宽x高=8x16 --*/ /*-- 文字: 0 --*/0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,/*-- 文字: 1 --*/0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00, 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, /*-- 文字: 2 --*/0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00, 0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00, /*-- 文字: 3 --*/0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00, 0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00, /*-- 文字: 4 --*/0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00, 0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00, /*-- 文字: 5 --*/0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00, 0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00, /*-- 文字: 6 --*/0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00, 0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00, /*-- 文字: 7 --*/0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00, 0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00, /*-- 文字: 8 --*/0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00, 0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00, /*-- 文字: 9 --*/0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, 0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00, /*-- 文字: a --*/0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00, 0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20, /*-- 文字: b --*/0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00, 0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00, /*-- 文字: c --*/0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00, 0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00, /*-- 文字: d --*/0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00, 0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00, /*-- 文字: e --*/0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00, 0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00, /*-- 文字: f --*/0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,/*-- 文字: x --*/0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,};uchar code dispunit[]={/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/ /*-- 文字: b --*/0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,/*-- 文字: p --*/0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,/*-- 文字: s --*/0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,};uchar code hz13[]={/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/ /*-- 文字: 发--*/0x00,0x00,0x00,0xE0,0xA0,0x80,0x80,0xF0,0x80,0xA0,0xB0,0x80,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x1C,0x14,0x13,0x1B,0x0D,0x07,0x0B,0x18,0x18,0x30,0x10,0x00,/*-- 文字: 送--*/0x00,0x80,0xD0,0xB0,0xA0,0x80,0x80,0x70,0x40,0xC0,0x60,0x50,0x40,0x00,0x00,0x00,0x08,0x08,0x08,0x0C,0x0B,0x08,0x09,0x0D,0x1B,0x13,0x13,0x35,0x3D,0x30,0x10,0x08,/*-- 文字: 数--*/0x00,0x00,0x40,0xE0,0x40,0xF0,0xE0,0x70,0x00,0xF0,0x50,0xC0,0x40,0x40,0x00,0x00,0x00,0x02,0x13,0x16,0x1E,0x0B,0x16,0x13,0x11,0x0B,0x06,0x0F,0x18,0x18,0x10,0x00,/*-- 文字: 据--*/0x00,0x00,0x40,0x40,0xF0,0x40,0x40,0xF0,0x60,0x50,0xD0,0x50,0x70,0x60,0x00,0x00,0x00,0x12,0x13,0x31,0x1F,0x11,0x0D,0x07,0x3D,0x15,0x17,0x15,0x3D,0x1D,0x03,0x00,};uchar code hz14[]={/*-- 隶书12; 此字体下对应的点阵为:宽x高=16x16 --*/ /*-- 文字: 为--*/0x00,0x00,0x00,0x80,0x80,0xB0,0xA0,0x80,0x80,0xC0,0xE0,0xB0,0x80,0x80,0x00,0x00,0x13,0x36,0x34,0x30,0x1E,0x07,0x00,0x00,};/************************函数声明***********************/void chk_busy (void); //判断LCD工作状态void delay (uint us); //us延时函数void init_uart(void); //初始化串口程序void wr_lcd (uchar dat_comm,uchar content);//写数据或命令到LCDvoid init_lcd (void); //初始化LCD程序void lat_disp (uchar data1,uchar data2);//LCD写点阵程序void chn_disp (uchar x,uchar y,uchar xl,uchar yl,uchar row_xl,uchar row_yl,uchar *chn);//写字符函数void change(void); //调整波特率显示码程序void change_dat(void); //调整接收到的数据为显示码程序void disp (void); //LCD显示程序void measure(void); //1bit数据发送时间测量程序void search(void); //查询发送数据波特率程序void init_T0 (void); //T0初始化程序void disp_dat(void); //数据显示程序/**********************主程序***********************/void main (){init_T0 (); //初始化T0init_lcd (); //初始化LCDmeasure (); //检测主机发送波特率init_uart(); //初始化串口disp(); //调用显示while (1){disp_dat(); //修改接收数据}}/***********************us延时函数**********************/void delay (uint us){while(us--);}/**********************T0初始化程序***********************/void init_T0 (void){TMOD=0x01; //工作方式1TH0=0x00; //初始化定时器内部寄存器TL0=0x00;}/***************1bit数据发送时间测量程序*************/void measure(void){while(RXD); //等待主机发送起始位0TR0=1; //启动定时器计时while(!RXD); //等待主机发送最高位1TR0=0; //定时器停止计时baud_set=TH0; //将1bit的发送时间存入baud_SET }/**********************初始化串口程序********************/void init_uart(void){SCON=0x50; //工作方式1,允许接收TMOD=TMOD|0x20; //T1为工作方式2TH1=255-baud_set; //设置T1TL1=255-baud_set;ES=1; //允许串行中断EA=1; //开总中断TR1=1; //启动定时器T1SBUF=0x0d; //向主机发送确认码}/********************判断LCD工作状态********************/void chk_busy (void){data_ora=0xff;rs=0; //命令标志rw=1; //读数据e=1;while(bf||res==1);e=0;}/*******************写数据或命令到LCD******************/void wr_lcd (uchar dat_comm,uchar content){chk_busy (); //查看LCD是否处于忙状态rs=dat_comm; //写入命令/数据rw=0; //写数据data_ora=content; //送命令/数据e=1;e=0;}/*********************初始化LCD程序********************/void init_lcd (void){delay(50);cs1=0;cs2=0;wr_lcd (comm,disp_off);wr_lcd (comm,disp_on); //开显示lat_disp(0x00,0x00); //清屏}/********************LCD写点阵程序*********************/void lat_disp (uchar data1,uchar data2){uchar i,j;cs1=0;cs2=0;wr_lcd (comm,disp_on);for(j=0;j<8;j++){wr_lcd (comm,disp_x+j); //设置页地址wr_lcd (comm,disp_z); //设置起始行wr_lcd (comm,disp_y); //设置列地址for(i=0;i<32;i++){wr_lcd (dat,data1);wr_lcd (dat,data2);}}}/**********************写字符函数**********************/void chn_disp (uchar x,uchar y,uchar xl,uchar yl,uchar row_xl,uchar row_yl,uchar *chn) {uchar i,j,k,l,a;wr_lcd (comm,disp_on); //开显示for(l=0;l<row_xl;l++) //行数循环{for(k=0;k<row_yl;k++) //字数循环{for(j=0;j<xl;j++){wr_lcd (comm,disp_x+x+l*xl+j); //行数调整wr_lcd (comm,disp_z); //列数调整wr_lcd (comm,disp_y+y+k*yl); //字数调整a=l*xl*yl*row_yl+k*xl*yl+j*yl;for(i=0;i<yl;i++) //写数据wr_lcd (dat,chn[a+i]);}}}}/****************调整波特率显示码程序******************/void change(void){uchar temp,i,j,n=0;for(j=0;j<5;j++){temp=baud[j];if((j==0&baud[0]==0x00)|((j==1&baud[1]==0x00))){for(i=0;i<16;i++)dispnum[n++]=0x00;}else{for(i=0;i<16;i++)dispnum[n++]=num[i+temp*16];}}}/*************调整接收到的数据为显示码程序*************/void change_dat(void){uchar temp,i,j,n=0;r_dat[2]=uart_data/16; //将高四位存入r_dat[2]r_dat[3]=uart_data%16; //将低四位存入r_dat[3]for(j=0;j<4;j++){temp=r_dat[j];for(i=0;i<16;i++)dispnum[n++]=num[i+temp*16];//转换显示码}}/*********************LCD显示程序*********************/void disp (void){lat_disp(0x00,0x00); //清屏search(); //查询波特率显示码change(); //调整显示码cs1=0;cs2=1; //显示LCD屏幕左侧前三行信息chn_disp (0,0,2,16,1,4,hz11);chn_disp (2,24,2,8,1,5,dispnum);chn_disp (4,0,2,16,1,4,hz13);cs1=1;cs2=0; //显示LCD屏幕右侧前三行信息chn_disp (0,0,2,16,1,4,hz12);chn_disp (2,8,2,8,1,3,dispunit);chn_disp (4,0,2,16,1,1,hz14);}/*********************数据显示程序*********************/void disp_dat(void){change_dat(); //调整显示cs1=0;cs2=1;chn_disp (6,24,2,8,1,4,dispnum); //将接收到得数据显示在屏幕左侧第四行}/********************串口中断程序********************/void serial_TI(void) interrupt 4{if(RI==1){RI=0; //接收中断,清零RIuart_data=SBUF; //将接收数据存入temp,并将接收数据发送至上位机SBUF=uart_data;temp=uart_data;}else //发送中断,清零RITI=0;}/**************查询发送数据波特率程序***************/void search(void){uchar i;switch(baud_set){case 0x5f:for(i=0;i<5;i++)baud[i]=baudrate[0][i]; //波特率为300break;case 0x2f:for(i=0;i<5;i++)baud[i]=baudrate[1][i]; //波特率为600break;case 0x17:for(i=0;i<5;i++)baud[i]=baudrate[2][i]; //波特率为1200break;case 0x0b:for(i=0;i<5;i++)baud[i]=baudrate[3][i]; //波特率为2400break;case 0x05:for(i=0;i<5;i++)baud[i]=baudrate[4][i]; //波特率为4800break;case 0x02:for(i=0;i<5;i++)baud[i]=baudrate[5][i]; //波特率为9600break;case 0x01:for(i=0;i<5;i++)baud[i]=baudrate[6][i]; //波特率为14400break;default:for(i=0;i<5;i++)baud[i]=0x0e; //超出测量范围,显示EEEEE break;}}。

相关文档
最新文档