예제 #1
0
void set_big_cap_corr(void) {
uint8_t key_pressed;
int8_t korr;
  // set the contrast value
  message_key_released(SetCapCorr_str);	// display Capacity correction and wait for key released
  korr = eeprom_read_byte((uint8_t *)&big_cap_corr);
  #ifdef POWER_OFF
  uint8_t times;
  for (times=0;times<240;)
  #else
  while (1)                     /* wait endless without option POWER_OFF */
  #endif
  {
     lcd_line2();
     if (korr < 0) {
       lcd_data('-');
       DisplayValue16(-korr,-1,'%',3);
     } else {
       DisplayValue16(korr,-1,'%',3);
     }
     lcd_clear_line();		// clear to end of line
     key_pressed = wait_for_key_ms(1600);
#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
     if(key_pressed >= 130) break;	// more than 1.3 seconds
#ifdef WITH_ROTARY_SWITCH
     if (rotary.incre > FAST_ROTATION) break;		// fast rotation ends setting of korr
     korr += rotary.count;		// increase or decrease the korr by rotary.count
#endif
     if (key_pressed > 0) {
        if (key_pressed > 40) {
           korr++; // longer key press select higher korr value
        } else {
           korr--;	// decrease the korr 
        }
     }
     if (korr > MAX_KORR) korr -= (MAX_KORR - MIN_KORR + 1);
     if (korr < MIN_KORR) korr += (MAX_KORR - MIN_KORR + 1);
#ifdef POWER_OFF
     times = Pwr_mode_check(times);	// no time limit with DC_Pwr_mode
#endif
  } /* end for times */

  eeprom_write_byte((uint8_t *)(&big_cap_corr), (int8_t)korr);	// save korr value
}
예제 #2
0
void set_contrast(void) {
uint8_t key_pressed;
uint8_t contrast;
  // set the contrast value
  message_key_released(CONTRAST_str);	// display Contrast and wait for key released
  contrast = eeprom_read_byte(&EE_Volume_Value);
  #ifdef POWER_OFF
  uint8_t times;
  for (times=0;times<240;times++)
  #else
  while (1)                     /* wait endless without option POWER_OFF */
  #endif
  {
     lcd_command(CMD_SET_VOLUME_FIRST);		// 0x81 set  volume command
     lcd_command(contrast);			// value from 1 to 63 (0x3f) */
     lcd_line2();
     lcd_clear_line();
     lcd_line2();
     DisplayValue(contrast,0,' ',4);
     key_pressed = wait_for_key_ms(1600);
#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
     if(key_pressed >= 130) break;	// more than 1.3 seconds
#ifdef WITH_ROTARY_SWITCH
     if (rotary.incre > FAST_ROTATION) break;		// fast rotation ends setting of contrast
     if (rotary.count >= 0) {
        contrast += rotary.count;		// increase the contrast by rotary.count
     } else {
        contrast += (MAX_CONTRAST + 1 + rotary.count);	// decrease the contrast by rotary.count
     }
#endif
     if (key_pressed > 0) {
        if (key_pressed > 40) {
           contrast++; // longer key press select higher contrast value
        } else {
           contrast += MAX_CONTRAST;	// decrease the contrast 
        }
     }
     contrast &= MAX_CONTRAST;
  } /* end for times */

  eeprom_write_byte((uint8_t *)(&EE_Volume_Value), (int8_t)contrast);	// save contrast value
}
예제 #3
0
void show_Resis13(void) {
  uint8_t key_pressed;
  message_key_released(RESIS_13_str);	// "1-|=|-3 .."
#ifndef RMETER_WITH_L
  lcd_set_cursor(0,6);
  lcd_MEM_string(RL_METER_str);	// " [R]" or "[RL]"
#endif
#ifdef POWER_OFF
  uint8_t times;
  for (times=0;times<250;) 
 #else
  while (1)		/* wait endless without the POWER_OFF option */
 #endif
  {
        init_parts();		// set all parts to nothing found 
        GetResistance(TP3, TP1);
        GetResistance(TP1, TP3);
	lcd_line1();		// lcd_set_cursor(0,0);
        if (ResistorsFound != 0) {
           show_resis(TP1,TP3,1);
        } else {		/* no resistor found */
 #ifdef RMETER_WITH_L
           lcd_MEM_string(RESIS_13_str);
           lcd_MEM_string(RL_METER_str+4);	// " [R]" or "[RL]"
 #endif
           lcd_line2();
           lcd_data('?');		// too big
 #if LCD_LINES>2
           lcd_next_line(0);
 #endif
           lcd_clear_line();
        }
 #if defined(POWER_OFF) && defined(BAT_CHECK)
     Bat_update(times);
 #endif
     key_pressed = wait_for_key_ms(1000);
 #ifdef WITH_ROTARY_SWITCH
     if ((key_pressed != 0) || (rotary.incre > 3)) break;
 #else
     if (key_pressed != 0) break;
 #endif
 #if defined(POWER_OFF)
     times = Pwr_mode_check(times);	// no time limit with DC_Pwr_mode
 #endif
  }  /* end for times */
  lcd_clear();
} /* end show_Resis13() */
예제 #4
0
/* ****************************************************************** */
void show_C_ESR() {
  uint8_t key_pressed;
  message_key_released(C_ESR_str);
#ifdef POWER_OFF
  uint8_t times;
  for (times=0;times<250;times++) 
#else
  while (1)		/* wait endless without the POWER_OFF option */
#endif
  {
        PartFound = PART_NONE;
        ReadBigCap(TP3,TP1);
        if (PartFound == PART_CAPACITOR) {
           lcd_line1();		// clear old capacity value 
           lcd_clear_line();
           lcd_line1();
           lcd_data('C');
           lcd_data('=');
           DisplayValue(cap.cval_max,cap.cpre_max,'F',3);
           cap.esr = GetESR(cap.cb,cap.ca);
           lcd_line2();		// clear old ESR value 
           lcd_clear_line();
           lcd_line2();
           lcd_MEM_string(&ESR_str[1]);
           if (cap.esr < 65530) {
              DisplayValue(cap.esr,-2,LCD_CHAR_OMEGA,2);
           } else {
              lcd_data('?');		// too big
           }
        } else {
           lcd_clear();
           lcd_MEM2_string(C_ESR_str);
        }
     key_pressed = wait_for_key_ms(1000);
#ifdef WITH_ROTARY_SWITCH
     if ((key_pressed != 0) || (rotary.incre > 3)) break;
#else
     if (key_pressed != 0) break;
#endif
  }  /* end for times */
} /* end show_C_ESR() */
예제 #5
0
/* ****************************************************************** */
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()
예제 #6
0
/* *************************************************** */
void do_10bit_PWM() {
  uint8_t key_pressed;
  uint8_t percent;		// requestet duty-cycle in %
  uint8_t old_perc;		// old duty-cycle in %
  unsigned int pwm_flip;	// value for counter to flip the state
  message_key_released(PWM_10bit_str);	// display PWM-Generator and wait for key released
  // OC1B is connected with 680 Ohm resistor to TP2 (middle test pin) 
  TCCR1A = (1<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (1<<WGM10); // fast PWM mode, count to 10 bit
  TIMSK1 = 0;		// no interrupt used
  OCR1A = 1;		// highest frequency
  OCR1B	= 0xff;		// toggle OC1B at this count
  TIFR1 = (1<<OCF1A) | (1<<OCF1A) | (1<<TOV1);	// reset interrupt flags
  TCCR1C = 0;

  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
  key_pressed = 0;
  old_perc = 0;
  percent = 10;
#ifdef POWER_OFF
  uint8_t times;		// time limit
  for (times=0; times<240; times++) 
#else
  while (1)			/* wait endless without option POWER_OFF */
#endif
  {
     if (percent != old_perc) {
        // new duty cycle is requested
        if (percent >= 100) {
           percent -= 100;		//reset to 0 percent or higher
        }
        pwm_flip = (((unsigned long)0x3ff * percent) + 50) / 100;
        OCR1B = pwm_flip;		// new percentage
        lcd_line2();		// set cursor to begin of line 2
        lcd_clear_line();	// clear line 2
        lcd_line2();		// set cursor to row 1 of line 2
        DisplayValue((((unsigned long)pwm_flip * 1000) + 0x1ff) / 0x3ff,-1,'%',5);
#if 0
        lcd_space();
        if (rotary.count >= 0) {	// actual count for debugging
           lcd_data('+');
           lcd_data('0'+rotary.count);
        } else {
           lcd_data('-');
           lcd_data('0'-rotary.count);
        }
        lcd_line3();
        uint8_t kk;
        kk = (rotary.ind + 1) & ROT_MSK;
        do {
           lcd_data('0'+rotary.state[kk]);	// debugging output of rotary state
           kk = (kk + 1) & ROT_MSK;
        } while (kk != rotary.ind);
#endif
        old_perc = percent;	// update the old duty cycle
        if (key_pressed > 40) {
           wait_about300ms();	// wait some time to release the button
        }
     } /* end if percent != old_perc */
     key_pressed = wait_for_key_ms(1600);
     if(key_pressed > 130) break;	// more than 1.3 seconds
#ifdef WITH_ROTARY_SWITCH
     if (rotary.incre > FAST_ROTATION) break;		// fast rotation ends voltage measurement
     if (rotary.count >= 0) {
        percent += rotary.count;		// increase the duty cycle by rotary.count
     } else {
        percent += (100 + rotary.count);	// decrease the duty cycle by rotary.count
     }
#endif
     if (key_pressed > 50) {
        percent += 10;		// duty cycle will be increased with 10
     } else {
        if (key_pressed > 0) percent += 1;	// duty cycle will be increased with 1
     }
#ifdef POWER_OFF
 #ifdef WITH_ROTARY_SWITCH
     if ((key_pressed > 0) || (rotary.incre > 0)) times = 0;	// reset the loop counter, operator is active
 #else
     if (key_pressed > 0) times = 0;		//reset the loop counter, operator is active
 #endif
#endif
  } /* end for times */

  ADC_DDR =  TXD_MSK;	// disconnect TP1 
  TCCR1B = 0;		// stop counter
  TCCR1A = 0;		// stop counter
  R_DDR = 0;		// switch resistor ports to Input
  DDRB  &= ~(1<<DDB2);	// disable output 
} /* end do_10bit_PWM */
예제 #7
0
/* *************************************************** */
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 */
예제 #8
0
/* *************************************************** */
void show_vext() {
 #ifdef WITH_VEXT
 
  uint8_t key_pressed;
  uint8_t key_long_pressed;
  unsigned int Vext;
  // show the external voltage
  message_key_released(VOLTAGE_str);
  key_long_pressed = 0;
#ifdef POWER_OFF
  uint8_t times;
  for (times=0;times<240;times++) 
#else
  while (1)			/* wait endless without option POWER_OFF */
#endif
  {
#ifdef TPex2
     lcd_line1();		// 2 Vext measurements 
     lcd_clear_line();
     lcd_line1();
#else
     lcd_line2();		// only one measurement use line 2
     lcd_clear_line();
     lcd_line2();
#endif	/* TPex2 */
#ifdef WITH_UART
     uart_newline();          // start of new measurement
     uart_newline();          // start of new measurement
#endif
     lcd_MEM_string(Vext_str);          // Vext=
     Vext = W5msReadADC(TPext); // read external voltage 
//     ADC_DDR = TXD_MSK;               //activate Software-UART 
  #if EXT_NUMERATOR <= (0xffff/U_VCC)
     DisplayValue(Vext*EXT_NUMERATOR/EXT_DENOMINATOR,-3,'V',3); // Display 3 Digits of this mV units
  #else
     DisplayValue((unsigned long)Vext*EXT_NUMERATOR/EXT_DENOMINATOR,-3,'V',3);  // Display 3 Digits of this mV units
  #endif

#ifdef TPex2
     lcd_line2();
     lcd_clear_line();
     lcd_line2();
#ifdef WITH_UART
     uart_newline();          // start of new measurement
#endif
     lcd_MEM_string(Vext_str);          // Vext=
     Vext = W5msReadADC(TPext); // read external voltage 
  #if EXT_NUMERATOR <= (0xffff/U_VCC)
     DisplayValue(Vext*EXT_NUMERATOR/EXT_DENOMINATOR,-3,'V',3); // Display 3 Digits of this mV units
  #else
     DisplayValue((unsigned long)Vext*EXT_NUMERATOR/EXT_DENOMINATOR,-3,'V',3);  // Display 3 Digits of this mV units
  #endif
#endif	/* TPex2 */

     key_pressed = wait_for_key_ms(1000);
#ifdef POWER_OFF
 #ifdef WITH_ROTARY_SWITCH
     if ((key_pressed > 0) || (rotary.incre > 0)) times = 0;	// reset the loop counter, operator is active
     if (rotary.incre > 5) break;		// fast rotation ends voltage measurement
 #else
     if (key_pressed > 0) times = 0;		//reset the loop counter, operator is active
 #endif
#endif
     if (key_pressed > ((1000/10)-6)) {
        key_long_pressed++;	// count the long key press
     }
     if (key_pressed == 0) key_long_pressed = 0; //reset the key long pressed counter
     if (key_long_pressed > 4) break;	// five seconds end the loop
  }  /* end for times */
 #endif  /* WITH_VEXT */
} /* end show_vext() */
예제 #9
0
void set_contrast(void) {
uint8_t key_pressed;
uint8_t contrast;
  // set the contrast value
  message_key_released(CONTRAST_str);	// display Contrast and wait for key released
  contrast = eeprom_read_byte(&EE_Volume_Value);
  #ifdef POWER_OFF
  uint8_t times;
  for (times=0;times<240;)
  #else
  while (1)                     /* wait endless without option POWER_OFF */
  #endif
  {
  #if ((LCD_ST_TYPE == 7565) || (LCD_ST_TYPE == 1306))
     lcd_command(CMD_SET_VOLUME_FIRST);		// 0x81 set  volume command
     lcd_command(contrast);			// value from 1 to 63 (0x3f) */
  #elif (LCD_ST_TYPE == 8812)	/* PCF8812 controller */
     lcd_command(CMD_SET_EXTENDED_INSTRUCTION);		// set extended instruction mode
     lcd_command(ECMD_SET_CONTRAST | (contrast & 0x7f));	// set the contrast value
     lcd_command(CMD_SET_NORMAL_INSTRUCTION);		// return to normal instruction mode
  #elif (LCD_ST_TYPE == 8814)	/* PCF8814 controller */
   lcd_command(CMD_SET_VOP_UPPER | ((contrast >> 5) & 0x07));      // set upper Vop
   lcd_command(CMD_SET_VOP_LOWER | (contrast & 0x1f));    // set lower Vop
  #else		/* DOGM display */
     lcd_command(CMD_SetIFOptions | MODE_8BIT | 0x09);	// 2-line / IS=1
     lcd_command(CMD1_PowerControl | ((contrast>>4)&0x07));	// booster on,off / set contrast C5:C4 
     lcd_command(CMD1_SetContrast | (contrast&0x0f));	// set contrast C3:0 
     lcd_command(CMD_SetIFOptions | MODE_8BIT | 0x08);	// 2-line / IS=0
  #endif
     lcd_line2();
     DisplayValue16(contrast,0,' ',4);
     lcd_clear_line();		// clear to end of line
     key_pressed = wait_for_key_ms(1600);
#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
     if(key_pressed >= 130) break;	// more than 1.3 seconds
#ifdef WITH_ROTARY_SWITCH
     if (rotary.incre > FAST_ROTATION) break;		// fast rotation ends setting of contrast
     if (rotary.count >= 0) {
        contrast += rotary.count;		// increase the contrast by rotary.count
     } else {
        contrast += (MAX_CONTRAST + 1 + rotary.count);	// decrease the contrast by rotary.count
     }
#endif
     if (key_pressed > 0) {
        if (key_pressed > 40) {
           contrast++; // longer key press select higher contrast value
        } else {
           contrast += MAX_CONTRAST;	// decrease the contrast 
        }
     }
     contrast &= MAX_CONTRAST;
#ifdef POWER_OFF
     times = Pwr_mode_check(times);	// no time limit with DC_Pwr_mode
#endif
  } /* end for times */

  eeprom_write_byte((uint8_t *)(&EE_Volume_Value), (int8_t)contrast);	// save contrast value
}
예제 #10
0
/* *************************************************** */
void do_10bit_PWM() {
  uint8_t key_pressed;
  uint8_t percent;		// requestet duty-cycle in %
  uint8_t old_perc;		// old duty-cycle in %
  unsigned int pwm_flip;	// value for counter to flip the state
  message_key_released(PWM_10bit_str);	// display PWM-Generator and wait for key released
  // OC1B is connected with 680 Ohm resistor to TP2 (middle test pin) 
  TCCR1A = (1<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (1<<WGM10); // fast PWM mode, mode 7: count to 10 bit
  TIMSK1 = 0;		// no interrupt used
  OCR1B	= 0xff;		// toggle OC1B at this count
  TIFR1 = (1<<OCF1A) | (1<<OCF1A) | (1<<TOV1);	// reset interrupt flags
  TCCR1C = 0;

  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
#if PROCESSOR_TYP == 1280
  DDRB  |= (1<<DDB6);	// set output enable for OC1B
#else
  DDRB  |= (1<<DDB2);	// set output enable
#endif
#ifdef PWM_SERVO
  TCCR1B = (1<<WGM13) | (1<<WGM12) | SERVO_START; // mode 15, clock divide by 8 or 64
  OCR1A = PWM_MAX_COUNT - 1;	// clock tics for 20 ms
#else
  OCR1A = 1;		// highest frequency
  TCCR1B = (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10); // mode 7, no clock divide
#endif
  key_pressed = 0;
  old_perc = 0;
  percent = (SERVO_MAX + SERVO_MIN) / 2;	// set to middle
#ifdef POWER_OFF
  uint8_t times;		// time limit
  for (times=0; times<240; ) 
#else
  while (1)			/* wait endless without option POWER_OFF */
#endif
  {
     if (percent != old_perc) {
        // new duty cycle is requested
        if (percent >= SERVO_MAX) {
	   percent -= (SERVO_MAX - SERVO_MIN);		// reset near to mininum value
        }
#ifdef PWM_SERVO
        pwm_flip = (((unsigned long)PWM_MAX_COUNT * percent) + 500) / 1000;
#else
        pwm_flip = (((unsigned long)PWM_MAX_COUNT * percent) + 50) / 100;
#endif
        OCR1B = pwm_flip;		// new percentage
        lcd_line2();		// goto line 2
#ifdef PWM_SERVO
        DisplayValue(((unsigned long)pwm_flip * SERVO_DIV)/MHZ_CPU ,-6,'s',3);
	lcd_space();
	lcd_data('/');
	lcd_space();
	DisplayValue16(((unsigned long)PWM_MAX_COUNT * SERVO_DIV)/MHZ_CPU, -6,'s',3);
#else
        DisplayValue16((((unsigned long)pwm_flip * 1000) + (PWM_MAX_COUNT/2)) / PWM_MAX_COUNT,-1,'%',5);
#endif
        lcd_clear_line();
        old_perc = percent;	// update the old duty cycle
        if (key_pressed > 40) {
           wait_about300ms();	// wait some time to release the button
        }
     } /* end if percent != old_perc */
     key_pressed = wait_for_key_ms(1600);
     if(key_pressed > 130) break;	// more than 1.3 seconds
#ifdef WITH_ROTARY_SWITCH
     if (rotary.incre > FAST_ROTATION) break;		// fast rotation ends voltage measurement
     if (rotary.count >= 0) {
        percent += rotary.count;		// increase the duty cycle by rotary.count
     } else {
        percent += ((SERVO_MAX-SERVO_MIN) + rotary.count);	// decrease the duty cycle by rotary.count
     }
#endif
     if (key_pressed > 50) {
        percent += 10;		// duty cycle will be increased with 10
     } else {
        if (key_pressed > 0) percent += 1;	// duty cycle will be increased with 1
     }
#ifdef POWER_OFF
 #ifdef WITH_ROTARY_SWITCH
     if ((key_pressed > 0) || (rotary.incre > 0)) times = 0;	// reset the loop counter, operator is active
 #else
     if (key_pressed > 0) times = 0;		//reset the loop counter, operator is active
 #endif
#endif
#ifdef POWER_OFF
     times = Pwr_mode_check(times);	// no time limit with DC_Pwr_mode
#endif
  } /* end for times */

  ADC_DDR =  TXD_MSK;	// disconnect TP1 
  TCCR1B = 0;		// stop counter
  TCCR1A = 0;		// stop counter
  R_DDR = 0;		// switch resistor ports to Input
#if PROCESSOR_TYP == 1280
  DDRB  &= ~(1<<DDB6);	// disable output 
#else
  DDRB  &= ~(1<<DDB2);	// disable output 
#endif
} /* end do_10bit_PWM */
예제 #11
0
/* ****************************************************************** */
void show_C_ESR() {
  uint8_t key_pressed;
  message_key_released(C_ESR_str);
#ifdef POWER_OFF
  uint8_t times;
  for (times=0;times<250;) 
#else
  while (1)		/* wait endless without the POWER_OFF option */
#endif
  {
        PartFound = PART_NONE;
        ReadBigCap(TP3,TP1);
        if (PartFound == PART_CAPACITOR) {
#if LCD_LINES > 2
           lcd_line2(); 	// set to line2 
#else
           lcd_line1(); 	// set to line1 
#endif
           lcd_data('C');
           lcd_equal();		// lcd_data('=');
           DisplayValue(cap.cval_max,cap.cpre_max,'F',3);
           lcd_clear_line();	// clear to end of line 1
           cap.esr = GetESR(cap.cb,cap.ca);
#if LCD_LINES > 2
	   lcd_line3();		// use line 3 
#else
           lcd_line2();		// use line 2 
#endif
           lcd_MEM_string(&ESR_str[1]);
           if (cap.esr < 65530) {
              DisplayValue16(cap.esr,-2,LCD_CHAR_OMEGA,2);
           } else {
              lcd_data('?');		// too big
           }
           lcd_clear_line();		// clear to end of line
        } else { // no cap found
#if LCD_LINES > 2
           lcd_clear_line2(); 	// clear C value 
           lcd_line3();
	   lcd_clear_line();	// clear old ESR value
#else
           lcd_line1();	//  
           lcd_MEM2_string(C_ESR_str);
           lcd_clear_line();
           lcd_clear_line2(); 	// clear old ESR value 
#endif
        }
#if defined(POWER_OFF) && defined(BAT_CHECK)
     Bat_update(times);
#endif
     key_pressed = wait_for_key_ms(1000);
#ifdef WITH_ROTARY_SWITCH
     if ((key_pressed != 0) || (rotary.incre > 3)) break;
#else
     if (key_pressed != 0) break;
#endif
#ifdef POWER_OFF
     times = Pwr_mode_check(times);	// no time limit with DC_Pwr_mode
#endif
  }  /* end for times */
} /* end show_C_ESR() */
예제 #12
0
/* ****************************************************************** */
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;
  message_key_released(SELECTION_str);
 #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);
#if (LCD_LINES > 3)
  uint8_t mm;
 #ifdef PAGE_MODE
     ff = 0;
     mm = 0;
     do {
	p_nr = page_nr + mm;
        if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1);
        if (func_number == p_nr) ff = 1;	// number is found
     } while (++mm < MENU_LINES);

     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
     }
     mm= 0;
     do {
        p_nr = page_nr + mm;
        if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1);
        lcd_set_cursor((mm+1)*PAGES_PER_LINE,0);
        if (func_number == p_nr) {
           lcd_data('>');
        } else {
           lcd_space();				// put a blank to 1. row of line 2
        }
        message2line(p_nr);			// show  page function
     } while (++mm < MENU_LINES);

 #else	/* no PAGE_MODE */
     uint8_t f_nr;
     mm = 0;
     do {
        lcd_set_cursor((mm+1)*PAGES_PER_LINE,0);
        if (mm == MENU_MIDDLE) {
           lcd_data('>');				// put a '>' marker to row 1 of line 4
        } else {
           lcd_space();				// put a blank to 1. row of line 2
        } 
        f_nr = func_number + MODE_LAST + 1 - MENU_MIDDLE + mm;
        if (f_nr > MODE_LAST) f_nr -= (MODE_LAST +1);
        message2line(f_nr);	// show function for this line
     } while (++mm < MENU_LINES);

 #endif         /* PAGE_MODE */
