找回密码
 立即注册
查看: 1651|回复: 23

电子元件测试仪制作,STC8H1K16+OLED+6只电阻,AVR-Transistortester移植改造版

[复制链接]

该用户从未签到

4

主题

1

回帖

382

积分

等待验证会员

积分
382
发表于 2024-3-21 09:58:51 | 显示全部楼层 |阅读模式
根据荣誉版主 AutoCopyPC 提供的开源的:
《德国开源项目:A_TransistorTester晶体管测试仪的中文注释C源码》


网友经过几个星期天的努力,改为STC8H1K16芯片,
对电路进行了简化,经简单测试效果良好,
精度未仔细调整,现公布改造和移植的原码开源给大家一起制造白菜价测试仪。


注意通过STC-ISP烧录时,时钟源选择内部,频率为8MHz,
设置其他频率烧录后,屏幕只会在启动的时候显示闪烁一下就会一直黑屏,
需要设置为8MHz才能正常显示。

超简单电路,看程序和图片即可正确连接电路。
单片机型号: STC8H1K16,制作出来的实物图如下:

0.jpg

104630tma89m02m1n9wmtx.jpg

部分测试结果如下:
104725r8moz6rmocacm84z.jpg

104742cd944phjmmyk54mc.jpg

104923pzgugagksc6gug5u.jpg

104713q3gso7aldbea3lis.jpg

104853cttqzkyyh2vu02tu.jpg

电路图:
104415qxwrqgrxthxrz5hn.jpg

原理图:
112850i3lwgrhwx3bzg82w.png


