电子元件测试仪制作,STC8H1K16+OLED+6只电阻,AVR-Transistortester移植改造版
根据荣誉版主 AutoCopyPC 提供的开源的:《德国开源项目:A_TransistorTester晶体管测试仪的中文注释C源码》
网友经过几个星期天的努力,改为STC8H1K16芯片,
对电路进行了简化,经简单测试效果良好,
精度未仔细调整,现公布改造和移植的原码开源给大家一起制造白菜价测试仪。
(注意:通过STC-ISP烧录时,时钟源选择内部,频率为8MHz,
设置其他频率烧录后,屏幕只会在启动的时候显示闪烁一下就会一直黑屏,
需要设置为8MHz才能正常显示。)
超简单电路,看程序和图片即可正确连接电路。
单片机型号: STC8H1K16,制作出来的实物图如下:
部分测试结果如下:
电路图:
原理图:
单片机部分源程序如下:
[*]//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>
[*]
[*]#defineuint8_t unsigned char
[*]#defineuint16_t unsigned int
[*]#defineuint32_t unsigned long int
[*]#defineint16_tsigned 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_FACTOR94 //使用 470k 高电阻测量(小电容)系数
[*]#define Hr_LowCAPACITY_FACTOR21
[*]//#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_JFET5 //N沟道JFET
[*]#define PART_MODE_P_JFET6 //P沟道JFET
[*]
[*]//二极管结构体
[*]struct Diode //声明有3个成员的结构体,标签被命名为Diode(结构体将不同的数据类型整合为一个有机整体,方便数据管理,增加代码的可读性)
[*]{
[*]uint8_t Anode; //阳极引脚序号
[*]uint8_t Cathode; //阴极
[*]int16_t Voltage; //二极管导通电压降
[*]};
[*]struct Diode diodes; //用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_tu32_hfe; //u32值,用于直流放大系数、电阻值等
[*]uint16_tADCval; //ADC测量值
[*]uint16_tADCuBE; //ADC测量: 基极-发射极BE
[*]
[*]//电阻和电容测量
[*]uint8_t ra, rb; //电阻引脚序号,配合显示引脚号(取值0-2)
[*]uint16_trv; //电阻两端的电压降
[*]uint16_trADCmax; //可实现的最大ADC值(小于1023,因为测量电阻时LowPin上的电压高于零)
[*]uint8_t ca, cb; //电容引脚序号,配合显示引脚号(取值0-2)
[*]uint32_tcv; //电容容量值
[*]
[*]uint8_t tmpVAL, tmpVAL2; //2个通用u8临时变量
[*]uint16_tADCv; //ADC的测量值
[*]char chrVAL; //字符串1
[*]char chrVAL2; //字符串2
[*]uint32_tchrVAL2_cv;
[*]uint32_tchrVAL_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.5OLED+电源
[*]
[*] 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.Anode + 49);
[*] OLED_ShowChar(40,2,(diodes.Anode + 49),16);
[*] OLED_ShowChinese(48,2,8,16);//二极管
[*] //lcd_data(diodes.Cathode + 49);
[*]
[*] OLED_ShowChar(64,2,(diodes.Cathode + 49),16);
[*] // Line2();
[*] //lcd_eep_string(Uf); //“Uf =”
[*] OLED_ShowString(0,4,"Uf =",16);
[*] //lcd_string(itoa(diodes.Voltage, chrVAL, 10)); //显示二极管导通电压降
[*] OLED_ShowNum(40,4,(diodes.Voltage),4, 16);
[*] //lcd_eep_string(mV);
[*] OLED_ShowString(72,4,"mV",16);
[*] goto end;
[*] }
[*] else if(NumOfDiodes == 2)
[*] {
[*] //双二极管
[*] if(diodes.Anode == diodes.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.Anode + 49);
[*] OLED_ShowChar(88,2,(diodes.Anode + 49),16);
[*] //lcd_data(diodes.Cathode + 49);
[*] OLED_ShowChar(98,2,(diodes.Cathode + 49),16);
[*] //lcd_data(diodes.Cathode + 49);
[*] OLED_ShowChar(108,2,(diodes.Cathode + 49),16);
[*]
[*] OLED_ShowChar(40,4,(diodes.Anode + 49),16);
[*] OLED_ShowChinese(48,4,8,16);//二极管
[*] OLED_ShowChar(64,4,(diodes.Cathode + 49),16);
[*] OLED_ShowChar(40,6,(diodes.Anode + 49),16);
[*] OLED_ShowChinese(48,6,8,16);//二极管
[*] OLED_ShowChar(64,6,(diodes.Cathode + 49),16);
[*] goto end;
[*] }
[*] else if(diodes.Cathode == diodes.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.Cathode + 49);
[*] OLED_ShowChar(88,2,(diodes.Cathode + 49),16);
[*] //lcd_data(diodes.Anode + 49);
[*] OLED_ShowChar(98,2,(diodes.Anode + 49),16);
[*] //lcd_data(diodes.Anode + 49);
[*] OLED_ShowChar(108,2,(diodes.Anode + 49),16);
[*] goto end;
[*] }
[*] else if ((diodes.Cathode == diodes.Anode) && (diodes.Cathode == diodes.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.Anode == diodes.Anode) || (diodes.Anode == diodes.Anode)) b = diodes.Anode;
[*] if(diodes.Anode == diodes.Anode) b = diodes.Anode;
[*] if((diodes.Cathode == diodes.Cathode) || (diodes.Cathode == diodes.Cathode)) c = diodes.Cathode;
[*] if(diodes.Cathode== diodes.Cathode) c = diodes.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 = ADCval;
[*] ADCuBE = ADCuBE;
[*] }
[*]
[*] if((ADCval>ADCval)) //如果在第一次测试期间放大系数较高,则更新数据,并对调c和e极。
[*] {
[*] ADCval = ADCval;
[*] ADCuBE = ADCuBE;
[*] 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;
[*] u32_hfe*= RH_RL_RATIO; //高低电阻比
[*]
[*] if(ADCuBE < 11) ADCuBE = 11;
[*]
[*] u32_hfe/= ADCuBE;
[*] ADCval = (uint16_t)u32_hfe;
[*]
[*] //lcd_eep_string(hfeSTR); //“hFE=”
[*] OLED_ShowString(0,4,"hFE=",16);
[*] //lcd_string(utoa(ADCval, chrVAL, 10));
[*] OLED_ShowNum(32,4,(ADCval),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.Cathode == e) && (diodes.Anode == b) && (PartMode == PART_MODE_NPN)) || ((diodes.Anode == e) && (diodes.Cathode == b) && (PartMode == PART_MODE_PNP)))
[*] {
[*] //lcd_eep_string(Uf); //“Uf=”
[*] OLED_ShowString(8,6,"Uf=",16);
[*] //lcd_string(itoa(diodes.Voltage, chrVAL, 10));
[*] OLED_ShowNum(32,6,(diodes.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>512) //检查测试电阻两端的电压与中值512相差有多远
[*] {
[*] ADCval = (rv-512);
[*] }
[*] else
[*] {
[*] ADCval = (512-rv);
[*] }
[*]
[*] if(rv>512)
[*] {
[*] ADCval = (rv-512);
[*] }
[*] else
[*] {
[*] ADCval = (512-rv);
[*] }
[*]
[*] if(ADCval > ADCval)
[*] {
[*] rADCmax = rADCmax;
[*] rv = rv; //使用更接近512的结果(准确度更高)
[*] rv = R_H_PER; //470k电阻(数值除100)
[*] }
[*] else
[*] {
[*] rv = R_L_VAL; //680R测试电阻
[*] }
[*]
[*] if(rv==0) rv = 1;
[*] u32_hfe = (uint32_t)((uint32_t)((uint32_t)rv*(uint32_t)rv) / (uint32_t)((uint32_t)rADCmax-(uint32_t)rv));
[*]
[*]//计算电阻
[*] if(rv==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==R_H_PER) //470k电阻
[*]// {
[*]// ra = strlen(chrVAL); //ra字符串长度,必须显示逗号
[*]// for (rb=0;rb<ra;rb++)
[*]// {
[*]// lcd_data(chrVAL);
[*]// 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;
[*]uint8_ttmpVAL, 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 = ReadADC(LowPin);
[*]//OLED_ShowNum(60,6,ADCv,4, 16);
[*]// while(!RX1_Cnt);//等待输入
[*]// Print(0xdd);
[*]// RX1_Cnt=0; //复位
[*]if(ADCv < 20) goto next;
[*]//否则:为 P 通道放电(栅极接正)
[*]DischargePin(TriPin,1);
[*]//再测量LowPin上的电压
[*]ADCv = ReadADC(LowPin);
[*]
[*]next:
[*]if(ADCv < 20) //如果元件在HighPin和LowPin 之间没有连续性
[*]{
[*] tmpVAL2 = (TriPin*2);
[*] R_DDR |= (1<<tmpVAL2); //三态引脚通过 R_L 接地,以测试 pnp
[*] P2M1 = ~P2M0;
[*] _delay_ms(2);
[*] ADCv = ReadADC(LowPin); //测量电压
[*]
[*] if(ADCv > 700)
[*] {
[*] //元件传导 => pnp 三极管或类似的。
[*] //测量两个方向的增益
[*]
[*] R_DDR = (1<<tmpVAL); //三态引脚(基极)高阻抗
[*] P2M1 = ~P2M0;
[*] tmpVAL2++;
[*] R_DDR|= (1<<tmpVAL2); //三态引脚(基极)通过 R_H 接地
[*] P2M1 = ~P2M0;
[*] _delay_ms(10);
[*] ADCv = ReadADC(LowPin); //测量LowPin(假定为集电极)的电压。
[*] ADCv = ReadADC(TriPin); //测量三态引脚(基极)电压
[*] R_DDR = (1<<tmpVAL); //三态引脚(基极)高阻抗
[*] P2M1 = ~P2M0;
[*] //三态引脚(基极)高阻抗
[*] //检查测试是否已经运行过
[*] if((PartFound == PART_TRANSISTOR) || (PartFound == PART_FET)) PartReady = 1; //将PartReady置1(第2轮)
[*]
[*] ADCval = ADCv; //登记到n轮的结果
[*] ADCuBE = ADCv;
[*]
[*] if(ADCv > 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输出
代码:
很好很强大!哈哈。
感谢 我们 STC 51 爱好者的 开源奉献
AVR单片机运行的代码在 github上有很多,
移植到STC上面,用keil c51,移植难度较大,
建议使用 IAR C++ for 8051, 支持新的 C 标准
是不是要换成12位ADC , 提高一下精度 主要是要换成带 硬件 USB,
能 硬件USB下载/仿真的 STC8H8K64U
这有个 电容表,哪位爱好者能整合下,就好了
51 开源 电容表: STC8H8K64U比较器+OLED12864-I2C 实现 - STC开源频谱分析仪-FFT,PID控制,示波器,四轴飞行器,智能小车 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)
这个不错啊 谢谢分享 学习了