我们日常接触的线材如USB、HDMI、VGA及网线等在生产过程中一般都需要做导通、线序测试。其中有Overmolding制程的产品还需做短路测试。其对应的连接器也需要做同样的测试。厂商的通常做法是购买线缆测试仪来测试。由于线缆测试仪是通用检测设备,单价比较高,体积也比较大。如果用来测USB、网线,及连接器有点大材小用;用起来也不是十分方便。如果自行设计,成本会更低;特别是用于连接器制程检测,更容易嵌入自动化机台中,弥补PLC采样灵活性不足,并可减少所需PLC的输入/输出点数,降低PLC购置费用。下面就讲解如何来设计来设计这种测试治具。

      如何来设计测试治具呢?既然线材与连接器的作用都是连接。那么我们就把它作为数据传输通路,分别连接到接收与发送的I/O口上,用它来传送数据。将发送的数据与接收的数据比较,如果与接线相符, 那么被测样品OK,反之则NG。是不是原理很简单?明白了测试原理,我们就可以动手来做了。

       下面一网线测试为例,讲解如何设计制作这类治具。先设计制作一个网线测试仪。如果要在制程中使用,不但要测试网线的好坏,还要测出问题出在哪里,为制程改善提供依据。搞这个东西需软硬兼施,即既要设计硬件系统,又要做软件编程。还需要设计机箱与等,这不是这里需要讨论的范畴,就不做说明。

   一  硬件设计  这是一个简单的测试治具,其硬件部分很简单,如下图示:

查询带schema_51单片机

 采用4节1.5V电池串联供电,主供电电路上串接了一只1N4001二极管。二极管有两个作用:降压与防电源极性弄反损坏元件。电源开关采用2位拨动开关,电源指示用LED。网线插座可采用两只648 8P8C,或带线RJ45 如下图:

查询带schema_51单片机_02

 按原理图分别与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。

水晶头的线号如下图:

查询带schema_单片机_03

        我们做的测试治具,必须两种接法的线读必须能测。上面原理图中设计两个按钮开关,一个做模式选择,一个做选择确认。原理图中设计有蜂鸣器驱动电路,用蜂鸣器声做按键音。另外有两个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上,点击鼠标右键。

查询带schema_51单片机_04

在弹出菜单点击Add Existing Files to Group‘Lib’

查询带schema_查询带schema_05

选中delay.c,mtype.c,stcio.c,lcd.c

查询带schema_查询带schema_06

 点击右下角的Add按钮,再点击Close关闭对话框,回到编程界面。

查询带schema_查询带schema_07

点击Lib前的+,展开可看到delay.c,mtype.c,stcio.c,lcd.c已加入,如下:

查询带schema_c语言_08

这里先说下如何改Proj名及设置生成的编译文件名。 可以看到Proj名为C51 Template

查询带schema_单片机_09

 如何将Proj名改为Network Cable Test呢?退出Keil,直接将Proj文件夹下的 C51 Template.uvproj重命名为Network Cable Test.uvproj。

查询带schema_Test_10

再启动Keil,打开Network Cable Test.uvproj,Proj名就改过来了,如下:

查询带schema_Test_11

点击Options for Target

查询带schema_Test_12

在弹出对话框中,点击Output按钮

查询带schema_c语言_13

将Name ofExecute 后面输入框中的C51 Template 改为Network Cable Tester

查询带schema_查询带schema_14

编译程序,得到如下结果:

查询带schema_c语言_15

可以看出生成的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函数中加入 初始化代码,如下:

查询带schema_单片机_16

 在main函数中添加响应按键代码,如下:

查询带schema_单片机_17

 到此,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,对应关系如下:

查询带schema_查询带schema_18

代码中需处理线的交叉 , 完成后的代码如下:

//********************************************
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()

程序编译结果如下:

查询带schema_查询带schema_19

到这里所有软硬件设计,就完成了。该程序的代码已上传到文件名为Network Cable Tester Code.rar。如需查看可搜索下载。