#else	/* not LCD_LINES > 3 */
     lcd_line2();
     message2line(func_number);
#endif /* (LCD_LINES > 3) */
#ifdef POWER_OFF
     ii = wait_for_key_ms(SHORT_WAIT_TIME);	// wait about 5 seconds
     if (ii > 0) ll = 0;			// reset timer, operator present
     if (DC_Pwr_mode == 1) ll = 0;
#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_RESIS) {
           show_Resis13();		// measure resistor at TP1 and TP3
        }
        if (func_number == MODE_CAP13) {
	   lcd_clear();
           show_Cap13();		// measure capacitor at TP1 and TP3
        }
        if (func_number == MODE_ROTARY) {
           CheckRotaryEncoder();		// check rotary encoder
        }
        if (func_number == MODE_BIG_CAP_CORR) {
           set_big_cap_corr();
        }
  #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) || (LCD_ST_TYPE == 1306) || (LCD_ST_TYPE == 8812) || (LCD_ST_TYPE == 8814) || defined(LCD_DOGM))
        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
        message_key_released(SELECTION_str);	//write Line 1 with Selection:
     } /* 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()
예제 #13
0
uint8_t 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;
  message_key_released(SELECTION_str);
 #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);
#if (LCD_LINES > 3)
  uint8_t mm;
#ifdef WITH_HARDWARE_SERIAL
     uart_newline();          // start of new measurement
     for (mm=0;mm<LCD_LINE_LENGTH;mm++) uart_putc('=');
     message_key_released(SELECTION_str);	//write Line 1 with Selection:
#endif
 #ifdef PAGE_MODE
     ff = 0;
     mm = 0;
     do {
	p_nr = page_nr + mm;
        if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1);
        if (func_number == p_nr) ff = 1;	// number is found
     } while (++mm < MENU_LINES);

     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
     }
     mm= 0;
     do {
        p_nr = page_nr + mm;
        if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1);
        lcd_set_cursor((mm+1)*PAGES_PER_LINE,0);
        if (func_number == p_nr) {
           lcd_data('>');
        } else {
           lcd_space();				// put a blank to 1. row of line 2
        }
        message2line(p_nr);			// show  page function
     } while (++mm < MENU_LINES);

 #else	/* no PAGE_MODE */
     uint8_t f_nr;
     mm = 0;
     do {
        lcd_set_cursor((mm+1)*PAGES_PER_LINE,0);
        if (mm == MENU_MIDDLE) {
           lcd_data('>');				// put a '>' marker to row 1 of line 4
        } else {
           lcd_space();				// put a blank to 1. row of line 2
        } 
        f_nr = func_number + MODE_LAST + 1 - MENU_MIDDLE + mm;
        if (f_nr > MODE_LAST) f_nr -= (MODE_LAST +1);
        message2line(f_nr);	// show function for this line
     } while (++mm < MENU_LINES);

 #endif         /* PAGE_MODE */
#else	/* not LCD_LINES > 3 */
     lcd_line2();
     message2line(func_number);
#endif /* (LCD_LINES > 3) */
#ifdef POWER_OFF
     ii = wait_for_key_ms(SHORT_WAIT_TIME);	// wait about 5 seconds
     if (ii > 0) ll = 0;			// reset timer, operator present
     if (DC_Pwr_mode == 1) ll = 0;
#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) return 0;		// return to TransistorTester
        do_menu(func_number);
        // 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
        message_key_released(SELECTION_str);	//write Line 1 with Selection:
     } /* 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 0;
 } // end function_menu()
예제 #14
0
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()