// monitor Battery in line 4 or line2, if a two line display void Bat_update(uint8_t tt) { if((tt % 16) == 0) { #if (LCD_LINES > 3) lcd_line4(); Battery_check(); #else wait_about1s(); /* time delay before overwiting line2 with Bat= message */ #if (LCD_LINES == 3) lcd_line3(); // use the last line for Bat= #else lcd_line2(); // use the last line for Bat= #endif Battery_check(); wait_about2s(); /* time delay for reading the Bat= message */ #endif } }; /* end Bat_update() */
/* ****************************************************************** */ void function_menu() { uint8_t ii; uint8_t func_number; #ifdef PAGE_MODE uint8_t page_nr; uint8_t p_nr; uint8_t ff; page_nr = MODE_LAST; #ifdef WITH_ROTARY_SWITCH rotary.count = 0; #endif #endif func_number = 0; #ifdef POWER_OFF uint8_t ll; for (ll=0;ll<((MODE_LAST+1)*10);ll++) #else while (1) /* without end, if no power off specified */ #endif { if (func_number > MODE_LAST) func_number -= (MODE_LAST + 1); message_key_released(SELECTION_str); #ifdef FOUR_LINE_LCD #ifdef PAGE_MODE ff = 0; if (func_number == page_nr) ff = 1; // number is found p_nr = page_nr + 1; if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1); if (func_number == p_nr) ff = 1; // number is found p_nr = page_nr + 2; if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1); if (func_number == p_nr) ff = 1; // number is found if (ff == 0) { // func_number is not in page list #ifdef WITH_ROTARY_SWITCH if (rotary.count >= 0) { page_nr = (func_number + MODE_LAST -1); // page_nr = func_number - 2 } else { page_nr = func_number; // for backward, set page_nr to func_number } if (page_nr > MODE_LAST) page_nr -= (MODE_LAST + 1); #else page_nr = func_number; #endif } if (ff == 0) { lcd_line2(); lcd_clear_line(); // clear line 2 } lcd_line2(); // reset cursor to begin of line 2 if (func_number == page_nr) { lcd_data('>'); } else { lcd_space(); // put a blank to 1. row of line 2 } message2line(page_nr); // show first page function if (ff == 0) { lcd_line3(); lcd_clear_line(); // clear line 3 } lcd_line3(); // reset cursor to begin of line 3 p_nr = page_nr + 1; if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1); if (func_number == p_nr) { lcd_data('>'); } else { lcd_space(); // put a blank to 1. row of line 3 } message2line(p_nr); // show 2. page function if (ff == 0) { lcd_line4(); lcd_clear_line(); // clear line 4 } lcd_line4(); // reset cursor to begin of line 4 p_nr = page_nr + 2; if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1); if (func_number == p_nr) { lcd_data('>'); } else { lcd_space(); // put a blank to 1. row of line 4 } message2line(p_nr); // show 3. page function #else /* no PAGE_MODE */ lcd_line2(); lcd_clear_line(); // clear line 2 lcd_line2(); // reset cursor to begin of line 2 lcd_space(); // put a blank to 1. row of line 2 message2line(func_number + MODE_LAST); // show lower (previous) function lcd_line3(); lcd_clear_line(); // clear line 3 lcd_line3(); // reset cursor to begin of line 3 lcd_data('>'); // put a '>' marker to row 1 of line 3 message2line(func_number); // show selectable function lcd_line4(); lcd_clear_line(); // clear line 4 lcd_line4(); // reset cursor to begin of line 4 lcd_space(); // put a blank to 1. row of line 4 message2line(func_number + 1); // show higher (next) function #endif /* PAGE_MODE */ #else /* no FOUR_LINE_LCD */ lcd_line2(); lcd_clear_line(); // clear line 2 lcd_line2(); // reset cursor to begin of line 2 message2line(func_number); #endif /* FOUR_LINE_LCD */ #ifdef POWER_OFF ii = wait_for_key_ms(SHORT_WAIT_TIME); // wait about 5 seconds if (ii > 0) ll = 0; // reset timer, operator present #else ii = wait_for_key_ms(0); // wait endless #endif #ifdef WITH_ROTARY_SWITCH if ((ii >= MIN_SELECT_TIME) || ((rotary_switch_present != 0) && (ii > 0))) #else if (ii >= MIN_SELECT_TIME) #endif { // selection only with key-press if (func_number == MODE_TRANS) break; // return to TransistorTester if (func_number == MODE_FREQ) GetFrequency(0); #if PROCESSOR_TYP == 644 if (func_number == MODE_HFREQ) GetFrequency(1); // measure high frequency with 16:1 divider if (func_number == MODE_H_CRYSTAL) GetFrequency(5); // HF crystal input + 16:1 divider if (func_number == MODE_L_CRYSTAL) GetFrequency(6); // LF crystal input, 1:1 divider #endif if (func_number == MODE_FGEN) { make_frequency(); // make some sample frequencies } if (func_number == MODE_PWM) { do_10bit_PWM(); // generate 10bit PWM } if (func_number == MODE_ESR) { show_C_ESR(); // measure capacity and ESR at TP1 and TP3 } if (func_number == MODE_ROTARY) { CheckRotaryEncoder(); // check rotary encoder } #ifdef WITH_SELFTEST if (func_number == MODE_SELFTEST) AutoCheck(0x11); // Full selftest with calibration #endif if (func_number == MODE_VEXT) show_vext(); #if (LCD_ST_TYPE == 7565) if (func_number == MODE_CONTRAST) set_contrast(); #endif if (func_number == MODE_SHOW) { ShowData(); // Show Calibration Data } if (func_number == MODE_OFF) { ON_PORT &= ~(1<<ON_PIN); //switch off power wait_for_key_ms(0); //never ending loop } // don't increase function number for easier selection the same function ii = 0; // function was executed before, do not increase func_number #ifdef WITH_ROTARY_SWITCH rotary.incre = 0; // reset all rotary information rotary.count = 0; #endif } /* end if (ii >= MIN_SELECT_TIME) */ #ifdef WITH_ROTARY_SWITCH if (rotary.incre >= FAST_ROTATION) break; // to much rotation #ifdef POWER_OFF if (rotary.count != 0) ll = 0; // someone is working, reset timer #endif if (rotary.count >= 0) { func_number += rotary.count; // function number is increased by rotary steps } else { func_number += (MODE_LAST + 1 + rotary.count); // function is decreased by rotary steps } #endif if (ii > 0) func_number++; // increase the function number with key press } /* end for ll */ return; } // end function_menu()
/* *************************************************** */ void make_frequency() { #define MAX_FREQ_NR 19 uint8_t key_pressed; uint8_t freq_nr; uint8_t old_freq; message_key_released(F_GEN_str); // display f-Generator and wait for key released // OC1B is connected with 680 Ohm resistor to TP2 (middle test pin) TCCR1A = (0<<COM1B1) | (1<<COM1B0) | (0<<WGM11) | (0<<WGM10); // CTC mode, count to OCR1A TIMSK1 = 0; // no interrupt used OCR1A = 1; // highest frequency OCR1B = 0; // toggle OC1B at this count TIFR1 = (1<<OCF1A) | (1<<OCF1A) | (1<<TOV1); // reset interrupt flags TCCR1C = 0; TCCR1B = (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10); // set counter mode R_PORT = 0; // set all resistor port outputs to GND #if PROCESSOR_TYP == 644 R_DDR = (1<<PIN_RL1) | (1<<PIN_RL2) | (1<<PIN_RL3); // set TP1, DDD4(TP2) and TP3 to output #else R_DDR = (1<<PIN_RL1) | (1<<PIN_RL3); // set TP1 and TP3 to output #endif ADC_PORT = TXD_VAL; ADC_DDR = (1<<TP1) | TXD_MSK; //connect TP1 to GND DDRB |= (1<<DDB2); // set output enable TCCR1B = (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10); // no clock divide old_freq = 0; freq_nr = MAX_FREQ_NR - 1; // start with 1 MHz #ifdef POWER_OFF uint8_t new_points; // one point for every 30 seconds wait time uint8_t shown_points; // one point for every 30 seconds wait time uint8_t times; // total wait time shown_points = 0; for (times=0; times<240; times++) #else while (1) /* wait endless without option POWER_OFF */ #endif { #define KEYPRESS_LENGTH_10ms 0 #ifdef POWER_OFF new_points = (times+10) / 30; if (new_points != shown_points) { // count of points has changed, build LCD line1 new lcd_line1(); lcd_clear_line(); // clear line 1 lcd_line1(); lcd_MEM2_string(F_GEN_str); // display f-Generator shown_points = new_points; for (new_points=0; new_points<shown_points ;new_points++) { lcd_data('.'); // show elapsed time, one point is 30 seconds } } #undef KEYPRESS_LENGTH_10ms #define KEYPRESS_LENGTH_10ms 20 /* change frequency only with >200ms key press */ #endif if (old_freq != freq_nr) { // new frequency is selected if (freq_nr > MAX_FREQ_NR) freq_nr -= (MAX_FREQ_NR + 1); old_freq = freq_nr; // update the last active frequency number #ifdef FOUR_LINE_LCD lcd_line2(); lcd_clear_line(); // clear line 2 for previous frequency lcd_line2(); lcd_space(); // add a space to row 1 of line2 switch_frequency(freq_nr + MAX_FREQ_NR); lcd_line4(); lcd_clear_line(); // clear line 4 for next frequency lcd_line4(); lcd_space(); // add a space to row 1 of line4 switch_frequency(freq_nr + 1); lcd_line3(); lcd_clear_line(); // clear line 3 for new frequency lcd_line3(); lcd_data('>'); switch_frequency(freq_nr); #else lcd_line2(); lcd_clear_line(); // clear line 2 for next frequency lcd_line2(); switch_frequency(freq_nr); #endif } /* end if (old_freq != freq_nr) */ key_pressed = wait_for_key_ms(1000); #ifdef POWER_OFF #ifdef WITH_ROTARY_SWITCH if ((key_pressed != 0) || (rotary.incre > 0)) times = 0; // reset counter, operator is active #else if (key_pressed != 0) times = 0; // reset counter, operator is active #endif #endif #ifdef WITH_ROTARY_SWITCH if (rotary.incre > FAST_ROTATION) break; // fast rotation ends voltage measurement if (rotary.count >= 0) { freq_nr += rotary.count; // increase the frequency number by rotary.count } else { freq_nr += (MAX_FREQ_NR + 1 + rotary.count); // decrease the frequency by rotary.count } #endif if (key_pressed > KEYPRESS_LENGTH_10ms) freq_nr++; // longer key press select next frequency if(key_pressed >= 80) break; // more than 0.8 seconds } /* end for times */ TCCR1B = 0; // stop counter TCCR1A = 0; // stop counter ADC_DDR = TXD_MSK; // disconnect TP1 R_DDR = 0; // switch resistor ports to Input DDRB &= ~(1<<DDB2); // disable output } /* end make frequency */
// not enough Flash space for ShowIcons at ATmega328 // Show all Icons on the screen, up to four at one screen void ShowIcons(void) { #define ShowTime 15000 /* 15 seconds wait time, or key press, or rotary encoder movement */ uint8_t cc; lcd_clear(); lcd_big_icon(BJT_NPN|LCD_UPPER_LEFT); lcd_update_icon_opt(bmp_vakdiode, OPT_VREVERSE); lcd_big_icon(BJT_NPN|LCD_UPPER_RIGHT); lcd_update_icon(bmp_pnp); // update for PNP lcd_set_cursor(5,0); lcd_MEM_string(NPN_str); lcd_set_cursor(5,(LCD_LINE_LENGTH / 2)); lcd_MEM_string(PNP_str); wait_for_key_ms(ShowTime); lcd_clear(); lcd_big_icon(N_JFET|LCD_LOWER_LEFT); lcd_big_icon(N_JFET|LCD_LOWER_RIGHT); lcd_update_icon(bmp_p_jfet); // update to P_JFET lcd_set_cursor(2,1); lcd_data('N'); // N-Type lcd_data('-'); lcd_MEM_string(jfet_str); lcd_set_cursor(2,1+(LCD_LINE_LENGTH / 2)); lcd_data('P'); // P-Type lcd_data('-'); lcd_MEM_string(jfet_str); wait_for_key_ms(ShowTime); lcd_clear(); lcd_big_icon(N_E_IGBT|LCD_UPPER_LEFT); lcd_big_icon(N_E_IGBT|LCD_UPPER_RIGHT); lcd_update_icon(bmp_p_e_igbt); // update to P-E-IGBT lcd_set_cursor(5,0); lcd_data('N'); // N-Type lcd_data('-'); lcd_data('E'); // Enhancement Type lcd_MEM_string(igbt_str); lcd_set_cursor(6,(LCD_LINE_LENGTH / 2)); lcd_data('P'); // P-Type lcd_data('-'); lcd_data('E'); // Enhancement Type lcd_MEM_string(igbt_str); wait_for_key_ms(ShowTime); lcd_clear(); lcd_big_icon(N_E_IGBT|LCD_LOWER_LEFT); lcd_update_icon(bmp_n_d_igbt); // update to N-D-IGBT lcd_big_icon(N_E_IGBT|LCD_LOWER_RIGHT); lcd_update_icon(bmp_p_d_igbt); // update to P-D-IGBT lcd_set_cursor(1,0); lcd_data('N'); // N-Type lcd_data('-'); lcd_data('D'); // Depletion Type lcd_MEM_string(igbt_str); lcd_set_cursor(2,(LCD_LINE_LENGTH / 2)); lcd_data('P'); // P-Type lcd_data('-'); lcd_data('D'); // Depletion Type lcd_MEM_string(igbt_str); wait_for_key_ms(ShowTime); lcd_clear(); lcd_big_icon(N_E_MOS|LCD_UPPER_LEFT); lcd_big_icon(N_E_MOS|LCD_UPPER_RIGHT); lcd_update_icon(bmp_p_e_mos); // update to P-E-MOS lcd_set_cursor(5,0); lcd_data('N'); // N-Type lcd_data('-'); lcd_data('E'); // Enhancement Type lcd_MEM_string(mosfet_str); lcd_set_cursor(6,(LCD_LINE_LENGTH / 2)); lcd_data('P'); // P-Type lcd_data('-'); lcd_data('E'); // Enhancement Type lcd_MEM_string(mosfet_str); wait_for_key_ms(ShowTime); lcd_clear(); lcd_big_icon(N_E_MOS|LCD_LOWER_LEFT); lcd_update_icon(bmp_n_d_mos); // update to N-D-MOS lcd_big_icon(N_E_MOS|LCD_LOWER_RIGHT); lcd_update_icon(bmp_p_d_mos); // update to P-D-MOS lcd_set_cursor(1,1); lcd_data('N'); // N-Type lcd_data('-'); lcd_data('D'); // Depletion Type lcd_MEM_string(mosfet_str); lcd_set_cursor(2,1+(LCD_LINE_LENGTH / 2)); lcd_data('P'); // P-Type lcd_data('-'); lcd_data('D'); // Depletion Type lcd_MEM_string(mosfet_str); wait_for_key_ms(ShowTime); #if (ICON_ELEMENTS == 14) lcd_clear(); lcd_big_icon(TRIAC|LCD_UPPER_LEFT); lcd_big_icon(THYRISTOR|LCD_UPPER_RIGHT); wait_for_key_ms(ShowTime); lcd_clear(); lcd_big_icon(INDUCTOR|LCD_LOWER_LEFT); lcd_big_icon(CAPACITOR|LCD_LOWER_RIGHT); lcd_big_icon(RESISTOR|LCD_UPPER_LEFT); lcd_big_icon(RESISTORS|LCD_UPPER_RIGHT); wait_for_key_ms(ShowTime); lcd_clear(); lcd_big_icon(DIODE_C_A|LCD_UPPER_LEFT); lcd_big_icon(DIODES_C_A_C_A|LCD_UPPER_RIGHT); lcd_big_icon(DIODES_A_C_C_A|LCD_LOWER_LEFT); lcd_big_icon(DIODES_C_A_A_C|LCD_LOWER_RIGHT); wait_for_key_ms(ShowTime); #endif lcd_clear(); lcd_line1(); lcd_MEM_string(Resistor_str); // -[=]- lcd_line2(); lcd_MEM_string(Inductor_str); // -ww- lcd_line3(); lcd_MEM_string(CapZeich); // capacitor sign lcd_line4(); lcd_MEM_string(AnKat_str); //"->|-" lcd_space(); lcd_MEM_string(KatAn_str); //"-|<-" // show character set for (cc=0;cc<(0x7f-0x20);cc++) { if ((cc%16) == 0) { // begin new line if((cc%64) == 0) { wait_for_key_ms(ShowTime); lcd_clear(); } lcd_set_cursor(((cc/16)%4)*2,0); } lcd_data(cc+0x20); } /* end for cc */ wait_for_key_ms(ShowTime); lcd_clear(); #ifdef LCD_CYRILLIC for (cc=0;cc<((Cyr_ja+1-Cyr_B)+(Cyr_schtsch+1-Cyr_D));cc++) { if ((cc%16) == 0) { // begin new line lcd_set_cursor(((cc/16)%4)*2,0); } if (cc <= (Cyr_ja-Cyr_B)) { lcd_data(cc + Cyr_B); } else { lcd_data(cc + Cyr_D - (Cyr_ja + 1 - Cyr_B)); } } /* end for cc */ wait_for_key_ms(ShowTime); lcd_clear(); #endif }
//================================================================= void ReadInductance(void) { #if FLASHEND > 0x1fff // check if inductor and measure the inductance value unsigned int tmpint; unsigned int umax; unsigned int total_r; // total resistance of current loop unsigned int mess_r; // value of resistor used for current measurement unsigned long inductance[4]; // four inductance values for different measurements union t_combi{ unsigned long dw; // time_constant uint16_t w[2]; } timeconstant; uint16_t per_ref1,per_ref2; // percentage uint8_t LoPinR_L; // Mask for switching R_L resistor of low pin uint8_t HiADC; // Mask for switching the high pin direct to VCC uint8_t ii; uint8_t count; // counter for the different measurements uint8_t cnt_diff; // resistance dependent offset uint8_t LowPin; // number of pin with low voltage uint8_t HighPin; // number of pin with high voltage int8_t ukorr; // correction of comparator voltage uint8_t nr_pol1; // number of successfull inductance measurement with polarity 1 uint8_t nr_pol2; // number of successfull inductance measurement with polarity 2 inductor_lpre = 0; // H units, mark inductor as 0 if(PartFound != PART_RESISTOR) { return; //We have found no resistor } if (ResistorsFound != 1) { return; // do not search for inductance, more than 1 resistor } if (resis[0].rx > 21000) return; // we can check for Inductance, if resistance is below 2100 Ohm for (count=0;count<4;count++) { // Try four times (different direction and with delayed counter start) if (count < 2) { // first and second pass, direction 1 LowPin = resis[0].ra; HighPin = resis[0].rb; } else { // third and fourth pass, direction 2 LowPin = resis[0].rb; HighPin = resis[0].ra; } HiADC = pgm_read_byte(&PinADCtab[HighPin]); // Table of ADC Pins including | TXD_VAL LoPinR_L = pgm_read_byte(&PinRLtab[LowPin]); //R_L mask for HighPin R_L load //================================================================================== // Measurement of Inductance values R_PORT = 0; // switch R port to GND ADC_PORT = TXD_VAL; // switch ADC-Port to GND if ((resis[0].rx < 240) && ((count & 0x01) == 0)) { // we can use PinR_L for measurement mess_r = RR680MI - R_L_VAL; // use only pin output resistance ADC_DDR = HiADC | (1<<LowPin) | TXD_MSK; // switch HiADC and Low Pin to GND, } else { R_DDR = LoPinR_L; // switch R_L resistor port for LowPin to output (GND) ADC_DDR = HiADC | TXD_MSK; // switch HiADC Pin to GND mess_r = RR680MI; // use 680 Ohm and PinR_L for current measurement } // Look, if we can detect any current for (ii=0;ii<20;ii++) { // wait for current is near zero umax = W10msReadADC(LowPin); total_r = ReadADC(HighPin); if ((umax < 2) && (total_r < 2)) break; // low current detected } // setup Analog Comparator ADC_COMP_CONTROL = (1<<ACME); //enable Analog Comparator Multiplexer ACSR = (1<<ACBG) | (1<<ACI) | (1<<ACIC); // enable, 1.3V, no Interrupt, Connect to Timer1 ADMUX = (1<<REFS0) | LowPin; // switch Mux to Low-Pin ADCSRA = (1<<ADIF) | AUTO_CLOCK_DIV; //disable ADC // setup Counter1 timeconstant.w[1] = 0; // set ov counter to 0 TCCR1A = 0; // set Counter1 to normal Mode TCNT1 = 0; //set Counter to 0 TI1_INT_FLAGS = (1<<ICF1) | (1<<OCF1B) | (1<<OCF1A) | (1<<TOV1); // reset TIFR or TIFR1 // HiADC |= TXD_VAL; wait200us(); // wait for bandgap to start up if ((count & 0x01) == 0 ) { //first start counter, then start current TCCR1B = (1<<ICNC1) | (0<<ICES1) | (1<<CS10); //start counter 1MHz or 8MHz ADC_PORT = HiADC; // switch ADC-Port to VCC } else { //first start current, then start counter with delay //parasitic capacity of coil can cause high current at the beginning ADC_PORT = HiADC; // switch ADC-Port to VCC #if F_CPU >= 8000000UL wait3us(); // ignore current peak from capacity #else wdt_reset(); // delay wdt_reset(); // delay #endif TI1_INT_FLAGS = (1<<ICF1); // Reset Input Capture TCCR1B = (1<<ICNC1) | (0<<ICES1) | (1<<CS10); //start counter 1MHz or 8MHz } //****************************** while(1) { // Wait, until Input Capture is set ii = TI1_INT_FLAGS; //read Timer flags if (ii & (1<<ICF1)) { break; } if((ii & (1<<TOV1))) { // counter overflow, 65.536 ms @ 1MHz, 8.192ms @ 8MHz TI1_INT_FLAGS = (1<<TOV1); // Reset OV Flag wdt_reset(); timeconstant.w[1]++; // count one OV if(timeconstant.w[1] == (F_CPU/100000UL)) { break; //Timeout for Charging, above 0.13 s } } } TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<CS10); // stop counter TI1_INT_FLAGS = (1<<ICF1); // Reset Input Capture timeconstant.w[0] = ICR1; // get previous Input Capture Counter flag // check actual counter, if an additional overflow must be added if((TCNT1 > timeconstant.w[0]) && (ii & (1<<TOV1))) { // this OV was not counted, but was before the Input Capture TI1_INT_FLAGS = (1<<TOV1); // Reset OV Flag timeconstant.w[1]++; // count one additional OV } ADC_PORT = TXD_VAL; // switch ADC-Port to GND ADCSRA = (1<<ADEN) | (1<<ADIF) | AUTO_CLOCK_DIV; //enable ADC for (ii=0;ii<20;ii++) { // wait for current is near zero umax = W10msReadADC(LowPin); total_r = ReadADC(HighPin); if ((umax < 2) && (total_r < 2)) break; // low current detected } #define CNT_ZERO_42 6 #define CNT_ZERO_720 7 //#if F_CPU == 16000000UL // #undef CNT_ZERO_42 // #undef CNT_ZERO_720 // #define CNT_ZERO_42 7 // #define CNT_ZERO_720 10 //#endif total_r = (mess_r + resis[0].rx + RRpinMI); // cnt_diff = 0; // if (total_r > 7000) cnt_diff = 1; // if (total_r > 14000) cnt_diff = 2; cnt_diff = total_r / ((14000UL * 8) / (F_CPU/1000000UL)); tmpint = ref_mv_offs; // corrected reference voltage (for C) if (mess_r < R_L_VAL) { // measurement without 680 Ohm cnt_diff = CNT_ZERO_42; if (timeconstant.dw < 225) { ukorr = (timeconstant.w[0] / 5) - 20; } else { ukorr = 25; } tmpint -= (((REF_L_KORR * 10) / 10) + ukorr); } else { // measurement with 680 Ohm resistor // if 680 Ohm resistor is used, use REF_L_KORR for correction cnt_diff += CNT_ZERO_720; tmpint += REF_L_KORR; } if (timeconstant.dw > cnt_diff) timeconstant.dw -= cnt_diff; else timeconstant.dw = 0; if ((count&0x01) == 1) { // second pass with delayed counter start timeconstant.dw += (3 * (F_CPU/1000000UL))+10; } if (timeconstant.w[1] >= (F_CPU/100000UL)) timeconstant.dw = 0; // no transition found if (timeconstant.dw > 10) { timeconstant.dw -= 1; } // compute the maximum Voltage umax with the Resistor of the coil umax = ((unsigned long)mess_r * (unsigned long)ADCconfig.U_AVCC) / total_r; per_ref1 = ((unsigned long)tmpint * 1000) / umax; // per_ref2 = (uint8_t)MEM2_read_byte(&LogTab[per_ref1]); // -log(1 - per_ref1/100) per_ref2 = get_log(per_ref1); // -log(1 - per_ref1/1000) /* ********************************************************* */ #if 0 if (count == 0) { lcd_line3(); DisplayValue(count,0,' ',4); DisplayValue(timeconstant.dw,0,'+',4); DisplayValue(cnt_diff,0,' ',4); DisplayValue(total_r,-1,'r',4); lcd_space(); DisplayValue(per_ref1,-1,'%',4); lcd_line4(); DisplayValue(tmpint,-3,'V',4); lcd_space(); DisplayValue(umax,-3,'V',4); lcd_space(); DisplayValue(per_ref2,-1,'%',4); wait_about4s(); wait_about2s(); } #endif /* ********************************************************* */ // inductor_lx in 0.01mH units, L = Tau * R per_ref1 = ((per_ref2 * (F_CPU/1000000UL)) + 5) / 10; inductance[count] = (timeconstant.dw * total_r ) / per_ref1; if (((count&0x01) == 0) && (timeconstant.dw > ((F_CPU/1000000UL)+3))) { // transition is found, measurement with delayed counter start is not necessary inductance[count+1] = inductance[count]; // set delayed measurement to same value count++; // skip the delayed measurement } wdt_reset(); } //end for count ADC_PORT = TXD_VAL; // switch ADC Port to GND wait_about20ms(); nr_pol1 = 0; if (inductance[1] > inductance[0]) { nr_pol1 = 1; } nr_pol2 = 2; if (inductance[3] > inductance[2]) { nr_pol2 = 3; } if (inductance[nr_pol2] < inductance[nr_pol1]) nr_pol1 = nr_pol2; inductor_lx = inductance[nr_pol1]; inductor_lpre = -5; // 10 uH units if (((nr_pol1 & 1) == 1) || (resis[0].rx >= 240)) { // with 680 Ohm resistor total_r is more than 7460 inductor_lpre = -4; // 100 uH units inductor_lx = (inductor_lx + 5) / 10; } if (inductor_lx == 0) inductor_lpre = 0; //mark as zero // switch all ports to input ADC_DDR = TXD_MSK; // switch all ADC ports to input R_DDR = 0; // switch all resistor ports to input #endif return; } // end ReadInductance()
void GetFrequency(uint8_t range) { unsigned char taste; // set if key is pressed during measurement #if PROCESSOR_TYP == 644 unsigned long freq_count; // the counted pulses in 1 second #endif unsigned long long ext_period; unsigned long freq_from_per; uint8_t ii; uint8_t mm; /* range has set the lowest bit to use the 16:1 frequency divider permanently. */ /* The upper bits of range specifies the input selection. */ /* 0 = external input, 2 = channel 2, 4 = HF Quartz, 6 = LF Quartz */ #if PROCESSOR_TYP == 644 FDIV_DDR |= (1<<FDIV_PIN); //switch to output if ((range & 0x01) == 0) { FDIV_PORT &= ~(1<<FDIV_PIN); // switch off the 16:1 divider } else { FDIV_PORT |= (1<<FDIV_PIN); // use frequency divider for next measurement } FINP_DDR |= (1<<FINP_P0) | (1<<FINP_P1); // switch both pins to output FINP_PORT &= ~(1<<FINP_P0); // clear lower bit of input selection FINP_PORT &= ~(1<<FINP_P1); // clear higher bit of input selection if (range == 0) { message_key_released(FREQ_str); // Frequency: in line 1 } else if (range == 1) { message_key_released(HFREQ_str); // High Frequency: in line 1 } else if (range < 4) { /* 2+3 */ FINP_PORT |= (1<<FINP_P0); // set lower bit of input selection FINP_PORT &= ~(1<<FINP_P1); // clear higher bit of input selection } else if (range < 6) { /* 4+5 */ FINP_PORT &= ~(1<<FINP_P0); // clear lower bit of input selection FINP_PORT |= (1<<FINP_P1); // set higher bit of input selection message_key_released(H_CRYSTAL_str); // HF Quarz: in line 1 } else { /* 6+7 */ FINP_PORT |= (1<<FINP_P0); // set lower bit of input selection FINP_PORT |= (1<<FINP_P1); // set higher bit of input selection message_key_released(L_CRYSTAL_str); // LF Quarz: in line 1 } #else message_key_released(FREQ_str); // Frequency: in line 1 #endif taste = 0; // reset flag for key pressed for (mm=0;mm<240;mm++) { // ************************************************************************* // *********** straight frequency measurement by counting 1 second ********* // ************************************************************************* //set up Counter 0 // Counter 0 is used to count the external signal connected to T0 (PD4 or PB0) FREQINP_DDR &= ~(1<<FREQINP_PIN); // switch frequency pin to input wait1ms(); // let capacitor time to load to 2.4V input #if PROCESSOR_TYP == 1280 TCCR3A = 0; // normal operation, no output TCNT3 = 0; // set counter 3 to zero ext_freq.dw = 0; // set external frequency to zero TIFR3 = (1<<TOV3); // clear OV interrupt of timer 3 TIMSK3 = (1<<TOIE3); // enable OV interrupt of timer 3 #else TCCR0A = 0; // normal operation, no output TCNT0 = 0; // set counter to zero ext_freq.dw = 0; // set external frequency to zero TIFR0 = (1<<TOV0); // clear OV interrupt of timer 0 TIMSK0 = (1<<TOIE0); // enable OV interrupt of timer 0 #endif // start counter after starting second counter timer 1 // set up counter 1 to measure one second TCCR1A = 0; // normal operation #define CNT1_END_VAL ((F_CPU / 256UL) + 1) #define CNT1_DIVIDER (1<<CS12) #if CNT1_END_VAL > 0xffff #undef CNT1_END_VAL #undef CNT1_DIVIDER #define CNT1_END_VAL ((F_CPU / 1024UL) + 1) #define CNT1_DIVIDER ((1<<CS12) | (1<<CS10)) #if F_CPU != ((F_CPU / 1024UL) * 1024UL) #warning F_CPU can not be divided by 1024, measured frequency is wrong! #endif #else #if F_CPU != ((F_CPU / 256UL) * 256UL) #warning F_CPU can not be divided by 256, measured frequency is wrong! #endif #endif OCR1B = CNT1_END_VAL; // set to 1 second (counter 0 is started with 1) OCR1A = 1; // start counter 0 with first count TCNT1 = 0; // set counter to zero GTCCR |= (1<<PSRSYNC); // reset clock precounter TIFR1 = (1<<OCF1B) | (1<<OCF1A); // clear Output compare match TIMSK1 = (1<<OCIE1B) | (1<<OCIE1A); // enable the Compare A match and Compare B match interrupt sei(); // set interrupt enable TCCR1B = CNT1_DIVIDER; // divide CPU clock by 256, start counter // both counter are running now, wait for counter 1 reach OCR1A for (ii=0;ii<50;ii++) { wait20ms(); // first count of counter 1 (<32us) has started the counter 0 wdt_reset(); if (!(RST_PIN_REG & (1<<RST_PIN))) taste = 1; // user request stop of operation #if PROCESSOR_TYP == 1280 if (TCCR3B == 0) break; // timer 3 is stopped by interrupt #else if (TCCR0B == 0) break; // timer 0 is stopped by interrupt #endif } // one second is counted #if PROCESSOR_TYP == 1280 TCCR3B = 0; // stop timer 3, if not stopped by timer 1 compare interrupt ext_freq.w[0] = TCNT3; // add lower 16 bit to get total counts #else TCCR0B = 0; // stop timer 0, if not stopped by timer 1 compare interrupt ext_freq.b[0] = TCNT0; // add lower 8 bit to get total counts #endif #if PROCESSOR_TYP == 644 freq_count = ext_freq.dw; // save the frequency counter #endif #if (LCD_LINES > 3) lcd_line3(); lcd_clear_line(); lcd_line4(); lcd_clear_line(); lcd_clear_line2(); #else lcd_clear(); // clear total display #endif lcd_data('f'); lcd_equal(); // lcd_data('='); #if PROCESSOR_TYP == 644 if ((FDIV_PORT&(1<<FDIV_PIN)) == 0) { Display_Hz(ext_freq.dw, 7); } else { // frequency divider is activ Display_Hz(ext_freq.dw*FREQ_DIV, 7); } #else Display_Hz(ext_freq.dw, 7); #endif #if PROCESSOR_TYP == 644 lcd_space(); if ((FDIV_PORT&(1<<FDIV_PIN)) != 0) { lcd_data('/'); // Frequency divider is activ } else { lcd_space(); // Frequency divider is not activ } #endif FREQINP_DDR &= ~(1<<FREQINP_PIN); // switch frequency pin to input if (TCCR1B != 0) { // Exact 1000ms period is only with "end of period" from timer1 interrupt. // When stopped with the for loop, the time is too long because wait call does not // respect CPU time used for interrupts and loop itself. // For this case show ? behind the Hz. lcd_data('?'); } TCCR1B = 0; // stop timer 1 TIMSK1 = 0; // disable all timer 1 interrupts if ((ext_freq.dw < FMAX_PERIOD) && (ext_freq.dw > 0)) { // ************************************************************************* // ******** Period measurement by counting some periods ******************** // ************************************************************************* pinchange_max = ((10 * (unsigned long)ext_freq.dw) + MHZ_CPU) / MHZ_CPU; // about 10000000 clock tics pinchange_max += pinchange_max; // * 2 for up and down change FREQINP_DDR &= ~(1<<FREQINP_PIN); // switch frequency pin to input wait1ms(); // let capacitor time to load to 2.4V input #if PROCESSOR_TYP == 1280 TCNT3 = 0; // set counter 3 to zero ext_freq.dw = 0; // reset counter to zero TIFR3 = (1<<TOV3); // clear OV interrupt TIMSK3 = (1<<TOIE3); // enable OV interrupt // counter 3 ist started with first pin change interrupt pinchange_count = 0; EICRB = (0<<ISC61) | (1<<ISC60); // set int6 pin change EIFR |= (1<<INTF6); // clear interrupt 6 flag PCMSK_FREQ |= (1<<PCINT_FREQ); // enable int6 #else TCNT0 = 0; // set counter 0 to zero ext_freq.dw = 0; // reset counter to zero TIFR0 = (1<<TOV0); // clear OV interrupt TIMSK0 = (1<<TOIE0); // enable OV interrupt // counter 0 ist started with first pin change interrupt pinchange_count = 0; PCIFR = (1<<PCI_CLEAR_BIT); // clear Pin Change Status PCICR |= (1<<PCI_ENABLE_BIT); // enable pin change interrupt #endif sei(); PCMSK_FREQ |= (1<<PCINT_FREQ); // monitor PD4 PCINT20 or PB0 PCINT8 pin change for (ii=0;ii<250;ii++) { wait20ms(); wdt_reset(); if (!(RST_PIN_REG & (1<<RST_PIN))) taste = 1; // user request stop of operation if ((PCMSK_FREQ & (1<<PCINT_FREQ)) == 0) break; // monitoring is disabled by interrupt } /* end for ii */ #if PROCESSOR_TYP == 1280 TCCR3B = 0; // stop counter 3 PCMSK_FREQ &= ~(1<<PCINT_FREQ); // disable int6 ext_freq.w[0] = TCNT3; // add lower 16 bit to get total counts #else TCCR0B = 0; // stop counter 0 PCMSK_FREQ &= ~(1<<PCINT_FREQ); // stop monitor PD4 PCINT20 or PB0 PCINT8 pin change PCICR &= ~(1<<PCI_ENABLE_BIT); // disable the interrupt ext_freq.b[0] = TCNT0; // add lower 8 bit to get total counts #endif // lcd_clear_line2(); // wait50ms(); // let LCD flicker to #if (LCD_LINES > 3) lcd_line3(); // use line3 to report the period with 4-line LCD #else lcd_line2(); // report period on line 2 of 2-line LCD #endif lcd_data('T'); lcd_equal(); // lcd_data('='); ext_period = ((unsigned long long)ext_freq.dw * (200000/MHZ_CPU)) / pinchange_max; #if PROCESSOR_TYP == 644 if ((FDIV_PORT&(1<<FDIV_PIN)) != 0) { // frequency divider is activ, period is measured too long ext_period = ext_period / FREQ_DIV; } #endif if (pinchange_max > 127) { DisplayValue(ext_period,-11,'s',7); // show period converted to 0.01ns units } else { //prevent overflow of 32-Bit DisplayValue((unsigned long)(ext_period/100),-9,'s',7); // show period converted to 1ns units } if (ii == 250) { lcd_data('?'); // wait loop has regular finished } else { if (ext_period > 249500) { #if (LCD_LINES > 3) lcd_line4(); // use line 4 of 4-line LCD to report the computed frequency #else lcd_line1(); // overwrite line 1 of 2-line LCD to report the computed frequency #endif lcd_data('f'); lcd_equal(); // lcd_data('='); if (ext_period > 1000000000) { // frequency in 0.000001Hz (1e11*1e6)/(0.01ns count) freq_from_per = (unsigned long long)(100000000000000000) / ext_period; DisplayValue(freq_from_per,-6,'H',7); // display with 0.000001 Hz resolution } else { // prevent unsigned long overflow, scale to 0.0001 Hz // frequency in 0.0001Hz (1e11*1e4)/(0.01ns count) freq_from_per = (unsigned long long)(1000000000000000) / ext_period; DisplayValue(freq_from_per,-4,'H',7); // display with 0.0001 Hz resolution } lcd_data('z'); FREQINP_DDR &= ~(1<<FREQINP_PIN); // switch frequency pin to input } } } /* end if 1 < ext_freq < FMAX_PERIOD */ #if PROCESSOR_TYP == 644 if ((FDIV_PORT & (1<<FDIV_PIN)) == 0) { // frequency divider is not activ if ( ((freq_count >= FMAX_PERIOD) && (freq_count < ((unsigned long)FMAX_PERIOD*FREQ_DIV))) || (freq_count > FMAX_INPUT) ){ FDIV_PORT |= (1<<FDIV_PIN); // use frequency divider for next measurement } } else { // frequency divider is activ if ((freq_count < (FMAX_PERIOD/FREQ_DIV)) && ((range & 0x01) == 0)) { FDIV_PORT &= ~(1<<FDIV_PIN); // switch off the 16:1 divider } } #endif // taste += wait_for_key_ms(SHORT_WAIT_TIME/2); TIMSK0 = 0; // disable all timer 0 interrupts taste += wait_for_key_ms(2000); #ifdef WITH_ROTARY_SWITCH if ((taste != 0) || (rotary.incre > 2)) break; #else if (taste != 0) break; #endif } /* end for mm */ return; } // end GetFrequency()
void AutoCheck(uint8_t test_mode) { /* (test_mode & 0x0f) == 0 , only calibration without T1-T7 */ /* (test_mode & 0x0f) == 1 , calibration and additional T1-T7 */ /* (test_mode & 0xf0) == 0 , check for shorted probes, if unshorted, return */ /* (test_mode & 0xf0) == 0x10 , ask for shorted probes */ uint8_t ww; // counter for repeating the tests int adcmv[7]; #ifdef EXTENDED_TESTS uint16_t u680; // 3 * (Voltage at 680 Ohm) uint8_t taste; // ist key pressed? 0 = no #else #ifndef NO_TEST_T1_T7 #warning "Selftest without extended tests T1 to T7!" #endif #endif #if defined(EXTENDED_TESTS) || defined(WITH_MENU) uint8_t tt; // number of running test #endif #ifdef FREQUENCY_50HZ uint8_t ff50; // loop counter for 2s #endif // define the maximum count of repetitions MAX_REP #define MAX_REP 4 #ifdef AUTO_CAL uint8_t cap_found; // counter for found capacitor #ifdef AUTOSCALE_ADC int8_t udiff; // difference between ADC Voltage with VCC or Bandgap reference int8_t udiff2; #endif #endif PartFound = PART_NONE; // no part found before if ((test_mode & 0xf0) == 0) { // probed should be shorted already to begin selftest if (AllProbesShorted() != 3) return; lcd_clear(); lcd_MEM_string(SELFTEST); // "Selftest mode.." lcd_line2(); lcd_data('?'); // wait for key pressed for confirmation if (wait_for_key_ms(2000) > 10) goto begin_selftest; // key is pressed again #ifdef WITH_MENU } else { // report to user, that probes should be shorted ww = 0; for (tt=0;tt<150;tt++) { /* wait about 30 seconds for shorted probes */ lcd_clear(); lcd_MEM2_string(SHORT_PROBES_str); // message "Short probes!" to LCD if (AllProbesShorted() == 3) { ww++; // all probes now shorted } else { ww = 0; // connection not stable, retry } if (ww > 3) break; // connection seems to be stable lcd_refresh(); // write the pixels to display, ST7920 only wait_about200ms(); // wait 200ms and try again } /* end for (tt...) */ if (tt < 150) goto begin_selftest; // is shorted before time limit goto no_zero_resistance; // skip measuring of the zero resistance #endif } // no key pressed for 2s lcd_clear(); lcd_MEM_string(VERSION_str); //"Version ..." return; begin_selftest: lcd_line2(); lcd_MEM2_string(R0_str); // "R0=" eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[2]), (uint8_t)0); // clear zero offset eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[3]), (uint8_t)0); // clear zero offset eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[1]), (uint8_t)0); // clear zero offset adcmv[0] = GetESR(TP3, TP1); adcmv[1] = GetESR(TP3, TP2); adcmv[2] = GetESR(TP2, TP1); DisplayValue16(adcmv[0],-2,' ',3); DisplayValue16(adcmv[1],-2,' ',3); DisplayValue16(adcmv[2],-2,LCD_CHAR_OMEGA,3); if (adcmv[0] >= 90) { adcmv[0] = ESR_ZERO; // set back to default value } eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[2]), (uint8_t)adcmv[0]); // fix zero offset if (adcmv[1] >= 90) { adcmv[1] = ESR_ZERO; // set back to default value } eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[3]), (uint8_t)adcmv[1]); // fix zero offset if (adcmv[2] >= 90) { adcmv[2] = ESR_ZERO; // set back to default value } eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[1]), (uint8_t)adcmv[2]); // fix zero offset last_line_used = 2; wait_for_key_5s_line2(); // wait up to 5 seconds and clear line 2 #ifdef WITH_MENU no_zero_resistance: #endif #ifdef EXTENDED_TESTS #define TEST_COUNT 8 if((test_mode & 0x0f) == 1) { /* full test requested */ for(tt=1;tt<TEST_COUNT;tt++) { // loop for all Tests for(ww=0;ww<MAX_REP;ww++) { // repeat the test MAX_REP times lcd_clear_line2(); // clear total line 2 lcd_clear_line1(); // clear total line 1 lcd_data('T'); //output the Testmode "T" u2lcd(tt); //lcd_string(utoa(tt, outval, 10)); //output Test number lcd_space(); //############################################ if (tt == 1) { // output of reference voltage and factors for capacity measurement lcd_MEM2_string(URef_str); //"URef=" Calibrate_UR(); // get Reference voltage, Pin resistance Display_mV(ref_mv,4); lcd_line2(); //Cursor to column 1, row 2 lcd_MEM2_string(RHfakt_str); //"RHf=" u2lcd(RHmultip); //lcd_string(utoa(RHmultip, outval, 10)); ADCconfig.Samples = R_ANZ_MESS; // set number of ADC reads near to maximum } //############################################ if (tt == 2) { // how equal are the RL resistors? u680 = ((long)ADCconfig.U_AVCC * (PIN_RM + R_L_VAL) / (PIN_RM + R_L_VAL + R_L_VAL + PIN_RP)); R_PORT = 1<<PIN_RL1; //RL1 to VCC R_DDR = (1<<PIN_RL1) | (1<<PIN_RL2); //RL2 to - adcmv[0] = W20msReadADC(TP1); adcmv[0] -= u680; R_DDR = (1<<PIN_RL1) | (1<<PIN_RL3); //RL3 to - adcmv[1] = W20msReadADC(TP1); adcmv[1] -= u680; R_PORT = 1<<PIN_RL2; //RL2 to VCC R_DDR = (1<<PIN_RL2) | (1<<PIN_RL3); //RL3 to - adcmv[2] = W20msReadADC(TP2); adcmv[2] -= u680; lcd_MEM_string(RLRL_str); // "RLRL" } //############################################ if (tt == 3) { // how equal are the RH resistors R_PORT = 1<<PIN_RH1; //RH1 to VCC R_DDR = (1<<PIN_RH1) | (1<<PIN_RH2); //RH2 to - adcmv[0] = W20msReadADC(TP1); adcmv[3] = ADCconfig.U_AVCC / 2; adcmv[0] -= adcmv[3]; R_DDR = (1<<PIN_RH1) | (1<<PIN_RH3); //RH3 to - adcmv[1] = W20msReadADC(TP1); adcmv[1] -= adcmv[3]; R_PORT = 1<<PIN_RH2; //RH2 to VCC R_DDR = (1<<PIN_RH2) | (1<<PIN_RH3); //RH3 to - adcmv[2] = W20msReadADC(TP2); adcmv[2] -= adcmv[3]; lcd_MEM_string(RHRH_str); // "RHRH" } //############################################ if (tt == 4) { // Text release probes lcd_MEM_string(RELPROBE); // "Release Probes" if (AllProbesShorted() != 0) ww = MAX_REP-2; } //############################################ if (tt == 5) { // can we switch the ADC pins to GND across R_H resistor? R_PORT = 0; R_DDR = 1<<PIN_RH1; //Pin 1 over R_H to GND adcmv[0] = W20msReadADC(TP1); R_DDR = 1<<PIN_RH2; //Pin 2 over R_H to GND adcmv[1] = W20msReadADC(TP2); R_DDR = 1<<PIN_RH3; //Pin 3 over R_H to GND adcmv[2] = W20msReadADC(TP3); lcd_MEM_string(RH1L_str); // "RH_Lo=" } //############################################ if (tt == 6) { // can we switch the ADC pins to VCC across the R_H resistor? R_DDR = 1<<PIN_RH1; //Pin 1 over R_H to VCC R_PORT = 1<<PIN_RH1; adcmv[0] = W20msReadADC(TP1) - ADCconfig.U_AVCC; R_DDR = 1<<PIN_RH2; //Pin 2 over R_H to VCC R_PORT = 1<<PIN_RH2; adcmv[1] = W20msReadADC(TP2) - ADCconfig.U_AVCC; R_DDR = 1<<PIN_RH3; //Pin 3 over R_H to VCC R_PORT = 1<<PIN_RH3; adcmv[2] = W20msReadADC(TP3) - ADCconfig.U_AVCC; lcd_MEM_string(RH1H_str); // "RH_Hi=" } if (tt == 7) { // is the voltage of all R_H / R_L dividers correct? u680 = ((long)ADCconfig.U_AVCC * (PIN_RM + R_L_VAL) / (PIN_RM + R_L_VAL + (unsigned long)R_H_VAL*100)); R_PORT = 1<<PIN_RH1; //RH1 to VCC R_DDR = (1<<PIN_RH1) | (1<<PIN_RL1); //RH1 to +, RL1 to - adcmv[0] = W20msReadADC(TP1); adcmv[0] -= u680; R_PORT = 1<<PIN_RH2; //RH2 to VCC R_DDR = (1<<PIN_RH2) | (1<<PIN_RL2); //RH2 to +, RL2 to - adcmv[1] = W20msReadADC(TP2); adcmv[1] -= u680; R_PORT = 1<<PIN_RH3; //RH3 to VCC R_DDR = (1<<PIN_RH3) | (1<<PIN_RL3); //RH3 to +, RL3 to - adcmv[2] = W20msReadADC(TP3); adcmv[2] -= u680; lcd_MEM_string(RHRL_str); // "RH/RL" } //############################################ if (tt > 1) { // output 3 voltages lcd_line2(); //Cursor to column 1, row 2 i2lcd(adcmv[0]); // lcd_string(itoa(adcmv[0], outval, 10)); //output voltage 1 lcd_space(); i2lcd(adcmv[1]); // lcd_string(itoa(adcmv[1], outval, 10)); //output voltage 2 lcd_space(); i2lcd(adcmv[2]); // lcd_string(itoa(adcmv[2], outval, 10)); //output voltage 3 } ADC_DDR = TXD_MSK; // all-Pins to Input ADC_PORT = TXD_VAL; // all ADC-Ports to GND R_DDR = 0; // all R-Ports to Input R_PORT = 0; taste = wait_for_key_ms(1000); // wait up to 1 second or key is pressed if ((tt != 4) && (taste > 10)) { // don't finish repetition for T4 with pressed key break; // if key is pressed, don't repeat } } //end for ww wait_for_key_ms(1000); // wait up to 1 second or key is pressed } //end for tt #if PROCESSOR_TYP == 1280 lcd_clear(); lcd_testpin(TP1); lcd_data('L'); lcd_equal(); // lcd_data('='); ADC_PORT = TXD_VAL; ADC_DDR = (1<<TP1) | TXD_MSK; R_PORT = (1<<PIN_RL1); R_DDR = (1<<PIN_RL1); adcmv[0] = W5msReadADC(TP1); ADCSRB = (1<<MUX5); // switch to upper 8 MUX inputs adcmv[1] = ReadADC(PIN_RL1); ADCSRB = 0; // switch back to lower 8 MUX inputs ResistorVal[0] = (adcmv[0] * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]); DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3); lcd_space(); lcd_data('H'); lcd_equal(); // lcd_data('='); ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[1]) * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]); DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3); lcd_line2(); lcd_testpin(TP1); lcd_space(); lcd_data('H'); lcd_equal(); // lcd_data('='); ADC_PORT = (1<<TP1) | TXD_VAL; R_PORT = 0; adcmv[0] = W5msReadADC(TP1); ADCSRB = (1<<MUX5); // switch to upper 8 MUX inputs adcmv[1] = ReadADC(PIN_RL1); ADCSRB = 0; // switch back to lower 8 MUX inputs ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[0]) * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]); DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3); lcd_space(); lcd_data('L'); lcd_equal(); // lcd_data('='); ResistorVal[0] = (adcmv[1] * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]); DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3); wait_about1s(); // only for mega1280 last_line_used = 2; wait_for_key_5s_line2(); // wait up to 5 seconds and clear line 2 // lcd_clear(); lcd_testpin(TP2); lcd_data('L'); lcd_equal(); // lcd_data('='); ADC_PORT = TXD_VAL; ADC_DDR = (1<<TP2) | TXD_MSK; R_PORT = (1<<PIN_RL2); R_DDR = (1<<PIN_RL2); adcmv[0] = W5msReadADC(TP2); ADCSRB = (1<<MUX5); // switch to upper 8 MUX inputs adcmv[1] = ReadADC(PIN_RL2); ADCSRB = 0; // switch back to lower 8 MUX inputs ResistorVal[0] = (adcmv[0] * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]); DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3); lcd_space(); lcd_data('H'); lcd_equal(); // lcd_data('='); ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[1]) * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]); DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3); lcd_line2(); lcd_testpin(TP2); lcd_data('H'); lcd_equal(); // lcd_data('='); ADC_PORT = (1<<TP2) | TXD_VAL; R_PORT = 0; adcmv[0] = W5msReadADC(TP2); ADCSRB = (1<<MUX5); // switch to upper 8 MUX inputs adcmv[1] = ReadADC(PIN_RL2); ADCSRB = 0; // switch back to lower 8 MUX inputs ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[0]) * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]); DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3); lcd_space(); lcd_data('L'); lcd_equal(); // lcd_data('='); ResistorVal[0] = (adcmv[1] * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]); DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3); wait_about1s(); // only for mega1280 last_line_used = 2; wait_for_key_5s_line2(); // wait up to 5 seconds and clear line 2 // lcd_clear(); lcd_testpin(TP3); lcd_data('L'); lcd_equal(); // lcd_data('='); ADC_DDR = (1<<TP3) | TXD_MSK; R_PORT = (1<<PIN_RL3); R_DDR = (1<<PIN_RL3); adcmv[0] = W5msReadADC(TP3); ADCSRB = (1<<MUX5); // switch to upper 8 MUX inputs adcmv[1] = ReadADC(PIN_RL3); ADCSRB = 0; ResistorVal[0] = (adcmv[0] * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]); DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3); lcd_space(); lcd_data('H'); lcd_equal(); // lcd_data('='); ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[1]) * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]); DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3); lcd_line2(); lcd_testpin(TP3); lcd_data('H'); lcd_equal(); // lcd_data('='); ADC_PORT = (1<<TP3) | TXD_VAL; R_PORT = 0; adcmv[0] = W5msReadADC(TP3); ADCSRB = (1<<MUX5); // switch to upper 8 MUX inputs adcmv[1] = ReadADC(PIN_RL3); ADCSRB = 0; // switch back to lower 8 MUX inputs ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[0]) * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]); DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3); lcd_space(); lcd_data('L'); lcd_equal(); // lcd_data('='); ResistorVal[0] = (adcmv[1] * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]); DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3); wait_about1s(); // only for mega1280 last_line_used = 2; wait_for_key_5s_line2(); // wait up to 5 seconds and clear line 2 #endif /* PROCESSOR_TYP == 1280 */ } /* end if((test_mode & 0x0f) == 1) */ #endif /* end EXTENDED_TESTS */ for (ww=0;ww<120;ww++) { // wait up to 1 minute for releasing the probes if (AllProbesShorted() == 0) break; lcd_clear_line2(); // clear total line2 lcd_MEM_string(RELPROBE); // "Release Probes" lcd_refresh(); // write the pixels to display, ST7920 only wait_about500ms(); } lcd_clear(); lcd_MEM_string(RIHI_str); // "RiHi=" DisplayValue16(RRpinPL,-1,LCD_CHAR_OMEGA,3); lcd_line2(); lcd_MEM_string(RILO_str); // "RiLo=" DisplayValue16(RRpinMI,-1,LCD_CHAR_OMEGA,3); last_line_used = 2; wait_for_key_5s_line2(); // wait up to 5 seconds and clear line 2 //measure Zero offset for Capacity measurement PartFound = PART_NONE; lcd_clear(); lcd_MEM_string(C0_str); //output "C0 " ReadCapacity(TP3, TP1); adcmv[5] = (unsigned int) cap.cval_uncorrected.dw; //save capacity value of empty Pin 1:3 ReadCapacity(TP3, TP2); adcmv[6] = (unsigned int) cap.cval_uncorrected.dw; //save capacity value of empty Pin 2:3 ReadCapacity(TP2, TP1); adcmv[2] = (unsigned int) cap.cval_uncorrected.dw; //save capacity value of empty Pin 1:2 ReadCapacity(TP1, TP3); adcmv[1] = (unsigned int) cap.cval_uncorrected.dw; //save capacity value of empty Pin 3:1 ReadCapacity(TP2, TP3); adcmv[4] = (unsigned int) cap.cval_uncorrected.dw; //save capacity value of empty Pin 3:2 ReadCapacity(TP1, TP2); adcmv[0] = (unsigned int) cap.cval_uncorrected.dw; //save capacity value of empty Pin 2:1 #ifdef WITH_MENU if (((test_mode & 0x0f) == 1) || (UnCalibrated == 2)) #else if (UnCalibrated == 2) #endif { adcmv[3] = adcmv[0] + 2; // mark as uncalibrated until Cap > 100nF has success } else { adcmv[3] = adcmv[0]; // mark as calibrated, short calibration is finished UnCalibrated = 0; // clear the UnCalibrated Flag lcd_cursor_off(); // switch cursor off } u2lcd_space(adcmv[5]); //DisplayValue(adcmv[5],0,' ',3); //output cap0 1:3 u2lcd_space(adcmv[6]); //DisplayValue(adcmv[6],0,' ',3); //output cap0 2:3 DisplayValue(adcmv[2],-12,'F',3); //output cap0 1:2 #ifdef AUTO_CAL for (ww=0;ww<7;ww++) { //checking loop if ((adcmv[ww] > 190) || (adcmv[ww] < 10)) goto no_c0save; } for (ww=0;ww<7;ww++) { // write all zero offsets to the EEprom (void) eeprom_write_byte((uint8_t *)(&c_zero_tab[ww]),adcmv[ww]+(COMP_SLEW1 / (CC0 + CABLE_CAP + COMP_SLEW2))); } lcd_line2(); lcd_MEM_string(OK_str); // output "OK" no_c0save: #endif last_line_used = 2; wait_for_key_5s_line2(); // wait up to 5 seconds and clear line 2 #ifdef SamplingADC sampling_cap_calibrate(); // measure zero capacity for samplingADC #endif #ifdef AUTO_CAL #ifdef WITH_MENU if (((test_mode & 0x0f) == 1) || (UnCalibrated == 2)) #endif // without menu function the capacitor is requested every time, // because there is no way to request recaltbration again // With menu function the capacitor is only requested for first time // calibration (UnCalibrated = 2) or for the full selftest call (test_mode = 1) // of the menu function, not with the automatically call (test_mode = 1). { // for full test or first time calibration, use external capacitor // Message C > 100nF at TP1 and TP3 cap_found = 0; for (ww=0;ww<64;ww++) { init_parts(); #if (TPCAP >= 0) CalibrationCap(); // measure with internal calibration capacitor #else lcd_clear(); lcd_testpin(TP1); lcd_MEM_string(CapZeich); // "-||-" lcd_testpin(TP3); lcd_MEM2_string(MinCap_str); // " >100nF!" PartFound = PART_NONE; ReadCapacity(TP3, TP1); // look for capacitor > 100nF #endif while (cap.cpre < -9) { cap.cpre++; cap.cval /= 10; } if ((cap.cpre == -9) && (cap.cval > 95) && (cap.cval < 22000) && (load_diff > -150) && (load_diff < 150)) { cap_found++; } else { cap_found = 0; // wait for stable connection } if (cap_found > 4) { // value of capacitor is correct (void) eeprom_write_word((uint16_t *)(&ref_offset), load_diff); // hold zero offset + slew rate dependend offset lcd_clear(); lcd_MEM2_string(REF_C_str); // "REF_C=" i2lcd(load_diff); // lcd_string(itoa(load_diff, outval, 10)); //output REF_C_KORR RefVoltage(); // new ref_mv_offs and RHmultip #if 0 //####################################### // Test for switching level of the digital input of port TP3 for (tt=0;tt<8;tt++) { ADC_PORT = TXD_VAL; //ADC-Port 1 to GND ADC_DDR = 1<<TP1 | TXD_MSK; //ADC-Pin 1 to output 0V R_PORT = 1<<PIN_RH3; //Pin 3 over R_H to VCC R_DDR = 1<<PIN_RH3; //Pin 3 over R_H to VCC while (1) { wdt_reset(); if ((ADC_PIN&(1<<TP3)) == (1<<TP3)) break; } R_DDR = 0; //Pin 3 without current R_PORT = 0; adcmv[0] = ReadADC(TP3); lcd_line3(); Display_mV(adcmv[0],4); R_DDR = 1<<PIN_RH3; //Pin 3 over R_H to GND while (1) { wdt_reset(); if ((ADC_PIN&(1<<TP3)) != (1<<TP3)) break; } R_DDR = 0; //Pin 3 without current lcd_line4(); adcmv[0] = ReadADC(TP3); Display_mV(adcmv[0],4); last_line_used = 2; wait_for_key_5s_line2(); // wait up to 5 seconds and clear line 2 } //####################################### #endif #ifdef AUTOSCALE_ADC #if (TPCAP >= 0) #define CAP_ADC TPCAP /* Cap >100nF is integrated at TPCAP */ TCAP_PORT &= ~(1<<TCAP_RH); // 470k resistor to GND TCAP_DDR |= (1<<TCAP_RH); // enable output #else #define CAP_ADC TP3 /* Cap >100nF at TP3 */ ADC_PORT = TXD_VAL; //ADC-Port 1 to GND ADC_DDR = 1<<TP1 | TXD_MSK; //ADC-Pin 1 to output 0V R_DDR = 1<<PIN_RH3; //Pin 3 over R_H to GND #endif do { adcmv[0] = ReadADC(CAP_ADC); } while (adcmv[0] > 980); #if (TPCAP >= 0) TCAP_DDR &= ~(1<<TCAP_RH); // 470k resistor port to input mode #else R_DDR = 0; //all Pins to input #endif ADCconfig.U_Bandgap = 0; // do not use internal Ref adcmv[0] = ReadADC(CAP_ADC); // get cap voltage with VCC reference ADCconfig.U_Bandgap = adc_internal_reference; adcmv[1] = ReadADC(CAP_ADC); // get cap voltage with internal reference adcmv[1] += adcmv[1]; // double the value ADCconfig.U_Bandgap = 0; // do not use internal Ref adcmv[2] = ReadADC(CAP_ADC); // get cap voltage with VCC reference ADCconfig.U_Bandgap = adc_internal_reference; udiff = (int8_t)(((signed long)(adcmv[0] + adcmv[2] - adcmv[1])) * adc_internal_reference / adcmv[1])+REF_R_KORR; lcd_line2(); lcd_MEM2_string(REF_R_str); // "REF_R=" udiff2 = udiff + (int8_t)eeprom_read_byte((uint8_t *)(&RefDiff)); (void) eeprom_write_byte((uint8_t *)(&RefDiff), (uint8_t)udiff2); // hold offset for true reference Voltage i2lcd(udiff2); // output correction voltage RefVoltage(); // set new ADCconfig.U_Bandgap #endif /* end AUTOSCALE_ADC */ last_line_used = 2; wait_for_key_5s_line2(); // wait up to 5 seconds and clear line 2 UnCalibrated = 0; // clear the UnCalibrated Flag lcd_cursor_off(); // switch cursor off cap_found = eeprom_read_byte((uint8_t *)&c_zero_tab[0]); // read first capacity zero offset eeprom_write_byte((uint8_t *)&c_zero_tab[3], cap_found); // mark as calibrated permanent break; // leave the ww for loop } /* end if (cap_found > 4) */ lcd_line2(); DisplayValue(cap.cval,cap.cpre,'F',4); lcd_refresh(); // write the pixels to display, ST7920 only wait_about200ms(); // wait additional time } // end for ww } /* end if((test_mode & 0x0f) == 1) */ #endif /* end AUTO_CAL */ ADCconfig.Samples = ANZ_MESS; // set to configured number of ADC samples #ifdef SamplingADC sampling_lc_calibrate(); // Cap for L-meas #endif #ifdef FREQUENCY_50HZ //#define TEST_SLEEP_MODE /* only select for checking the sleep delay */ lcd_clear(); lcd_MEM_string(T50HZ); //" 50Hz" lcd_refresh(); // write the pixels to display, ST7920 only ADC_PORT = TXD_VAL; ADC_DDR = 1<<TP1 | TXD_MSK; // Pin 1 to GND R_DDR = (1<<PIN_RL3) | (1<<PIN_RL2); for(ww=0;ww<30;ww++) { // repeat the signal up to 30 times (1 minute) for (ff50=0;ff50<100;ff50++) { // for 2 s generate 50 Hz R_PORT = (1<<PIN_RL2); // Pin 2 over R_L to VCC, Pin 3 over R_L to GND #ifdef TEST_SLEEP_MODE sleep_5ms(2); // test of timing of sleep mode call #else wait10ms(); // normal delay #endif R_PORT = (1<<PIN_RL3); // Pin 3 over R_L to VCC, Pin 2 over R_L to GND #ifdef TEST_SLEEP_MODE sleep_5ms(2); // test of timing of sleep mode call #else wait10ms(); // normal delay #endif wdt_reset(); } /* end for ff50 */ if (!(RST_PIN_REG & (1<<RST_PIN))) { // if key is pressed, don't repeat break; } } /* end for ww */ #endif /* end FREQUENCY_50HZ */ lcd_clear(); lcd_MEM_string(VERSION_str); //"Version ..." lcd_line2(); lcd_MEM_string(ATE); //"Selftest End" PartFound = PART_NONE; last_line_used = 2; wait_for_key_5s_line2(); // wait up to 5 seconds and clear line 2 } /* end AutoCheck */
//================================================================= void GetVloss() { #if FLASHEND > 0x1fff // measure voltage drop after load pulse unsigned int tmpint; unsigned int adcv[4]; union t_combi{ unsigned long dw; // capacity value in 100nF units uint16_t w[2]; } lval; uint8_t ii; uint8_t HiPinR_L; uint8_t LoADC; if (cap.v_loss > 0) { return; // Voltage loss is already known (big Capacitor) } #if (((PIN_RL1 + 1) != PIN_RH1) || ((PIN_RL2 + 1) != PIN_RH2) || ((PIN_RL3 + 1) != PIN_RH3)) LoADC = pgm_read_byte((&PinRLRHADCtab[6])+cap.ca-TP_MIN) | TXD_MSK; #else LoADC = pgm_read_byte((&PinRLRHADCtab[3])+cap.ca-TP_MIN) | TXD_MSK; #endif HiPinR_L = pgm_read_byte(&PinRLRHADCtab[cap.cb-TP_MIN]); //R_L mask for HighPin R_L load EntladePins(); // discharge capacitor ADC_PORT = TXD_VAL; // switch ADC-Port to GND R_PORT = 0; // switch R-Port to GND ADC_DDR = LoADC; // switch Low-Pin to output (GND) R_DDR = HiPinR_L; // switch R_L port for HighPin to output (GND) adcv[0] = ReadADC(cap.cb); // voltage before any load // ******** should adcv[0] be measured without current??? if ((cap.cpre_max > -9) || (cap.cpre_max < -12)) return; // too much or too less capacity lval.dw = cap.cval_max; for (ii=cap.cpre_max+15;ii<7;ii++) { lval.dw = (lval.dw + 5) / 10; } if (lval.dw > 5000) { /* capacity more than 50uF, Voltage loss is already measured */ return; } if (lval.w[0] < 5) return; // Capacity below 5nF R_PORT = HiPinR_L; //R_L to 1 (VCC) R_DDR = HiPinR_L; //switch Pin to output, across R to GND or VCC for (tmpint=0;tmpint<lval.w[0];tmpint+=2) { // wait50us(); // wait exactly 50us wait5us(); // wait exactly 5us } R_DDR = 0; // switch back to input R_PORT = 0; // no Pull up // wait10us(); //wait a little time wdt_reset(); // read voltage without current ADCconfig.Samples = 5; // set ADC to only 5 samples adcv[2] = ReadADC(cap.cb); if (adcv[2] > adcv[0]) { adcv[2] -= adcv[0]; //difference to beginning voltage } else { adcv[2] = 0; // voltage is lower or same as beginning voltage } // wait 2x the time which was required for loading for (tmpint=0;tmpint<lval.w[0];tmpint++) { // wait50us(); wait5us(); } adcv[3] = ReadADC(cap.cb); // read voltage again, is discharged only a little bit ? ADCconfig.Samples = ANZ_MESS; // set ADC back to configured No. of samples wdt_reset(); if (adcv[3] > adcv[0]) { adcv[3] -= adcv[0]; // difference to beginning voltage } else { adcv[3] = 0; // voltage is lower or same as beginning voltage } if (adcv[2] > adcv[3]) { // build difference to load voltage adcv[1] = adcv[2] - adcv[3]; // lost voltage during load time wait } else { adcv[1] = 0; // no lost voltage } // compute voltage drop as part from loaded voltage if (adcv[1] > 0) { // there is any voltage drop (adcv[1]) ! // adcv[2] is the loaded voltage. cap.v_loss = (unsigned long)(adcv[1] * 500UL) / adcv[2]; } #if 0 lcd_line3(); DisplayValue16(adcv[2],0,' ',4); DisplayValue16(adcv[1],0,' ',4); lcd_line4(); DisplayValue16(lval.w[0],0,'x',4); #endif // discharge capacitor again EntladePins(); // discharge capacitors //ready // switch all ports to input ADC_DDR = TXD_MSK; // switch all ADC ports to input ADC_PORT = TXD_VAL; // switch all ADC outputs to GND, no pull up R_DDR = 0; // switch all resistor ports to input R_PORT = 0; // switch all resistor outputs to GND, no pull up #endif return; } // end GetVloss()
// first discharge any charge of capacitors void EntladePins() { uint8_t adc_gnd; // Mask of ADC-outputs, which can be directly connected to GND unsigned int adcmv[3]; // voltages of 3 Pins in mV unsigned int clr_cnt; // Clear Counter uint8_t lop_cnt; // loop counter // max. time of discharge in ms (10000/20) == 10s #define MAX_ENTLADE_ZEIT (10000/20) for(lop_cnt=0;lop_cnt<10;lop_cnt++) { adc_gnd = TXD_MSK; // put all ADC to Input ADC_DDR = adc_gnd; ADC_PORT = TXD_VAL; // ADC-outputs auf 0 R_PORT = 0; // R-outputs auf 0 // R_DDR = (1<<PIN_RH3) | (1<<PIN_RH2) | (1<<PIN_RH1); // R_H for all Pins to GND R_DDR = (1<<PIN_RH3) | (1<<PIN_RL3) | (1<<PIN_RH2) | (1<<PIN_RL2) | (1<<PIN_RH1) | (1<<PIN_RL1); // R_H and R_L for all Pins to GND adcmv[0] = W5msReadADC(PC0); // which voltage has Pin 1? adcmv[1] = ReadADC(PC1); // which voltage has Pin 2? adcmv[2] = ReadADC(PC2); // which voltage has Pin 3? if ((PartFound == PART_CELL) || (adcmv[0] < CAP_EMPTY_LEVEL) & (adcmv[1] < CAP_EMPTY_LEVEL) & (adcmv[2] < CAP_EMPTY_LEVEL)) { ADC_DDR = TXD_MSK; // switch all ADC-Pins to input R_DDR = 0; // switch all R_L Ports (and R_H) to input #if FLASHEND > 0x3fff cell_mv[0] = adcmv[0]; // save the voltage of pin 1 cell_mv[1] = adcmv[1]; // save the voltage of pin 2 cell_mv[2] = adcmv[2]; // save the voltage of pin 3 #endif return; // all is discharged } // all Pins with voltage lower than 1V can be connected directly to GND (ADC-Port) if (adcmv[0] < 1000) { adc_gnd |= (1<<PC0); //Pin 1 directly to GND } if (adcmv[1] < 1000) { adc_gnd |= (1<<PC1); //Pin 2 directly to GND } if (adcmv[2] < 1000) { adc_gnd |= (1<<PC2); //Pin 3 directly to GND } ADC_DDR = adc_gnd; // switch all selected ADC-Ports at the same time // additionally switch the leaving Ports with R_L to GND. // since there is no disadvantage for the already directly switched pins, we can // simply switch all R_L resistors to GND // R_DDR = (1<<PIN_RL3) | (1<<PIN_RL2) | (1<<PIN_RL1); // Pins across R_L resistors to GND for(clr_cnt=0;clr_cnt<MAX_ENTLADE_ZEIT;clr_cnt++) { wdt_reset(); adcmv[0] = W20msReadADC(PC0); // which voltage has Pin 1? adcmv[1] = ReadADC(PC1); // which voltage has Pin 2? adcmv[2] = ReadADC(PC2); // which voltage has Pin 3? if (adcmv[0] < 1300) { ADC_DDR |= (1<<PC0); // below 1.3V , switch directly with ADC-Port to GND } if (adcmv[1] < 1300) { ADC_DDR |= (1<<PC1); // below 1.3V, switch directly with ADC-Port to GND } if (adcmv[2] < 1300) { ADC_DDR |= (1<<PC2); // below 1.3V, switch directly with ADC-Port to GND } if ((adcmv[0] < (CAP_EMPTY_LEVEL+2)) && (adcmv[1] < (CAP_EMPTY_LEVEL+2)) && (adcmv[2] < (CAP_EMPTY_LEVEL+2))) { break; } } if (clr_cnt == MAX_ENTLADE_ZEIT) { PartFound = PART_CELL; // mark as Battery // there is charge on capacitor, warn later! } #if DebugOut == 99 lcd_line4(); u2lcd(adcmv[0]; // lcd_string(utoa(adcmv[0], outval, 10)); lcd_space(); u2lcd(adcmv[1]; // lcd_string(utoa(adcmv[1], outval, 10)); lcd_space(); u2lcd(adcmv[2]; // lcd_string(utoa(adcmv[2], outval, 10)); #endif for(adcmv[0]=0;adcmv[0]<clr_cnt;adcmv[0]++) { // for safety, discharge 5% of discharge time wait1ms(); } } // end for lop_cnt }
void ShowData(void) { #ifdef WITH_ROTARY_SWITCH show_page_1: #endif lcd_clear(); lcd_MEM2_string(VERSION_str); // "Version x.xxk" lcd_line2(); lcd_MEM2_string(R0_str); // "R0=" DisplayValue(eeprom_read_byte(&EE_ESR_ZEROtab[2]),-2,' ',3); DisplayValue(eeprom_read_byte(&EE_ESR_ZEROtab[3]),-2,' ',3); DisplayValue(eeprom_read_byte(&EE_ESR_ZEROtab[1]),-2,LCD_CHAR_OMEGA,3); #ifdef FOUR_LINE_LCD lcd_line3(); #else wait_for_key_ms(MIDDLE_WAIT_TIME); #ifdef WITH_ROTARY_SWITCH if (rotary.incre > FAST_ROTATION) return; // fast rotation ends the function if (rotary.count < 0) goto show_page_1; show_page_2: #endif lcd_clear(); #endif /* output line 3 */ lcd_MEM_string(RIHI); // "RiHi=" DisplayValue(RRpinPL,-1,LCD_CHAR_OMEGA,3); #ifdef FOUR_LINE_LCD lcd_line4(); #else lcd_line2(); #endif /* output line 4 */ lcd_MEM_string(RILO); // "RiLo=" DisplayValue(RRpinMI,-1,LCD_CHAR_OMEGA,3); wait_for_key_ms(MIDDLE_WAIT_TIME); #ifdef WITH_ROTARY_SWITCH if (rotary.incre > FAST_ROTATION) return; // fast rotation ends the function #ifdef FOUR_LINE_LCD if (rotary.count < 0) goto show_page_1; #else if (rotary.count < -1) goto show_page_1; if (rotary.count < 0) goto show_page_2; #endif show_page_3: #endif lcd_clear(); lcd_MEM_string(C0_str); //output "C0 " DisplayValue(eeprom_read_byte(&c_zero_tab[5]),0,' ',3); //output cap0 1:3 DisplayValue(eeprom_read_byte(&c_zero_tab[6]),0,' ',3); //output cap0 2:3 DisplayValue(eeprom_read_byte(&c_zero_tab[2]),-12,'F',3); //output cap0 1:2 lcd_line2(); lcd_space(); lcd_space(); lcd_space(); DisplayValue(eeprom_read_byte(&c_zero_tab[1]),0,' ',3); //output cap0 3:1 DisplayValue(eeprom_read_byte(&c_zero_tab[4]),0,' ',3); //output cap0 3:2 DisplayValue(eeprom_read_byte(&c_zero_tab[0]),-12,'F',3); //output cap0 2:1 #ifdef FOUR_LINE_LCD lcd_line3(); #else wait_for_key_ms(MIDDLE_WAIT_TIME); #ifdef WITH_ROTARY_SWITCH if (rotary.incre > FAST_ROTATION) return; // fast rotation ends the function if (rotary.count < -2) goto show_page_1; if (rotary.count < -1) goto show_page_2; if (rotary.count < 0) goto show_page_3; show_page_4: #endif lcd_clear(); #endif /* output line 7 */ lcd_MEM2_string(REF_C_str); // "REF_C=" i2lcd((int16_t)eeprom_read_word((uint16_t *)(&ref_offset))); #ifdef FOUR_LINE_LCD lcd_line4(); #else lcd_line2(); #endif /* output line 8 */ lcd_MEM2_string(REF_R_str); // "REF_R=" i2lcd((int8_t)eeprom_read_byte((uint8_t *)(&RefDiff))); wait_for_key_ms(MIDDLE_WAIT_TIME); #ifdef WITH_ROTARY_SWITCH if (rotary.incre > FAST_ROTATION) return; // fast rotation ends the function #ifdef FOUR_LINE_LCD if (rotary.count < -1) goto show_page_1; if (rotary.count < 0) goto show_page_3; #else if (rotary.count < -3) goto show_page_1; if (rotary.count < -2) goto show_page_2; if (rotary.count < -1) goto show_page_3; if (rotary.count < 0) goto show_page_4; #endif #endif }