数码之家

 找回密码
 立即注册
搜索
查看: 5347|回复: 11

关于晶体管测试仪测量ESR的原理

[复制链接]
发表于 2019-3-28 18:58:38 | 显示全部楼层 |阅读模式
本帖最后由 长寿烙铁 于 2019-3-28 18:58 编辑

最近学习了一下晶体管测试仪的程序,了解了一些测试原理。
由于初学单片机,而且不懂英语,还有一些问题不明白,请大家多多指教。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
 楼主| 发表于 2019-3-28 18:58:39 | 显示全部楼层
ESR测量  
  
//=================================================================
uint16_t GetESR(uint8_thipin, uint8_t lopin) {
#if FLASHEND > 0x1fff
  // measure the ESR value of capacitor
  unsigned int adcv[4];     // array for 4 ADC readings
  unsigned long sumvolt[4]; // array for 3 sums of ADC readings
  unsigned long cap_val_nF; // measured capacity value in nF units
  uint16_t esrvalue;
  uint8_t HiPinR_L;         // used to switch 680 Ohm to HighPin
  uint8_t HiADC;        // used to switch Highpin directly to GND or VCC用于将高脚直接切换到GND或VCC
  uint8_t LoPinR_L;         // used to switch 680 Ohm to LowPin
  uint8_t LoADC;        // used to switch Lowpin directly to GND or VCC
  uint8_t ii;           //tempory value
  int8_t pp;            //tempory prefix
  uint8_t StartADCmsk;      // Bit mask to start the ADC
  uint8_t SelectLowPin,SelectHighPin;
  int8_t esr0;          //used for ESR zero correction
#ifdef ADC_Sleep_Mode
        StartADCmsk = (1<<ADEN) | (1<<ADIF) |(1<<ADIE) | AUTO_CLOCK_DIV; /* enable ADC and Interrupt */
        ADCSRA = StartADCmsk;     /* enable ADC and Interrupt */
#else
        StartADCmsk =  (1<<ADSC) | (1<<ADEN) | (1<<ADIF) | AUTO_CLOCK_DIV; /*enable and start ADC */
#endif
  }
#if (((PIN_RL1 + 1) !=PIN_RH1) || ((PIN_RL2 + 1) != PIN_RH2) || ((PIN_RL3 + 1) != PIN_RH3))
  LoADC = pgm_read_byte((&PinRLRHADCtab[6])+lopin-TP_MIN)| TXD_MSK;
  HiADC =pgm_read_byte((&PinRLRHADCtab[6])+hipin-TP_MIN) | TXD_MSK;
#else
  LoADC =pgm_read_byte((&PinRLRHADCtab[3])+lopin-TP_MIN) | TXD_MSK;
  HiADC =pgm_read_byte((&PinRLRHADCtab[3])+hipin-TP_MIN) | TXD_MSK;
#endif
  LoPinR_L =pgm_read_byte(&PinRLRHADCtab[lopin-TP_MIN]);  //R_L mask for LowPin R_L load
  HiPinR_L =pgm_read_byte(&PinRLRHADCtab[hipin-TP_MIN]);    //R_L mask for HighPin R_L load
#if (PROCESSOR_TYP == 644) ||(PROCESSOR_TYP == 1280)
    /* ATmega640/1280/2560 1.1V Reference withREFS0=0 */
  SelectLowPin = (lopin | (1<<REFS1) |(0<<REFS0)); // switch ADC toLowPin, Internal Ref.
  SelectHighPin = (hipin | (1<<REFS1) |(0<<REFS0));    // switch ADC toHighPin, Internal Ref.
#else
  SelectLowPin = (lopin | (1<<REFS1) |(1<<REFS0)); // switch ADC toLowPin, Internal Ref.
  SelectHighPin = (hipin | (1<<REFS1) |(1<<REFS0));    // switch ADC toHighPin, Internal Ref.
#endif
//图F
   ADC_PORT = TXD_VAL;       // switch ADC-Port to GND
   ADMUX = SelectLowPin;     // set Mux input and Voltage Reference to internal 1.1V  将mux输入和电压基准设置为内部1.1v
#ifdef NO_AREF_CAP
   wait100us();              /*time for voltage stabilization */
#else
   wait_about10ms();         /* time for voltage stabilization with 100nF */
#endif
   /* start voltage must be negativ启动电压必须为负电压*/
   ADC_DDR = HiADC;                   // switch High Pin to GND
   R_PORT = LoPinR_L;            // switch R-Port to VCC
   R_DDR = LoPinR_L;             // switch R_L port for HighPin to output (VCC)
   wait10us();
   wait2us();
   R_DDR = 0;                //switch off current关断电流
   R_PORT = 0;
   StartADCwait();               // set ADCSRA Interrupt Mode, sleep设置ADCSRA中断模式,休眠
   // Measurement frequency is given by sum ofADC-Reads < 680 Hz for normal ADC speed.
