激光测距机故障检测软件的优化
激光测距机故障检测软件的优化
作者:孙斌;万强;郭延龙;林轶
激光测距仪机检修仪是针对目前军用激光测距机装备型号多、技术含量大、部队维修人员少、维修能力弱等问题而研制的新一代智能检修仪。它是一种能够实时、快速、有效地实现故障检测、信息传递、诊断分析、故障定位、维修方案确定等过程的自动化,最终以形象直观的方法指导普通技术人员对电路故障进行元件级的诊断与维修。该系统采用了基于 ADUC812+CPLD 的硬件平台,利用 C51软件编程,在 LCD 上显示交互界面和检测结果。由于激光测距机的品种多,检测信息量大,软件编制的工作量十分大,完成后的程序大小接近 64K。本文阐述了软件中的一些编程技巧。
2 设计方案及程序设计中的技巧
软件实现了对检修仪所有输入输出信号的控制,包括初始化硬件、人机交互、对激光测距机自动进行检测、数据处理、通讯等等。
2.1 CPLD 负责逻辑管理,Bank 切换时保护现场
本系统中共有地址线 21 条,2MB 地址空间。包括有 LCD 口,I/O 口,512k 汉字字库,A/D 口, 64k 内存 SRAM,以及两个 512k 的 table。这些 Bank的地址分配由 A16-A20 区分开,A16-A20 分别连在单片机 P1.0-P1.4 脚上。系统用 1 片 Altera MAX3128CPLD 来负责逻辑管理,利用 CPLD 丰富的I/O口资源和强大的逻辑管理功能,可以减轻mcu的负担并且扩展了 I/O 口,对于检测激光测距机各单板的多通道信号游刃有余。程序中的临时变量、全局变量、局部变量都存放在内存中。而当程序需读取 A/D 转换后的数据时,需要切换 Bank,选中A/D,这样才能正确地向 A/D 发出命令和接收转换后的数字,否则根本操作不了。反过来,如果 A/D转换已经完成,需要存储数据到变量中,那么也要切换 Bank 到内存,否则会把数据存到另一个地方。 LCD 也是一样,在操作 LCD 时要选中 LCD,在向显示缓冲区存数据时,必须选中 SRAM。由于切换操作如此频繁,程序把它们设计成了函数,分别为CS62256( )、CSIO( )、CSLCD( )、 CS197( )、 CSHZLIB( )、CSTABLE1( )、CSTABLE2( ),切换时调用这些函数既可。因为这些 Bank 的低 16 位地址是公用的,区别在于高 5 位,调用相应的函数,才能正确区分开不同的 Bank,向唯一的 Bank 发位选信号,同时其他 Bank 是收不到的,保证了只对一个唯一的地址进行操作。在 Bank 切换时需要保护好现场,入口用临时变量存储 P1,出口把临时变量的值赋给 P1,否则就会程序跑乱,LCD 上满屏乱码。
2.2 动态 BCD 码和动态七段码读取、处理与显示
端口的数据是不断变化的,个位、十位、百位、千位、万位的数字是随着位选信号的出现而出现,维持在口线上的时间大概在 1~2s。因此要正确地读取数据,必须首先快速准确地捕捉位选信号。程序中,在程序存储器中建立了 1 个位选码表,用 1个 for 循环,逐位捕捉位选信号。假设先捕捉个位的位选(假设高电平有效),那么程序在没有接收到 0x01 这个个位位选信号之前,是不会读取数据的。一旦捕捉到了,马上读取个位数字并存储到字符数组中,以供后面显示。捕捉到数据后还要进行数据的筛选,因为有些数据可能不符合条件,比如毛刺和传输畸变造成的乱码,或者数据为全零,这时候就要把这些没有意义的数据去掉,转而去端口重新捕捉。正确合理的数据被读取进来后,需要调用事先写好的BCD码到 ASCII码和7段码到 ASCII码的转换程序,从而把读进来的数据变成可以打在LCD 上显示的字符,以方便用户进行故障判断和结果分析。
2.3 A/D 转换后数据的读取、处理与显示
A/D 转换后的数据是一个 0~2048(双极性± 10V)或者 0~4096(单极性+10V)的整数。程序中要求能把它变成带符号的整型数据,最终直接根据这一数值,变成一个真实的电压值显示在屏幕上。为此编写了 AdtoBcd 的函数,它能把 A/D 转换后的数据经过计算后处理成真实电压值,并逐位剥离出它的个、十、百、千、万各位数字。所以该函数被定义为指向字符的指针变量,函数返回一个字符数组的首地址,个、十、百、千、万各位数字的 ASCII 码就保存在这个数组中,要显示时直接调用事先写好的 LCD 显示字符函数 Write_CC_EX 即可。因为该函数的参数是: x: 显示字符的 x 坐标,以 byte 为一个移动单位; y 显示字符的 y 坐标,以行为单位;
*p 指向字符串的指针;Reverse 0xFF 反白显示,0x00 正常显示。
例如:Write_CC_EX(24,25,Advalue(Read_AD(0,0)),0);这条语句的作用就是在座标为(24,25)的地方显示采集到的A/D第 0通道的电压值,且不反白显示。 编写 AdtoBcd 这个函数,需要事先推出公式 Y = X*10*scale/2048,其中 X 是 A/D 转换后得到的数据,Y 是实际的电压值。Scale 是满度标定数,假设1kV 经过处理后输入进 A/D,转换的值为 2048(双极性)或者 4096(单极性),那么 Scale=1000。Y的值得到后也不能马上就送去显示,因为这只是一个整数值,还需要逐位剥离出这个整数的个、十、万位,变成 ASCII 码存进字符数组中,否则显示不了。完成这个功能用一个 for 循环即可完成。但是由于需要显示的真实电压保留一位小数,要特别注意小数点的存放,在程序中要专门加上判断小数点位置的语句。另外需注意在存放真实电压各位数值的字符数组的结尾加上电压单位 V 和字符串结束标志\0。
2.4 用定时器实现精确延时,用软件实现估计延时
由于要对多种激光测距机的单板进行检测,所以要能够处理各种类型的信号。例如激光电源板的强电信号以及逻辑译码板的弱电信号。强电常常是600V~1000V 的充电高压,弱电则在 0.7V~5V 之间,此外还有正负脉冲。这些信号在时序上有着严格的关系,就 85 手持式激光电源板来说,首先通过 TTL 口输出信号来供电,并置选通控制为 1,但不能接着去读端口数据,因为继电器还未充分吸合,必须延时大概 100ms。不同的单片机有着不同的时钟周期,那么一条指令的执行时间也不会相同。在硬件系统上,执行一条指令估计需要 1ìs 的时间,与单片机定时器精确的延时相比误差很大。在程序中大量使用的是精确的定时器延时。方法是:先设置定时器的中断间隔,设定为 2ms,然后在定时器(如 TIMER0)中断服务程序中设置如下语句,if(LogicDelay!=0) TimeDelay--;当 2ms 定时器的中断一到,全局变量 LogicDelay 就会被减 1。再编写一个延时函数 LogicTimeDelay(uint t),参数为 t,它的数值就是精确延时的时间,该函数为:void LogicTimeDelay(uint t) { LogicDelay = t/2; while (LogicDelay!=0); } t/2 是方便在调用延时函数时,直接写需延时的时间,否则要把设定的 t 乘以 2 是真正延时的时间。当调用这个延时函数时,LogicDelay 的值只会在中断服务程序中减少,当它没有减到 0,就会一直停步不前,这样延时的时间就由中断间隔以及设定的LogicDelay 初值决定。如想延时 200ms,直接写LogicTimeDelay(200)。
软件估计延时的优点是延时时间可以在 ìs 级别。而上述的定时器精确延时在 ms 级别。当程序中要求延时几个到几十个 ìs 的时候,只能用软件估计延时。例如激光测距机电源板检测中要求在发出充电信号后等待几百 ìs,在这么短的时间内观测充电高压是否正常。如果用定时器来延时,尽管延时时间很精确,但 ms 级别的延时就会使充电板的充电高压充到 900V 以上,如果碰到故障板、充电电压不截止、延时过长、或没有及时断电停充,所造成的后果就很危险。但如果是 ìs 级别的延时,电压不可能充到那么高,再加上实时监测,一旦超过极限就断电停充。
使用 LogicDelay 函数来精确延时只是一方面的功能,另一方面还可以做计时器,精确地记录ms 级以及更高时间级别脉冲信号的脉宽。方法是给LogicDelay 置初值,例如 1500(1.5s),在一个 while循环中实时地监测某一脉冲信号,当电平发生反转时,跳出循环,把此时 LogicDelay 的值记录下来,经过计算就能得到脉冲宽度。
2.5 双 while 循环检测窄脉冲技巧
在检测单板时,有些信号在某个控制信号被置1 或置 0 后过若干 ms 或若干 ìs 会在某个 I/O 口产生,并且这个信号脉宽很短,有的只有几十 ìs。如果按常规给控制信号延时后读这个脉冲,很有可能检测不到。
从上面的程序可以看到,在发出回波以后,并没有延时,而是直接进入第一个 while 循环。读 AGC信号的对应端口,如果为低,退出第一个 while 循环,证明 AGC 信号确实来临,并且翻转过,否则 t累加。如果 AGC 信号当 t 加到 1000 还没有为低,证明没有 AGC 信号。AGC 翻转后程序进入第二个while 循环。与第一个相反,它是当 AGC 信号的对应端口为高时,退出循环。否则 t1 累加,当加到 5时(大约 100µs)还没有为高,证明 AGC 信号过长。如果 t1 小于 5,证明脉宽也在 100µs 以内,属于正常。所以只有经过两个 while 循环,t<1000 且 t1<5,才能说 AGC 控制正常。
2.6 串口发送数据时遇到的问题
首先波特率要与上位机设置一致,否则会因双方接收不到数据而无法通讯,一般有 9600bps、 38400bps、115200bps 几种。只要向 RCAP2H、 RCAP2L 中置入数值即可。单片机向上位机发送数据的函数一定要考虑两次发送数据的时延。在程序中用一个全局变量作为标志,在串口没有完成这次数据发送任务的时候,该变量标志禁止程序运行到下一个发送函数,这样就保护了这次要发送的数据不被下一次要发送的数据干扰。调试时如果没有加发送完成标志,则会造成上位机接收到的数据丢失或混乱。在发送完成标志的基础上再加上 50ms 的延时能够完全做到数据不丢失、不混乱。如果不加上这个标志,则加大波特率,从而加快发送数据的速度,也能暂时解决这一问题。但两次发送数据的间隔很短时,加大波特率也会出现数据丢失现象。 如果加大波特率,并加上发送完成标志则完全消除上述现象。
3 总 结
在用 C51 实现嵌入式系统设计时,各种中断服务程序的利用、地址空间的分配以及具体 C 程序的模块性和精简性是决定其效果的关键部分。在基于ADUC812 系统的激光测距机检测与界面设计与调试中发现,采用如上文所述的算法简单清晰,兼有实用、高效的特点。而且 ADUC812 系统有较大的内部数据存储器和程序存储器,检测时大量的数据计算显得相当简单和快速。另外 CPLD 有丰富的 I/O口资源和强大的逻辑管理功能,可以减轻 MCU 的负担并且扩展了 I/O 口,对于检测激光测距机各单板的多通道信号是足够的。利用 ADUC812+CPLD 来实现嵌入式系统来完成检测、显示、运算,是一种经济实用的选择。
本文章转自爱学术(aixueshu.com),如有侵权,请联系删除