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 }
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 }
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() */
/* ****************************************************************** */ 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() */
/* ****************************************************************** */ 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 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 */
/* *************************************************** */ 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 */
/* *************************************************** */ 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() */
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 }
/* *************************************************** */ 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 */
/* ****************************************************************** */ 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() */
/* ****************************************************************** */ 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()
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()
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()