我们日常接触的线材如USB、HDMI、VGA及网线等在生产过程中一般都需要做导通、线序测试。其中有Overmolding制程的产品还需做短路测试。其对应的连接器也需要做同样的测试。厂商的通常做法是购买线缆测试仪来测试。由于线缆测试仪是通用检测设备,单价比较高,体积也比较大。如果用来测USB、网线,及连接器有点大材小用;用起来也不是十分方便。如果自行设计,成本会更低;特别是用于连接器制程检测,更容易嵌入自动化机台中,弥补PLC采样灵活性不足,并可减少所需PLC的输入/输出点数,降低PLC购置费用。下面就讲解如何来设计来设计这种测试治具。
如何来设计测试治具呢?既然线材与连接器的作用都是连接。那么我们就把它作为数据传输通路,分别连接到接收与发送的I/O口上,用它来传送数据。将发送的数据与接收的数据比较,如果与接线相符, 那么被测样品OK,反之则NG。是不是原理很简单?明白了测试原理,我们就可以动手来做了。
下面一网线测试为例,讲解如何设计制作这类治具。先设计制作一个网线测试仪。如果要在制程中使用,不但要测试网线的好坏,还要测出问题出在哪里,为制程改善提供依据。搞这个东西需软硬兼施,即既要设计硬件系统,又要做软件编程。还需要设计机箱与等,这不是这里需要讨论的范畴,就不做说明。
一 硬件设计 这是一个简单的测试治具,其硬件部分很简单,如下图示:
采用4节1.5V电池串联供电,主供电电路上串接了一只1N4001二极管。二极管有两个作用:降压与防电源极性弄反损坏元件。电源开关采用2位拨动开关,电源指示用LED。网线插座可采用两只648 8P8C,或带线RJ45 如下图:
按原理图分别与P1、P2口相接,Pin对应关系: bit0-1,bit1-2,...bit7-8。
网线的接法有两种,一种是直连互联法,一种是交叉互联法。交叉线的做法是:一头采用568A标准,一头采用568B标准。平行(直通)线的做法是:两头同为568A标准或568B标准。一般用568B直通做法。568A标准:白绿1, 绿2, 白橙3, 蓝4,白蓝 5,橙6, 白棕7, 棕8。
568B标准:白橙1,橙2, 白绿3, 蓝4,白蓝5, 绿6, 白棕7, 棕8。
水晶头的线号如下图:
我们做的测试治具,必须两种接法的线读必须能测。上面原理图中设计两个按钮开关,一个做模式选择,一个做选择确认。原理图中设计有蜂鸣器驱动电路,用蜂鸣器声做按键音。另外有两个LED驱动电路,用以驱动NG/OK指示灯。原理图中LCD1602接口,接LCD1602显示屏。用LCD1602显示测试的详细信息。
二 软件设计
1. 明确设计目标 (或任务)软件设计前须做功能定义,没有设计目标就没法写程序。这个一般是由需求方定义,设计方依据这个定义设计硬件与软件;或则由设计方定义,再由需求方确认。现在就来做功能及定义。 1). 开机自检 由于原理图没有设计系统自检电路, 那就只有通过输出让使用者判定系统是否有问题。要求开机后,蜂鸣器鸣2声,NG指示灯(红灯接P3.2),OK指示灯(绿灯接P3.3)亮2秒后熄灭。2)开机界面 LCD1602第一行显示: P_T Mode. 即Pass Through Mode的缩写, 直通测试模式的意思。第二显示 Y_KeyL N_KeyR。意思按左边键确认使用当前测试模式,按右边键切换到另一测试模式。3) 模式切换 如果在开机界面下按左边键,即进入Pass Through Mode。如果按右边键,第一行显示 Cross Mode,即交叉线测试模式。如果再按右边键,第一行又显示: P_T Mode。按左边键进入前显示的测试模式。4)测试界面 空闲时第一行显示测试模式 (P_T Mode或Cross Mode),第二行显示 No Test。 由于测试时间很短,不做测试中界面。测试结果显示,如果测试结果为 OK, 第一行显示 OK 12345678,否则显示 NG 12345678 。第二行显示对应接通线号,如果有不到通的则显示空格。NG时,NG灯亮,OK灯不亮,蜂鸣器长鸣。OK时,OK灯亮,NG灯不亮,蜂鸣器不发声。进入测试界面后,不再响应按键。
2. 软件设计 依据以上设计要求可将程序大致分为以下几部分: 端口定义,初始化程序,测试程序,测试状态及结果显示程序几部分。下面一步一步来完成这个程序。
2.1 Network Cable Test.uvproj 新建一个Network Cable Tester 文件夹,将以前教程创建的C51 Template文件夹下的所有文件及文件夹复制到这个文件夹下,这样可以节省配置Proj时间(如果你不是新手,完全可以自己从头开始创建)。新建三个文件分别以myport.h, main.h,main.c 存在User文件夹下。 myport.h用于端口定义, 完成后的代码如下:
/*myport.h
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 11/21/2021
*/
#ifndef __MYPORT_H_
#define __MYPORT_H_
#include "stc15w4k.h"
#define LCD_DATAPINS P0
#define PORT_IN P1
#define PORT_IN P2
sbit LCD_RS = P4^1;
sbit LCD_RW = P4^2;
sbit LCD_EA = P4^4;
sbit LED_NG = P3^2; //NG LED control_bit
sbit LED_OK = P3^3; //OK LED control_bit
sbit BTN_L = P3^4; //left button input_bit
sbit BTN_R = P3^5; //right button input_bit
sbit BUZZER = P4^5; //buzzer control_bit
#endif
不用说就知道main.h是main.c的头文件。在main.h里面,包含需用到的库函数头文件,定义系统时钟(延时程序需用到),定义main.c需要用到的变量及函数,完成后如下:
/*main.h
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 11/21/2021
*/
#ifndef __MAIN_H_
#define __MAIN_H_
#include "mtype.h"
#include "stcio.h"
#include "lcd.h"
#include "delay.h"
const FSYSCLOCK FSCLK = F30MHz; //define system clock frequency 30MHz, FSYSCLOCK was defineed in mtype.h
ui8 testRes = 2; //test result, 0--NG, 1--OK, 2, No Test
BOOL modeFlag = 0; //test result, 0--PT mode, 1--Cross mode
ui8 tem = 0;
ui8 tem1 = 0;
ui8 mstr1[17]=" ";//space for clraring text
ui8 mstr2[9] = "12345678";
ui8 mstr3[17] = "";
void SoundBuzzerx10ms(ui8 x);
void LED_NgOn();
void LED_NgOff();
void LED_OkOn();
void LED_OkOff();
void PT_Test();
void Cross_Test();
void DispalyResult();
#endif
包含的库函数头及其实现在前面的教程中已经讲过,可从教程中复制,或者到网站下载. 在包含了头文件后,需将库函数的.c文件添加到Proj,否则编译时会出错。将鼠标光标移动到Lib上,点击鼠标右键。
在弹出菜单点击Add Existing Files to Group‘Lib’
选中delay.c,mtype.c,stcio.c,lcd.c
点击右下角的Add按钮,再点击Close关闭对话框,回到编程界面。
点击Lib前的+,展开可看到delay.c,mtype.c,stcio.c,lcd.c已加入,如下:
这里先说下如何改Proj名及设置生成的编译文件名。 可以看到Proj名为C51 Template
如何将Proj名改为Network Cable Test呢?退出Keil,直接将Proj文件夹下的 C51 Template.uvproj重命名为Network Cable Test.uvproj。
再启动Keil,打开Network Cable Test.uvproj,Proj名就改过来了,如下:
点击Options for Target
在弹出对话框中,点击Output按钮
将Name ofExecute 后面输入框中的C51 Template 改为Network Cable Tester
编译程序,得到如下结果:
可以看出生成的hex文件名也变成了Network Cable Tester 。
2.2 函数代码实现 实现main.c是整个程序最重要的部分,下面稍微详细讲解如何实现。没有函数实现的main.c如下:
/*main.c
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 11/21/2021
*/
#include "main.h"
void main()
{
while(1)
{
}
}
首选实现main.h中定义的部分函数,先将定义的函数复制到main.c中,分别去掉后面的分号,加上函数体的花括号. 并完成部分函数代码,如下:
/*main.c
Designed by Bill Liu
Version 0.0
Modified last by Bill Liu on 11/21/2021
*/
#include "main.h"
void main()
{
while(1)
{
}
}
//***********************************************
void SoundBuzzerx10ms(ui8 x)
{
BUZZER = 0;
Delay10xms(x, FSCLK);
BUZZER = 1;
}
//End of SundBuzzerx10ms(ui8 x)
//***********************************************
void LED_NgOn()
{
LED_NG = 0;
}
//End of LED_NgOn()
//***********************************************
void LED_NgOff()
{
LED_NG = 1;
}
//End of LED_NgOff()
//*********************************************
void LED_OkOn()
{
LED_OK = 0;
}
//End of LED_OkOn()
//*********************************************
void LED_OkOff()
{
LED_OK = 1;
}
//End of LED_OkOff()
//*********************************************
void PT_Test()
{
}
//End of PT_Test()
//********************************************
void Cross_Test()
{
}
//End of Cross_Test()
//********************************************
void DispalyResult()
{
switch(testRes)
{
case 0: //No test
LCD1602_DisplayString(0, 0, mstr1, 0);//clear line1
LCD1602_DisplayString(4, 0, "P_T Mode", 0);
LCD1602_DisplayString(0, 1, mstr1, 0);//clear line2
LCD1602_DisplayString(4, 1, "No Test", 0);
LED_NgOff();
LED_OkOff();
BUZZER = 1;
break;
case 1: //OK
LCD1602_DisplayString(0, 0, mstr1, 0);//clear line1
LCD1602_DisplayString(0, 0, "OK", 0);
LCD1602_DisplayString(4, 0, mstr2, 0);
LCD1602_DisplayString(0, 1, mstr1, 0);//clear line2
LCD1602_DisplayString(4, 1, mstr3, 0);
LED_NgOff();
LED_OkOn();
BUZZER = 1;
break;
case 2://NG
LCD1602_DisplayString(0, 0, mstr1, 0);//clear line1
LCD1602_DisplayString(0, 0, "NG", 0);
LCD1602_DisplayString(4, 0, mstr2, 0);
LCD1602_DisplayString(0, 1, mstr1, 0);//clear line2
LCD1602_DisplayString(4, 1, mstr3, 0);
LED_NgOn();
LED_OkOff();
BUZZER = 0; //sound buzzer
break;
}
}
//End of DispalyResult()
在 main函数中加入 初始化代码,如下:
在main函数中添加响应按键代码,如下:
到此,main函数代码就完成了。接下来完成PT_Test()函数。PT_Test()函数相对比较简单,从输出口输出一个数据,如果输入口收到的数据与输出口的数据相等,测试结果为OK,如果输入数据没变化,说明线缆未连接,没有测试,否则就为NG,如果为NG,则需查询不良Pin。显示结果。因功能定义要求,进入测试状态后,不响应按键。因此以上代码需放入一个死循环中。完成后的代码如下:
//*********************************************
void PT_Test()
{
ui8 i,j;
while(!modeFlag)
{
testRes = 1;
PORT_OUT = 0x00;
PORT_IN = 0xFF;
Delayxms(2,FSCLK);
if(PORT_IN== 0xFF)
testRes = 2;
else
{
for(i = 0; i < 8; i++)
{
PORT_OUT = ~(1 << i);
//PORT_IN = 0xFF;
Delayxms(2,FSCLK);
if(PORT_IN== PORT_OUT)
mstr3[i] = mstr2[i];
else if(PORT_IN== 0xFF)
{
testRes = 0;
mstr3[i] = ' ';
}
else
{
testRes = 0;
j = 0;
tem = ~PORT_IN;
while((tem >> j) != 1)
{
j++;
}
mstr3[i] = mstr2[j];
}
}
}
//display result
if(tem1 != testRes) //avoid frequently refresh
{
DispalyResult();
tem1 = testRes;
}
}
}
//End of PT_Test()
Cross_Test()函数相对麻烦一些,由于线缆两个接头分别为A,B,对应关系如下:
代码中需处理线的交叉 , 完成后的代码如下:
//********************************************
void Cross_Test()
{
ui8 i,j;
while(modeFlag)
{
testRes = 1;
PORT_OUT = 0x00;
PORT_IN = 0xFF;
Delayxms(2,FSCLK);
if(PORT_IN== 0xFF)
testRes = 2;
else
{
for(i = 0; i < 8; i++)
{
PORT_OUT = ~(1 << i);
Delayxms(2,FSCLK);
if(PORT_IN== PORT_OUT)
mstr3[i] = mstr2[i];
else if(PORT_IN== 0xFF)
{
testRes = 0;
mstr3[i] = ' ';
}
else
{
j = 0;
tem = ~PORT_IN;
while((tem >> j) != 1)
{
j++;
}
mstr3[i] = mstr2[j];
}
}
if(testRes==1)
{
if(strcmp(mstr3, "36145278"))
testRes = 0;
}
}
//display result
if(tem1 != testRes) //avoid frequently refresh
{
DispalyResult();
tem1 = testRes;
}
}
}
//End of Cross_Test()
程序编译结果如下:
到这里所有软硬件设计,就完成了。该程序的代码已上传到文件名为Network Cable Tester Code.rar。如需查看可搜索下载。