单片机部分源程序如下:

  • //neu2010.01.02版Mega8基础版(起源于约2009年。需配合Markus F.电路图,
  • //中文注释翻译:itkw: autopccopy @ guangzhou 2022.04.22 AVR单片机价格昂贵,强烈建议移植到STC单片机)
  • //程序移植:rz123456,非常喜欢STC,功能强大、使用方便、价格便宜。
  • //删除了一部分不需要的,原程序中AVR的硬件程序。OLED程序为厂家提供。
  • //本AVR例程不支持小容量芯片,需Mega8或Mega328起。使用WinAVR-20100110 编译, PROGISP 1.72+USBIAP工具下载
  • #include <STC8G.h>
  • #include <stdlib.h>
  • #include <string.h>
  • #include "oled.h"
  • #include <math.h>
  • #define  uint8_t unsigned char
  • #define  uint16_t unsigned int
  • #define  uint32_t unsigned long int
  • #define  int16_t  signed int
  • //三组测试电阻的阻值:R_L为680欧,R_H为470K
  • //如要修改,请输入以欧姆为单位的电阻值定义(特别注意:此三组电阻须配对为阻值相近,否则误差较大)
  • //#define R_L_VAL                680              //R_L; 标准值 680欧
  • //#define R_H_VAL                470000UL         //R_H; 标准值 470K
  • #define R_L_VAL                510              //510欧
  • #define R_H_VAL                510000UL         //510K
  • //在程序中计算必要的电阻值
  • #define RH_RL_RATIO            (R_H_VAL/R_L_VAL)//高低电阻比
  • #define R_H_PER                (R_H_VAL/100)    //高电阻/100的值
  • //注意:N和P沟道增强型E-MOSFET栅极电容计算系数:取决于AVR的制造公差,在必要时进行调整
  • //(注:其他改进型有插入基准元件进行自动校准功能)
  • //#define N_GATE_CAPACITY_FACTOR 387              //N沟道系数
  • //#define P_GATE_CAPACITY_FACTOR 142              //P沟道系数
  • #define N_GATE_CAPACITY_FACTOR 18              //N沟道系数
  • #define P_GATE_CAPACITY_FACTOR 18
  • //电容器的电容计算系数:取决于 AVR 的制造公差,在必要时进行调整
  • //总测量范围约为 0.2nF 至 1000uF。
  • //#define Hr_LowCAPACITY_FACTOR  94               //使用 470k 高电阻测量(小电容)系数
  • #define Hr_LowCAPACITY_FACTOR  21
  • //#define Lr_HighCAPACITY_FACTOR 283              //使用 680  低电阻测量(高电容)系数
  • #define Lr_HighCAPACITY_FACTOR 18
  • void ADC_Init();
  • void CheckPins(uint8_t HighPin, uint8_t LowPin, uint8_t TriPin);
  • void ReadCapacity(uint8_t HighPin, uint8_t LowPin);
  • void DischargePin(uint8_t PinToDischarge, uint8_t DischargeDirection);
  • uint16_t ReadADC(u8 addr);                  //ADC读取
  • void GetGateThresholdVoltage(void);             //取栅极开启阈值电压
  • void _delay_ms(unsigned int ms);
  • //端口C: PC0-PC2为测试脚TP1-TP3为,同时PB0-PB5分别连接680、470K三组测试电阻
  • //请不要更改 TP1、TP2和TP3 的定义!
  • //端口B: PB0-PB5分别连接680、470K连续三组测试电阻
  • //#define R_DDR             DDRB     //数据方向寄存器,    1:输出/0:输入
  • //#define R_PORT            PORTB    //6个测试电阻接PORTB,1:上拉电阻使能
  • //
  • ////以下注释为方便理解本程序:
  • ////DDRxn控制引脚方向:当DDRxn为1时,Pxn为输出;当DDRxn为0时,Pxn为输入。
  • ////PORTxn在PCn为输入时,1为上拉电阻至VCC;否则引脚悬空。PCn为输出时,1为输出高电平;否则输出低电平。
  • ////PINxn的值为Pxn引脚的电平。不论如何配置DDxn,都可以通过读取PINxn来获得引脚电平。如果给PINxn写入1,PORTxn的值会翻转。
  • //
  • //#define ADC_DDR           DDRC     //数据方向寄存器: 1:输出/0:输入
  • //#define ADC_PORT          PORTC    //数据寄存器    : 1: 输入:上拉电阻使能 或 输出:高电平
  • //#define ADC_PIN           PINC     //引脚寄存器    : 输出时引脚的实际值
  • //#define TP1               PC0      //0
  • //#define TP2               PC1      //1
  • //#define TP3               PC2      //2
  • #define     R_DDR       P2M0 // 这个还要加  P2M1= ~P2M0;
  • #define     R_PORT      P2
  • #define     ADC_DDR     P1M0 //这个 入=0  出=1   还要加P1M1 = ~P1M0; //设置 P1.0~P1.7 为双向口模式
  • #define     ADC_PORT    P1 //设置
  • #define     ADC_PIN     P1
  • u8   TP1=0;
  • u8   TP2=1;
  • u8   TP3=2;
  • sbit        RST_PIN=P0^1;        //测试按钮,按下为低电平
  • //元件属性码(与返回码PartFound匹配)
  • #define PART_NONE         0        //无或故障
  • #define PART_DIODE        1        //二极管
  • #define PART_TRANSISTOR   2        //三极管
  • #define PART_FET          3        //FET
  • #define PART_TRIAC        4        //单向可控硅
  • #define PART_THYRISTOR    5        //双向可控硅
  • #define PART_RESISTOR     6        //电阻
  • #define PART_CAPACITOR    7        //电容
  • //三极管子类型码
  • #define PART_MODE_NPN     1        //NPN三极管
  • #define PART_MODE_PNP     2        //PNP三极管
  • //场效应管子类型码(与PartMode返回码匹配。大属性码PartFound为PART_FET: 3)
  • #define PART_MODE_N_E_MOS 1        //N沟道增强型E-MOSFET
  • #define PART_MODE_P_E_MOS 2        //P沟道增强型E-MOSFET
  • #define PART_MODE_N_D_MOS 3        //N沟道耗尽型D-MOSFET
  • #define PART_MODE_P_D_MOS 4        //P沟道耗尽型D-MOSFET
  • #define PART_MODE_N_JFET  5        //N沟道JFET
  • #define PART_MODE_P_JFET  6        //P沟道JFET
  • //二极管结构体
  • struct Diode                       //声明有3个成员的结构体,标签被命名为Diode(结构体将不同的数据类型整合为一个有机整体,方便数据管理,增加代码的可读性)
  • {
  •   uint8_t Anode;                   //阳极引脚序号
  •   uint8_t Cathode;                 //阴极
  •   int16_t Voltage;                 //二极管导通电压降
  • };
  • struct Diode diodes[6];            //用Diode标签的结构体,另外声明了变量diodes数组
  • uint8_t   NumOfDiodes;             //存在的二极管个数
  • uint8_t   b,c,e;                   //b,c,e引脚序号,配合显示引脚号(取值0-2)
  • //三极管的测量
  • uint8_t   PartReady;               //测量的轮次数
  • uint8_t   PartFound, tmpPartFound; //返回的元件属性码
  • uint8_t   PartMode;                //返回的元件子类型码
  • uint32_t  u32_hfe;                 //u32值,用于直流放大系数、电阻值等
  • uint16_t  ADCval[2];               //ADC测量值
  • uint16_t  ADCuBE[2];               //ADC测量: 基极-发射极BE
  • //电阻和电容测量
  • uint8_t   ra, rb;                  //电阻引脚序号,配合显示引脚号(取值0-2)
  • uint16_t  rv[2];                   //电阻两端的电压降
  • uint16_t  rADCmax[2];              //可实现的最大ADC值(小于1023,因为测量电阻时LowPin上的电压高于零)
  • uint8_t   ca, cb;                  //电容引脚序号,配合显示引脚号(取值0-2)
  • uint32_t  cv;                      //电容容量值
  • uint8_t   tmpVAL, tmpVAL2;         //2个通用u8临时变量
  • uint16_t  ADCv[4];                 //ADC的测量值
  • char      chrVAL[8];               //字符串1
  • char      chrVAL2[6];              //字符串2
  • uint32_t  chrVAL2_cv;
  • uint32_t  chrVAL_cv;
  • uint8_t   itkw_tmp1;               //仅用于对调引脚序号的临时变量
  • //============================主程序开始============================
  • int main(void)
  • {
  • P0M0 = 0x08; //设置 P0.0~P0.7 为双向口模式
  • P0M1 = 0x00;
  • P3M0 = 0xC0; //设置 P3.0~P3.7 为双向口模式 C0=P3.6/7输出oled电源
  • P3M1 = 0x00;
  • P0PU = 0x02; //上拉电阻P0.1
  • P0=0X02;         //测试按钮
  • P3=0X40;  //P3.5  OLED+电源
  •         OLED_Init();//初始化OLED
  •     OLED_ColorTurn(0);//0正常显示,1 反色显示
  •     OLED_DisplayTurn(1);//0正常显示 1 屏幕翻转显示
  •    ADC_Init();
  • //EA = 1;     //允许全局中断
  •   //运行期间再次按下启动按钮时的入口点,复位变量后开始
  •   start:
  • //  wdt_enable(WDTO_2S);             //看门狗开启
  •   PartFound    = PART_NONE;        //返回属性码为0
  •   tmpPartFound = PART_NONE;        //返回属性码为0
  •   NumOfDiodes  = 0;                //二极管数量
  •   PartReady    = 0;                //测量的轮次数
  •   PartMode     = 0;                //返回子类型码
  •   ca           = 0;                //电容引脚序号a
  •   cb           = 0;                //电容引脚序舃
  • //  lcd_clear(); //清屏
  •   OLED_Clear();
  •   //开始测试
  • //  lcd_eep_string(Testrunning);     //显示:Testrunning..
  •   OLED_ShowString(0,0,"Testrunning...",16);
  •   OLED_ShowChinese(0,2,3,16);//测试中
  •         OLED_ShowChinese(16,2,4,16);//
  •         OLED_ShowChinese(32,2,5,16);//
  •         OLED_ShowString(48,2,"......",16);
  •   //测量3个引脚的所有6种组合
  •   CheckPins(TP1, TP2, TP3);        //PC0,PC1,PC2
  •   CheckPins(TP1, TP3, TP2);
  •   CheckPins(TP2, TP1, TP3);
  •   CheckPins(TP2, TP3, TP1);
  •   CheckPins(TP3, TP1, TP2);
  •   CheckPins(TP3, TP2, TP1);
  •   //若属性码为空或电阻或二极管,则再单独测量电容器(需先放电,否则可能无法测量)
  •   if((PartFound == PART_NONE) || (PartFound == PART_RESISTOR) || (PartFound == PART_DIODE))
  •   {
  •     R_PORT = 0;
  •     R_DDR = (1<<(TP1*2)) | (1<<(TP2*2)) | (1<<(TP3*2));  //电阻引脚R_H为输出模式接地
  •     P2M1 = ~P2M0;
  •         _delay_ms(50);
  •     R_DDR = 0; //电阻引脚为输入模式
  •         P2M1 = ~P2M0;
  •     //测量所有6个引脚组合中的电容器
  •     ReadCapacity(TP1, TP2);
  •     ReadCapacity(TP1, TP3);
  •     ReadCapacity(TP2, TP1);
  •     ReadCapacity(TP2, TP3);
  •     ReadCapacity(TP3, TP1);
  •     ReadCapacity(TP3, TP2);
  •   }
  •   GetGateThresholdVoltage();       //取栅极开启阈值电压
  • //  lcd_clear();
  •   OLED_Clear();
  •   //测量完成,现在评估如下
  •   if(PartFound == PART_DIODE)//***二极管
  •   {
  •     if(NumOfDiodes == 1)
  •     {
  •       //标准二极管
  •      // lcd_eep_string(Diode);
  •                 OLED_ShowChinese(0,0,16,16);//
  •                 OLED_ShowChinese(16,0,18,16);//
  •                 OLED_ShowChinese(32,0,19,16);//
  •         OLED_ShowString(50,0,"Diode",16);
  •      // lcd_eep_string(AK);          //"A,K="
  •         OLED_ShowString(0,2,"A,K=",16);
  •       //lcd_data(diodes[0].Anode   + 49);
  •         OLED_ShowChar(40,2,(diodes[0].Anode   + 49),16);
  •                OLED_ShowChinese(48,2,8,16);//二极管
  •           //lcd_data(diodes[0].Cathode + 49);
  •         OLED_ShowChar(64,2,(diodes[0].Cathode   + 49),16);
  •      // Line2();
  •       //lcd_eep_string(Uf);          //“Uf =”
  •         OLED_ShowString(0,4,"Uf =",16);
  •       //lcd_string(itoa(diodes[0].Voltage, chrVAL, 10)); //显示二极管导通电压降
  •         OLED_ShowNum(40,4,(diodes[0].Voltage),4, 16);
  •       //lcd_eep_string(mV);
  •          OLED_ShowString(72,4,"mV",16);
  •       goto end;
  •     }
  •     else if(NumOfDiodes == 2)
  •     {
  •       //双二极管
  •       if(diodes[0].Anode == diodes[1].Anode)
  •       {
  •         //lcd_eep_string(DualDiode); //共阳极双二极管
  •          OLED_ShowChinese(0,0,20,16);//
  •                 OLED_ShowChinese(16,0,16,16);//
  •                 OLED_ShowChinese(32,0,18,16);//
  •                 OLED_ShowChinese(48,0,19,16);//
  •                 //OLED_ShowString(0,0,"DualDiode",16);
  •         //lcd_string("CA");
  •         OLED_ShowString(72,0,"CA",16);
  •         //Line2();
  •         //lcd_eep_string(AK1K2);//阳极,阴极1,阴极2=
  •         OLED_ShowString(0,2,"AK1K2",16);
  •         //lcd_data(diodes[0].Anode   + 49);
  •         OLED_ShowChar(88,2,(diodes[0].Anode   + 49),16);
  •         //lcd_data(diodes[0].Cathode + 49);
  •         OLED_ShowChar(98,2,(diodes[0].Cathode   + 49),16);
  •         //lcd_data(diodes[1].Cathode + 49);
  •         OLED_ShowChar(108,2,(diodes[1].Cathode   + 49),16);
  •                 OLED_ShowChar(40,4,(diodes[0].Anode   + 49),16);
  •                 OLED_ShowChinese(48,4,8,16);//二极管
  •                 OLED_ShowChar(64,4,(diodes[0].Cathode   + 49),16);
  •                 OLED_ShowChar(40,6,(diodes[0].Anode   + 49),16);
  •                 OLED_ShowChinese(48,6,8,16);//二极管
  •                 OLED_ShowChar(64,6,(diodes[1].Cathode   + 49),16);
  •         goto end;
  •       }
  •       else if(diodes[0].Cathode == diodes[1].Cathode)
  •       {
  •         //lcd_eep_string(DualDiode); //共阴极双二极管
  •         OLED_ShowChinese(0,0,20,16);//
  •                 OLED_ShowChinese(16,0,16,16);//
  •                 OLED_ShowChinese(32,0,18,16);//
  •                 OLED_ShowChinese(48,0,19,16);//
  •         //lcd_string("CC");
  •         OLED_ShowString(72,0,"CC",16);
  •         //Line2();
  •         //lcd_string("K,A1,A2=");
  •         OLED_ShowString(0,2,"K,A1,A2=",16);
  •         //lcd_data(diodes[0].Cathode + 49);
  •         OLED_ShowChar(88,2,(diodes[0].Cathode   + 49),16);
  •         //lcd_data(diodes[0].Anode   + 49);
  •         OLED_ShowChar(98,2,(diodes[0].Anode   + 49),16);
  •         //lcd_data(diodes[1].Anode   + 49);
  •         OLED_ShowChar(108,2,(diodes[1].Anode   + 49),16);
  •         goto end;
  •       }
  •       else if ((diodes[0].Cathode == diodes[1].Anode) && (diodes[1].Cathode == diodes[0].Anode))
  •       {
  •         //lcd_eep_string(TwoDiodes); //反向并联2个二极管。(注:此处原程序没有显示引脚序号)
  •         OLED_ShowString(0,0,"TwoDiodes",16);
  •         //Line2();
  •         //lcd_eep_string(Antiparallel);
  •         OLED_ShowString(0,2,"Antiparallel",16);
  •                 OLED_ShowChar(0,4,'2',16);
  •                 OLED_ShowChinese(8,4,10,16);//        2个二极管
  •                 OLED_ShowChinese(26,4,16,16);//
  •                 OLED_ShowChinese(42,4,18,16);//
  •                 OLED_ShowChinese(58,4,19,16);//
  •         goto end;
  •       }
  •     }
  •     else if(NumOfDiodes == 3)           //2个二极管串联;将被认为是3个二极管
  •     {
  •       b = 3;
  •       c = 3;
  •       //为此,必须有2个阴极和2个阳极匹配。
  •       //这是因为这些二极管被认为是2个独立的二极管,并且也被认为是一个“大”二极管。
  •       if((diodes[0].Anode   == diodes[1].Anode)   || (diodes[0].Anode   == diodes[2].Anode))   b = diodes[0].Anode;
  •       if(diodes[1].Anode    == diodes[2].Anode)                                                b = diodes[1].Anode;
  •       if((diodes[0].Cathode == diodes[1].Cathode) || (diodes[0].Cathode == diodes[2].Cathode)) c = diodes[0].Cathode;
  •       if(diodes[1].Cathode  == diodes[2].Cathode)                                              c = diodes[1].Cathode;
  •       if((b<3) && (c<3))
  •       {
  •         //lcd_eep_string(TwoDiodes); //2个串联二极管
  •         OLED_ShowString(0,0,"TwoDiodes",16);
  •         //Line2();
  •         //lcd_eep_string(sAK);       //串联阳极及阴极=
  •         OLED_ShowString(0,2,"sAK",16);
  •         //lcd_data(b + 49);
  •         OLED_ShowChar(30,2,(b + 49),16);
  •         //lcd_data(c + 49);
  •         OLED_ShowChar(40,2,(c + 49),16);
  •                 OLED_ShowChar(0,4,'2',16);
  •                 OLED_ShowChinese(8,4,10,16);//        2个二极管
  •                 OLED_ShowChinese(26,4,16,16);//
  •                 OLED_ShowChinese(42,4,18,16);//
  •                 OLED_ShowChinese(58,4,19,16);//
  •         goto end;
  •       }
  •     }
  •   }
  •   else if (PartFound == PART_TRANSISTOR)  //***三极管
  •   {
  •     if(PartReady == 0)             //如果未进行过第二次测试(例如在带有保护二极管的三极管的情况下)
  •     {
  •       ADCval[1] = ADCval[0];
  •       ADCuBE[1] = ADCuBE[0];
  •     }
  •     if((ADCval[0]>ADCval[1]))            //如果在第一次测试期间放大系数较高,则更新数据,并对调c和e极。
  •     {
  •       ADCval[1] = ADCval[0];
  •       ADCuBE[1] = ADCuBE[0];
  •       itkw_tmp1 = c;
  •       c         = e;
  •       e         = itkw_tmp1;
  •     }
  •                  OLED_ShowChinese(26,0,17,16);//三极管
  •                 OLED_ShowChinese(42,0,18,16);//
  •                 OLED_ShowChinese(58,0,19,16);//
  •     if(PartMode == PART_MODE_NPN)  //显示NPN或PNP类型
  •     {
  •       //lcd_eep_string(NPN);
  •       OLED_ShowString(0,2,"NPN",16);
  •           OLED_ShowChinese(74,2,22,16);//<
  •     }
  •     else
  •     {
  •       //lcd_eep_string(PNP);
  •       OLED_ShowString(0,2,"PNP",16);
  •          OLED_ShowChinese(74,2,21,16);//>
  •     }
  •     //lcd_eep_string(BCE);           //BCE=
  •     OLED_ShowString(50,2,"BCE",16);
  •     //lcd_data(b + 49);              //依次显示引脚序号(ascii 49 是字符"1", b,c,e取值范围:0-2)
  •     OLED_ShowChar(90,2,(b + 49),16);
  •     //lcd_data(c + 49);
  •     OLED_ShowChar(98,2,(c + 49),16);
  •     //lcd_data(e + 49);
  •     OLED_ShowChar(106,2,(e + 49),16);
  •     //Line2();
  •     //计算 直流放大系数 hFE = 发射极电流/基极电流
  •     u32_hfe   = ADCval[1];
  •     u32_hfe  *= RH_RL_RATIO;          //高低电阻比
  •     if(ADCuBE[1] < 11) ADCuBE[1] = 11;
  •     u32_hfe  /= ADCuBE[1];
  •     ADCval[1] = (uint16_t)u32_hfe;
  •     //lcd_eep_string(hfeSTR);        //“hFE=”
  •     OLED_ShowString(0,4,"hFE=",16);
  •     //lcd_string(utoa(ADCval[1], chrVAL, 10));
  •    OLED_ShowNum(32,4,(ADCval[1]),4, 16);
  • //    SetCursor(2,7);                //光标在第2行,字符7
  •     if(NumOfDiodes > 2)            //带保护二极管的三极管
  •     {
  •       //lcd_data(LCD_CHAR_DIODE);    //显示二极管符号
  •       OLED_ShowChinese(64,0,8,16);//
  •     }
  •     else
  •     {
  •       //lcd_data(' ');
  •       OLED_ShowString(64,4,"  ",16);
  •     }
  •     for (c=0;c<NumOfDiodes;c++)
  •     {
  •       if(((diodes[c].Cathode == e) && (diodes[c].Anode   == b) && (PartMode == PART_MODE_NPN))   ||   ((diodes[c].Anode   == e) && (diodes[c].Cathode == b) && (PartMode == PART_MODE_PNP)))
  •       {
  •         //lcd_eep_string(Uf);        //“Uf=”
  •         OLED_ShowString(8,6,"Uf=",16);
  •         //lcd_string(itoa(diodes[c].Voltage, chrVAL, 10));
  •         OLED_ShowNum(32,6,(diodes[c].Voltage),4, 16);
  •         //lcd_data('m');             //应是mV的意思..
  •          OLED_ShowString(64,6,"mV",16);
  •         goto end;
  •       }
  •     }
  •     goto end;
  •   }
  •   else if (PartFound == PART_FET)       //JFET 或 MOSFET
  •   {
  •     if(PartMode&1)                 //判断子类型码为单数是N型,否则为P型(...)
  •     {
  •       //lcd_data('N');               //N型
  •       OLED_ShowString(0,0,"N",16);
  •     }
  •     else
  •     {
  •       //lcd_data('P');               //P型
  •       OLED_ShowString(0,0,"P",16);
  •     }
  •   //if((PartMode==PART_MODE_N_E_MOS) || (PART_MODE_P_E_MOS))
  •     if(PartMode < 3)                                                    //E-MOSFET:1、2(与下面对应)
  •     {
  •       //lcd_eep_string(emode);       //“-E”
  •       OLED_ShowString(8,0,"-E",16);
  •       //lcd_eep_string(mosfet);      //“-MOS”
  •       OLED_ShowString(24,0,"-MOS",16);
  •     }
  •     else if((PartMode==PART_MODE_N_D_MOS) || (PartMode==PART_MODE_P_D_MOS))  //耗尽型D-MOSFET:3、4
  •     {
  •       //lcd_eep_string(dmode);       //“-D”
  •       OLED_ShowString(8,0,"-D",16);
  •       //lcd_eep_string(mosfet);      //“-MOS”
  •       OLED_ShowString(24,0,"-MOS",16);
  •     }
  •     else                                                                //JFET:5、6
  •     {
  • //      lcd_eep_string(jfet);        //“-JFET”
  •        OLED_ShowString(24,0,"-JFET",16);
  •     }
  •     //增强型E-MOSFET 则测量 栅极电容
  •     if(PartMode < 3)               //E-MOSFET:1、2
  •     {
  • //      lcd_eep_string(GateCap);     //“C=”
  •       OLED_ShowString(50,4,"C=",16);
  •       //tmpVAL = strlen(chrVAL2);//chrVAL2_cv
  •       //tmpVAL2 = tmpVAL;
  • //      if(tmpVAL>4) tmpVAL = 4;     //对于 >100nF 的电容,不要指定最后一个小数位(否则它不适合 LCD)(显示4位长度)
  •       //lcd_show_format_cap(chrVAL2, tmpVAL, tmpVAL2);
  •                         OLED_ShowNum(66,4,chrVAL2_cv,4, 16);
  •       //lcd_data('n');
  •       OLED_ShowString(116,4,"p",16);
  •     }
  •     //Line2();
  •     //lcd_eep_string(gds);           //“GDS=” (注:此处与三极管的三个极分别显示的方式不同)
  •     OLED_ShowString(0,2,"GDS=",16);
  •     //lcd_data(b + 49);
  •     OLED_ShowChar(38,2,(b + 49),16);
  •     //lcd_data(c + 49);
  •     OLED_ShowChar(46,2,(c + 49),16);
  •     //lcd_data(e + 49);
  •     OLED_ShowChar(54,2,(e + 49),16);
  •     if((PartMode < 3) && (NumOfDiodes > 0)) //增强型E-MOSFET及带保护二极管的
  •     {
  •       //lcd_data(LCD_CHAR_DIODE);    //显示二极管符号
  •       OLED_ShowString(0,4,"DIODE",16);
  •     }
  •     else
  •     {
  •       //lcd_data(' ');               //空格
  •       OLED_ShowString(0,4,"  ",16);
  •     }
  •     if(PartMode < 3)               //增强型E-MOSFET
  •     {
  •       //lcd_eep_string(vt);          //Vt=
  •       OLED_ShowString(0,6,"Vt=",16);
  •       //lcd_string(chrVAL);          //显示栅极阈值电压
  •       OLED_ShowNum(24,6,chrVAL_cv,4, 16);
  •       //lcd_data('m');
  •       OLED_ShowString(100,6,"mV",16);
  •     }
  •     goto end;
  •   }
  •   else if (PartFound == PART_THYRISTOR) //单向可控硅
  •   {
  • //    lcd_eep_string(Thyristor);
  •         OLED_ShowString(0,0,"Thyristor",16);
  • //    Line2();
  • //    lcd_string("GAK=");
  •         OLED_ShowString(0,2,"GAK=",16);
  • //    lcd_data(b + 49);
  •         OLED_ShowChar(30,2,(b + 49),16);
  • //    lcd_data(c + 49);
  •         OLED_ShowChar(38,2,(c + 49),16);
  • //    lcd_data(e + 49);
  •         OLED_ShowChar(46,2,(e + 49),16);
  •     goto end;
  •   }
  •   else if (PartFound == PART_TRIAC)     //三端双向可控硅
  •   {
  •     //lcd_eep_string(Triac);
  •         OLED_ShowString(50,0,"Triac",16);
  •     //Line2();
  •     //lcd_eep_string(GA1A2);         //注:已改为统一显示
  •         OLED_ShowString(0,2,"G A1 A2",16);
  • //   lcd_data(b + 49);
  •         OLED_ShowChar(0,4,(b + 49),16);
  • //    lcd_data(e + 49);
  •         OLED_ShowChar(16,4,(e + 49),16);
  • //    lcd_data(c + 49);
  •         OLED_ShowChar(40,4,(c + 49),16);
  •     goto end;
  •   }
  •   else if(PartFound == PART_RESISTOR)   //电阻
  •   {
  • //    lcd_eep_string(Resistor);      //显示:Resistor
  •         OLED_ShowChinese(0,0,0,16);//电
  •         OLED_ShowChinese(16,0,1,16);//阻
  •         OLED_ShowString(40,0,"Resistor",16);
  • //    lcd_data(ra + 49);             //显示引脚序号
  •         OLED_ShowChar(30,2,(ra + 49),16);
  • //    lcd_data('-');
  •         //OLED_ShowChar(46,2,('-'),16);
  •         OLED_ShowChinese(38,2,6,16);//电zhu
  • //    lcd_data(rb + 49);
  •         OLED_ShowChar(54,2,(rb + 49),16);
  • //    Line2();
  • //    lcd_string ("R = ");
  •         OLED_ShowString(30,4,"R =",16);
  •     if(rv[0]>512)                  //检查测试电阻两端的电压与中值512相差有多远
  •     {
  •       ADCval[0] = (rv[0]-512);
  •     }
  •     else
  •     {
  •       ADCval[0] = (512-rv[0]);
  •     }
  •     if(rv[1]>512)
  •     {
  •       ADCval[1] = (rv[1]-512);
  •     }
  •     else
  •     {
  •       ADCval[1] = (512-rv[1]);
  •     }
  •     if(ADCval[0] > ADCval[1])
  •     {
  •       rADCmax[0] = rADCmax[1];
  •       rv[0] = rv[1];               //使用更接近512的结果(准确度更高)
  •       rv[1] = R_H_PER;             //470k电阻(数值除100)
  •     }
  •     else
  •     {
  •       rv[1] = R_L_VAL;             //680R测试电阻
  •     }
  •     if(rv[0]==0) rv[0] = 1;
  •    u32_hfe = (uint32_t)((uint32_t)((uint32_t)rv[1]*(uint32_t)rv[0]) / (uint32_t)((uint32_t)rADCmax[0]-(uint32_t)rv[0]));
  • //计算电阻
  •           if(rv[1]==R_H_PER)             //470k电阻
  •     {
  •            OLED_ShowNum(54,4,u32_hfe/10,5, 16);
  •           OLED_ShowChar(102,4,('K'),16);
  •          }
  •          else
  •          {
  •           OLED_ShowNum(54,4,u32_hfe,5, 16);
  •           OLED_ShowChinese(102,4,7,16);////显示Ω
  •           //OLED_ShowChar(102,4,32+95,16);//显示Ω
  •          }
  • //    ultoa(u32_hfe,chrVAL,10);      //转换一个无符号长整型数为字符串,10进制
  • //    if(rv[1]==R_H_PER)             //470k电阻
  • //    {
  • //      ra = strlen(chrVAL);         //ra字符串长度,必须显示逗号
  • //      for (rb=0;rb<ra;rb++)
  • //      {
  • //        lcd_data(chrVAL[rb]);
  • //        if(rb==(ra-2)) lcd_data('.');  //逗号
  • //      }
  • //      lcd_data ('k');              //如果使用470k 电阻,则显示单位为千欧
  • //    }
  • //    else
  • //    {
  • //      lcd_string(chrVAL);
  • //    }
  • //    lcd_data(LCD_CHAR_OMEGA);      //显示欧米茄符号代表欧姆
  •     goto end;
  •   }
  •   else
  •   if(PartFound == PART_CAPACITOR)  //电容
  •   {
  • //    lcd_eep_string(Capacitor);     //显示Capacitor
  •         OLED_ShowChinese(0,0,0,16);//电
  •         OLED_ShowChinese(16,0,2,16);//容
  •         OLED_ShowString(40,0,"Capacitor",16);
  • //    lcd_data(ca + 49);             //显示引脚序号
  •         OLED_ShowChar(0,2,(ca + 49),16);
  • //    lcd_data('-');
  •         OLED_ShowChar(16,2,('-'),16);
  • //    lcd_data(cb + 49);
  •         OLED_ShowChar(32,2,(cb + 49),16);
  • //    Line2();
  •     tmpVAL2 = 'n';
  • //    if(cv > 99999)                 //到达1uF则改为微法显示:u。
  • //    {
  • //      cv /= 1000;
  • //      tmpVAL2 = LCD_CHAR_U;
  • //    }
  •                 OLED_ShowNum(0,4,cv,9, 16);
  •                 OLED_ShowString(108,4,"pF",16);
  •                 OLED_ShowNum(0,6,cv/1000,6, 16);
  •                 OLED_ShowString(48,6,"nF",16);
  •                 OLED_ShowNum(64,6,cv/1000000,4, 16);
  •                 OLED_ShowString(108,6,"uF",16);
  • //    ultoa(cv, chrVAL, 10);
  • //    tmpVAL = strlen(chrVAL);
  • //    lcd_show_format_cap(chrVAL, tmpVAL, tmpVAL);
  • //    lcd_data(tmpVAL2); //显示: n或u
  • //    lcd_data('F');
  •     goto end;
  •   }
  •   if(NumOfDiodes == 0)             //未找到二极管
  •   {
  •                 OLED_ShowChinese(0,2,9,16);//
  •                 OLED_ShowChinese(16,2,10,16);//
  •                 OLED_ShowChinese(32,2,11,16);//
  •                 OLED_ShowChinese(48,2,12,16);//
  •                 OLED_ShowChinese(64,2,13,16);//
  •                 OLED_ShowChinese(80,2,14,16);//
  •                 OLED_ShowChinese(96,2,14,16);//
  •                 OLED_ShowChinese(112,2,14,16);//
  •                 OLED_ShowChinese(48,4,8,16);//
  •                 OLED_ShowChinese(32,4,6,16);//
  •                 OLED_ShowChinese(16,4,15,16);//
  •   }
  •   else
  •   {
  •                 OLED_ShowChinese(0,2,9,16);//
  •                 OLED_ShowChinese(16,2,10,16);//
  •                 OLED_ShowChinese(32,2,11,16);//
  •                 OLED_ShowChinese(48,2,12,16);//
  •                 OLED_ShowChinese(64,2,13,16);//
  •                 OLED_ShowChinese(80,2,14,16);//
  •                 OLED_ShowChinese(96,2,14,16);//
  •                 OLED_ShowChinese(112,2,14,16);//
  •         OLED_ShowChar(0,6,NumOfDiodes + 48,16);
  • //    lcd_data(LCD_CHAR_DIODE);      //二极管符号
  •         OLED_ShowChinese(16,6,8,16);//二极管符号
  •   }
  •   end:
  •   while(1) //无限循环(本程序自动关机功能已省略)
  •   {
  •     if(RST_PIN==0)//PD7按钮按下为低电平,跳回到起点并进行新的测试
  •     {
  •       goto start;
  •     }
  •   }
  •   return 0;
  • }
  • void CheckPins(uint8_t HighPin, uint8_t LowPin, uint8_t TriPin)  //调用方式:CheckPins(TP1, TP2, TP3);(共6个组合)PC口
  • {
  •   //用于测试具有指定引脚分配的元件属性
  •   //HighPin:最初设置为高电平的引脚:连接到 Vcc
  •   //LowPin: 最初设置为低电平的引脚: 通过 R_L 连接到 GND
  •   //TriPin: 最初设置为开路的引脚  : 高阻状态(三态脚)
  •   //在测试的过程中,TriPin会进行循环高低电平切换。
  •   //注:以下是否重复定义了变量???
  •   uint16_t ADCv[6];
  •   uint8_t  tmpVAL, tmpVAL2;
  •   u8 i,j;
  • //  wdt_reset();
  •   //LowPin通过 R_L 连接到 GND         1<<8 把1向左移8位
  •   tmpVAL  = (LowPin*2);
  •   R_DDR   = (1<<tmpVAL);
  • //  P2M1 = ~P2M0;
  •   P2M1=~P2M0;
  • //  OLED_ShowNum(0,6,P2M0,4, 16);
  •   R_PORT  = 0;
  • //                  while(!RX1_Cnt);  //等待输入
  • //             Print(0xcc);
  • //             RX1_Cnt=0;      //复位
  •   ADC_DDR = (1<<HighPin);
  •   P1M1 = ~P1M0;
  •   ADC_PORT= (1<<HighPin);  //HighPin连接在 Vcc
  •   _delay_ms(5);
  •   //对于某些 MOSFET,栅极(TriPin)必须先放电
  •   //N通道:
  •   DischargePin(TriPin,0);
  •   //测量LowPin上的电压,元件是否在测试座上锁定?
  •   ADCv[0] = ReadADC(LowPin);
  • //  OLED_ShowNum(60,6,ADCv[0],4, 16);
  • //          while(!RX1_Cnt);  //等待输入
  • //             Print(0xdd);
  • //             RX1_Cnt=0;      //复位
  •   if(ADCv[0] < 20) goto next;
  •   //否则:为 P 通道放电(栅极接正)
  •   DischargePin(TriPin,1);
  •   //再测量LowPin上的电压
  •   ADCv[0] = ReadADC(LowPin);
  •   next:
  •   if(ADCv[0] < 20)                 //如果元件在HighPin和LowPin 之间没有连续性
  •   {
  •     tmpVAL2   = (TriPin*2);
  •     R_DDR    |= (1<<tmpVAL2);      //三态引脚通过 R_L 接地,以测试 pnp
  •     P2M1 = ~P2M0;
  •         _delay_ms(2);
  •     ADCv[0]   = ReadADC(LowPin);   //测量电压
  •     if(ADCv[0] > 700)
  •     {
  •       //元件传导 => pnp 三极管或类似的。
  •       //测量两个方向的增益
  •           R_DDR   = (1<<tmpVAL);       //三态引脚(基极)高阻抗
  •       P2M1 = ~P2M0;
  •           tmpVAL2++;
  •       R_DDR  |= (1<<tmpVAL2);      //三态引脚(基极)通过 R_H 接地
  •       P2M1 = ~P2M0;
  •           _delay_ms(10);
  •       ADCv[0] = ReadADC(LowPin);   //测量LowPin(假定为集电极)的电压。
  •       ADCv[2] = ReadADC(TriPin);   //测量三态引脚(基极)电压
  •       R_DDR   = (1<<tmpVAL);       //三态引脚(基极)高阻抗
  •           P2M1 = ~P2M0;
  •       //三态引脚(基极)高阻抗
  •       //检查测试是否已经运行过
  •       if((PartFound == PART_TRANSISTOR) || (PartFound == PART_FET)) PartReady = 1; //将PartReady置1(第2轮)
  •       ADCval[PartReady] = ADCv[0];         //登记到n轮的结果
  •       ADCuBE[PartReady] = ADCv[2];
  •       if(ADCv[2] > 200)
  •       {
  •         if(PartFound != PART_THYRISTOR)    //若非双向可控硅
  •         {
  •           PartFound = PART_TRANSISTOR;
  •           PartMode  = PART_MODE_PNP;       //则为PNP 三极管(基极被“拉高”)
  •         }
  •       }
  •       else
  •       {
  •         if(PartFound != PART_THYRISTOR)    //若非双向可控硅
  •         {
  •           PartFound = PART_FET;
  •           PartMode  = PART_MODE_P_E_MOS;   //则为P沟道 MOSFET(基极/栅极未“上拉”)
  •         }
  •       }
  •       if(PartFound != PART_THYRISTOR)      //若非双向可控硅
  •       {
  •         b = TriPin;
  •         c = LowPin;
  •         e = HighPin;
  •       }
  •     }
  •     //三态脚TriPin(假定为基数)到正极,以测试 npn
  •     ADC_PORT = 0;                          //LowPin到地
  •     tmpVAL   = (TriPin*2);
  •     tmpVAL2  = (HighPin*2);
  •     R_DDR    = (1<<tmpVAL) | (1<<tmpVAL2); //HighPin和三态引脚输出
  •     P2M1 = ~P2M0;
  •         R_PORT   = (1<<tmpVAL) | (1<<tmpVAL2); //HighPin和三态引脚通过 R_L 到 Vcc
  •     ADC_DDR  = (1<<LowPin);                //LowPin输出




代码: Keil代码.7z (66.69 KB, 下载次数: 89)

104758xbm65nqncznocbyb.jpg

点评

转发帖子请注明转发地址,避免版权纠纷。原帖地址:http://www.51hei.com/bbs/dpj-223589-1.html  发表于 2024-5-13 19:35
回复 送花

使用道具 举报

  • TA的每日心情
    开心
    1 小时前
  • 签到天数: 336 天

    [LV.8]以坛为家I

    22

    主题

    433

    回帖

    1710

    积分

    荣誉版主

    积分
    1710
    发表于 2024-3-21 10:47:28 | 显示全部楼层
    很好很强大!哈哈。
    感谢 我们 STC 51 爱好者的 开源奉献
    回复 支持 1 反对 0 送花

    使用道具 举报

  • TA的每日心情
    开心
    1 小时前
  • 签到天数: 336 天

    [LV.8]以坛为家I

    22

    主题

    433

    回帖

    1710

    积分

    荣誉版主

    积分
    1710
    发表于 2024-3-21 10:51:49 | 显示全部楼层
    AVR单片机运行的代码在 github上有很多,
    移植到STC上面,用keil c51,移植难度较大,
    建议使用 IAR C++ for 8051, 支持新的 C 标准
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 15:49
  • 签到天数: 323 天

    [LV.8]以坛为家I

    9

    主题

    116

    回帖

    1458

    积分

    金牌会员

    积分
    1458
    发表于 2024-3-21 11:00:33 | 显示全部楼层
    是不是要换成12位ADC , 提高一下精度
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    640

    主题

    1万

    回帖

    1万

    积分

    管理员

    积分
    15687
    发表于 2024-3-21 11:13:56 | 显示全部楼层
    主要是要换成带 硬件 USB
    能 硬件USB下载/仿真的 STC8H8K64U
    截图202403211110449821.jpg
    截图202403211112569381.jpg

    截图202403211113231975.jpg


    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    640

    主题

    1万

    回帖

    1万

    积分

    管理员

    积分
    15687
    发表于 2024-3-21 11:14:11 | 显示全部楼层
    截图202403211114083507.jpg
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    640

    主题

    1万

    回帖

    1万

    积分

    管理员

    积分
    15687
    发表于 2024-3-21 11:23:44 | 显示全部楼层
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    23 分钟前
  • 签到天数: 241 天

    [LV.8]以坛为家I

    16

    主题

    2528

    回帖

    3110

    积分

    论坛元老

    积分
    3110
    发表于 2024-3-21 12:52:23 来自手机 | 显示全部楼层
    这个不错啊
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    6 小时前
  • 签到天数: 235 天

    [LV.7]常住居民III

    0

    主题

    324

    回帖

    806

    积分

    高级会员

    积分
    806
    发表于 2024-3-21 16:05:50 | 显示全部楼层
    谢谢分享
    回复 送花

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 09:45
  • 签到天数: 156 天

    [LV.7]常住居民III

    2

    主题

    154

    回帖

    625

    积分

    高级会员

    积分
    625
    发表于 2024-3-27 15:07:55 | 显示全部楼层
    学习了
    回复 送花

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-11-1 07:08 , Processed in 0.140720 second(s), 90 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表