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
|