//测量频率由ADC读数的和来确定,正常ADC速度小于680 Hz
   // For fast ADC mode the frequency is below2720 Hz
//对于快速adc模式,频率在2720 Hz以下(used for capacity value below 3.6uF).
   // ADC Sample and Hold (SH) is done 1.5 ADCclock number after real start of conversion.
// ADC采样和保持是在真正开始转换后1.5个ADC时钟数完成。
   // Real ADC-conversion is started with thenext ADC-Clock (125kHz) after setting the ADSC bit.
// 在设置ADSC位之后,下一个ADC时钟(125kHz)开始实际ADC转换。
  
for(ii=0;ii<MAX_CNT;ii++) {
//图A
      ADC_DDR = LoADC;                // switch Low-Pin to output (GND)
      R_PORT = LoPinR_L;          // switch R-Port to VCC
      R_DDR = LoPinR_L;           // switch R_L port for LowPin to output (VCC)
      ADMUX = SelectLowPin;
      StartADCwait();             // set ADCSRA Interrupt Mode, sleep
      StartADCwait();             // set ADCSRA Interrupt Mode, sleep
      adcv[0] = ADCW;             // Voltage LowPin with current
//图B
     ADMUX = SelectHighPin;
         StartADCwait();          // ADCSRA = (1<<ADEN)| (1<<ADIF) | (1<<ADIE) | AUTO_CLOCK_DIV;  
         ADCSRA = (1<<ADSC) | (1<<ADEN) | (1<<ADIF) |AUTO_CLOCK_DIV; // enable ADC and start with ADSC
         wait4us();
         R_PORT = HiPinR_L;            // switch R-Port to VCC
         R_DDR = HiPinR_L;             // switch R_L port for HighPin tooutput (VCC)
         DelayBigCap();       // wait predefined time
      R_DDR = 0;                  
// switch current off,  SH is 1.5 ADC clock behind real start电流关闭,实际启动1.5个ADC时钟后完成SH
      R_PORT = 0;
      while (ADCSRA&(1<<ADSC));       // wait for conversion finished
      adcv[1] = ADCW;             // Voltage HighPin with current
#ifdef ADC_Sleep_Mode
      ADCSRA = StartADCmsk;       /* enable ADC and Interrupt */
#endif
      wdt_reset();
      /* ********* Reverse direction, connectHigh side with GND反向,将高侧与GND连接*********** */
    // 图C
ADC_DDR = HiADC;                // switch High Pin to GND 是否和adcv[2]有冲突
      R_PORT = HiPinR_L;          // switch R-Port to VCC
      R_DDR = HiPinR_L;           // switch R_L port for HighPin to output (VCC)
      wdt_reset();
      ADMUX = SelectHighPin;
      StartADCwait();             // set ADCSRA Interrupt Mode, sleep
      StartADCwait();             // set ADCSRA Interrupt Mode, sleep
      adcv[2] = ADCW;             // Voltage HighPin with current
   //图D
ADMUX = SelectLowPin;
         StartADCwait();          // set ADCSRA Interrupt Mode, sleep
         ADCSRA = (1<<ADSC) | (1<<ADEN) | (1<<ADIF) |AUTO_CLOCK_DIV; // enable ADC and start with ADSC
         wait4us();
         R_PORT = LoPinR_L;
         R_DDR = LoPinR_L;             // switch LowPin with 680 Ohm to VCC
         DelayBigCap();       // wait predefined time
      R_DDR = 0;                  // switch current off
      R_PORT = 0;
      while (ADCSRA&(1<<ADSC));       // wait for conversion finished
      adcv[3] = ADCW;             //  Voltage LowPinwith current
#ifdef ADC_Sleep_Mode
      ADCSRA = StartADCmsk;       /* enable ADC and Interrupt */
#endif

回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-28 18:58:40 | 显示全部楼层
参考程序
#ifdef INHIBIT_SLEEP_MODE
//  #define StartADCwait() ADCSRA =(1<<ADSC) | (1<<ADEN)| (1<<ADIF) | AUTO_CLOCK_DIV; /* enable ADC and start */
    #define StartADCwait() ADCSRA =(1<<ADSC)|(1<<ADEN)|(1<<ADIF)|AUTO_CLOCK_DIV;/* Start conversion */\
    while (ADCSRA & (1 <<ADSC));  /* wait until conversion is done等待转换完成*/
#else
    #define StartADCwait() ADCSRA = (1<<ADEN) | (1<<ADIF) |(1<<ADIE) | AUTO_CLOCK_DIV; /*enable ADC and Interrupt */\
    set_sleep_mode(SLEEP_MODE_ADC);\
    sleep_mode();  /* Start ADC, return, if ADC has finished */
#endif
#if (TP1 < TP2) &&(TP1 < TP3)
#define TP_MIN TP1
#endif
#if (TP2 < TP1) &&(TP2 < TP3)
#define TP_MIN TP2
#endif
#if (TP3 < TP1) &&(TP3 < TP2)
#define TP_MIN TP3
#endif
// The combined Table forswitching RL / RH and ADC pins, index is the TP number
const unsigned char PinRLRHADCtab[] PROGMEM ={
(1<<PIN_RL1),
                        (1<<PIN_RL2),
                       (1<<PIN_RL3),  // Table ofcommands to switch the  R-L resistors Pin0,1,2
#if (((PIN_RL1 + 1) !=PIN_RH1) || ((PIN_RL2 + 1) != PIN_RH2) || ((PIN_RL3 + 1) != PIN_RH3))
// Processors with little memory must use onePin number higher than correspondig Low Resistor
/* PinRHtab */             (1<<PIN_RH1),
                       (1<<PIN_RH2),
                       (1<<PIN_RH3),  // Table ofcommands to switch the  R-L resistors Pin0,1,2
#endif
         // Table include the predefined value TXD_VAL of otheroutput port(s) of port C.
         // Every pin, that should be switched permanent to VCClevel, should be set to 1 in every tab position.
         // The predefined value TXD_MSK defines the pin (all pins),that must be switched permanent to output.
/* PinADCtab */            (1<<TP1)|TXD_VAL,
                       (1<<TP2)|TXD_VAL,
                       (1<<TP3)|TXD_VAL}; // Tableof commands to switch the ADC-Pins 0,1,2 to output
#define pgm_read_byte
// macros for easilyacquiring the bitmasks for pins
#define pinmaskRL(pin)pgm_read_byte(PinRLRHADCtab+(pin))
#if (((PIN_RL1 + 1) !=PIN_RH1) || ((PIN_RL2 + 1) != PIN_RH2) || ((PIN_RL3 + 1) != PIN_RH3))
#define pinmaskRH(pin)pgm_read_byte(PinRLRHADCtab+(pin)+3)
#define pinmaskADC(pin)(pgm_read_byte(PinRLRHADCtab+(pin)+6)) | TXD_MSK
#else
#define pinmaskRH(pin) (pinmaskRL(pin)<<1)
#define pinmaskADC(pin)(pgm_read_byte(PinRLRHADCtab+(pin)+3)) | TXD_MSK
#endif

回复 支持 反对

使用道具 举报

发表于 2019-3-28 19:59:55 | 显示全部楼层
收藏学习了,感谢!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-28 20:20:16 | 显示全部楼层
图C中 ADC_DDR = HiADC;                // switch High Pin to GND
是否和adcv[2]有冲突,引脚接地,怎么测量电压
回复 支持 反对

使用道具 举报

发表于 2019-3-28 20:20:41 | 显示全部楼层
一脸懵逼的点开,一脸懵逼的关闭:titter:
回复 支持 反对

使用道具 举报

发表于 2019-3-28 22:31:44 | 显示全部楼层
我对这话题也感兴趣,但没研究。
只能帮顶一下。
回复 支持 反对

使用道具 举报

发表于 2019-3-29 15:24:27 | 显示全部楼层
我可以在这里跟你请教一下我那个1602的屏幕芯片烧了,可以问一下怎样恢复吗?就是拿它来物测带电的电容烧坏的。就是电路加上PTC主来保护芯片吗?
回复 支持 反对

使用道具 举报

发表于 2019-3-29 17:03:52 | 显示全部楼层
一脸懵逼的点开,一脸懵逼的关闭
回复 支持 反对

使用道具 举报

发表于 2019-3-29 21:15:03 | 显示全部楼层
海岛椰子树 发表于 2019-3-29 15:24
我可以在这里跟你请教一下我那个1602的屏幕芯片烧了,可以问一下怎样恢复吗?就是拿它来物测带电的电容烧坏 ...

屏幕芯片烧了就别折腾了,换新屏幕,还有,电桥还是万用表还有晶体管测试仪,都不能测带电电容,都是要放电后再测
回复 支持 反对

使用道具 举报

发表于 2019-3-31 09:32:08 | 显示全部楼层
官网开源文件里有原理说明pdf
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-4-4 22:12:23 | 显示全部楼层
bxak 发表于 2019-3-31 09:32
官网开源文件里有原理说明pdf

英文网站看不懂啊
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-5 13:55 , Processed in 0.280801 second(s), 11 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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