// initialize the XBee module void XBee_Init() { sendATCommand("X"); wait1ms(2980); sendATCommand("+++"); wait1ms(2980); sendATCommand("ATDL4F\r"); sendATCommand("ATDH0\r"); // Sets destination high address to 0 sendATCommand("ATMY4E\r"); // Sets my address to 78 sendATCommand("ATAP1\r"); // API mode 1 (sends/receive packets) sendATCommand("ATCN\r"); // Ends command mode }
//文字列をスクロール表示、構造体で方向および速度を設定する void lcd_scroll(SCROLL_FACTORY settings) { int i; for (;;) { //画面を塗りつぶす(残像防止) lcd_cursor(0, 0); for (i = 0; i < 32; i++) { lcd_printch(' '); if (i == 15) { lcd_cursor(0, 1); } } lcd_print_with_position(settings.string, settings.x, settings.y); //方向設定に従って座標を更新 settings.x += settings.direction; //改行の判断、座標の変更 if (settings.x >= 16 || settings.x < 0) { if (settings.y == 0) { settings.y = 1; } else { settings.y = 0; } if (settings.direction == LEFT) { settings.x = 15; } else { settings.x = 0; } } wait1ms(settings.speed); } }
// sends an AT command repeatedly until it receives // a reply that it was correctly received void sendATCommand(char *command) { SCIb_OutString(command); wait1ms(20); while(SCIb_InChar2() != 'O') { } while(SCIb_InChar2() != 'K') { } while(SCIb_InChar2() != '\r') { } }
void GetFrequency(uint8_t range) { unsigned char taste; // set if key is pressed during measurement #if PROCESSOR_TYP == 644 unsigned long freq_count; // the counted pulses in 1 second #endif unsigned long long ext_period; unsigned long freq_from_per; uint8_t ii; uint8_t mm; /* range has set the lowest bit to use the 16:1 frequency divider permanently. */ /* The upper bits of range specifies the input selection. */ /* 0 = external input, 2 = channel 2, 4 = HF Quartz, 6 = LF Quartz */ #if PROCESSOR_TYP == 644 FDIV_DDR |= (1<<FDIV_PIN); //switch to output if ((range & 0x01) == 0) { FDIV_PORT &= ~(1<<FDIV_PIN); // switch off the 16:1 divider } else { FDIV_PORT |= (1<<FDIV_PIN); // use frequency divider for next measurement } FINP_DDR |= (1<<FINP_P0) | (1<<FINP_P1); // switch both pins to output FINP_PORT &= ~(1<<FINP_P0); // clear lower bit of input selection FINP_PORT &= ~(1<<FINP_P1); // clear higher bit of input selection if (range == 0) { message_key_released(FREQ_str); // Frequency: in line 1 } else if (range == 1) { message_key_released(HFREQ_str); // High Frequency: in line 1 } else if (range < 4) { /* 2+3 */ FINP_PORT |= (1<<FINP_P0); // set lower bit of input selection FINP_PORT &= ~(1<<FINP_P1); // clear higher bit of input selection } else if (range < 6) { /* 4+5 */ FINP_PORT &= ~(1<<FINP_P0); // clear lower bit of input selection FINP_PORT |= (1<<FINP_P1); // set higher bit of input selection message_key_released(H_CRYSTAL_str); // HF Quarz: in line 1 } else { /* 6+7 */ FINP_PORT |= (1<<FINP_P0); // set lower bit of input selection FINP_PORT |= (1<<FINP_P1); // set higher bit of input selection message_key_released(L_CRYSTAL_str); // LF Quarz: in line 1 } #else message_key_released(FREQ_str); // Frequency: in line 1 #endif taste = 0; // reset flag for key pressed for (mm=0;mm<240;mm++) { // ************************************************************************* // *********** straight frequency measurement by counting 1 second ********* // ************************************************************************* //set up Counter 0 // Counter 0 is used to count the external signal connected to T0 (PD4 or PB0) FREQINP_DDR &= ~(1<<FREQINP_PIN); // switch frequency pin to input wait1ms(); // let capacitor time to load to 2.4V input #if PROCESSOR_TYP == 1280 TCCR3A = 0; // normal operation, no output TCNT3 = 0; // set counter 3 to zero ext_freq.dw = 0; // set external frequency to zero TIFR3 = (1<<TOV3); // clear OV interrupt of timer 3 TIMSK3 = (1<<TOIE3); // enable OV interrupt of timer 3 #else TCCR0A = 0; // normal operation, no output TCNT0 = 0; // set counter to zero ext_freq.dw = 0; // set external frequency to zero TIFR0 = (1<<TOV0); // clear OV interrupt of timer 0 TIMSK0 = (1<<TOIE0); // enable OV interrupt of timer 0 #endif // start counter after starting second counter timer 1 // set up counter 1 to measure one second TCCR1A = 0; // normal operation #define CNT1_END_VAL ((F_CPU / 256UL) + 1) #define CNT1_DIVIDER (1<<CS12) #if CNT1_END_VAL > 0xffff #undef CNT1_END_VAL #undef CNT1_DIVIDER #define CNT1_END_VAL ((F_CPU / 1024UL) + 1) #define CNT1_DIVIDER ((1<<CS12) | (1<<CS10)) #if F_CPU != ((F_CPU / 1024UL) * 1024UL) #warning F_CPU can not be divided by 1024, measured frequency is wrong! #endif #else #if F_CPU != ((F_CPU / 256UL) * 256UL) #warning F_CPU can not be divided by 256, measured frequency is wrong! #endif #endif OCR1B = CNT1_END_VAL; // set to 1 second (counter 0 is started with 1) OCR1A = 1; // start counter 0 with first count TCNT1 = 0; // set counter to zero GTCCR |= (1<<PSRSYNC); // reset clock precounter TIFR1 = (1<<OCF1B) | (1<<OCF1A); // clear Output compare match TIMSK1 = (1<<OCIE1B) | (1<<OCIE1A); // enable the Compare A match and Compare B match interrupt sei(); // set interrupt enable TCCR1B = CNT1_DIVIDER; // divide CPU clock by 256, start counter // both counter are running now, wait for counter 1 reach OCR1A for (ii=0;ii<50;ii++) { wait20ms(); // first count of counter 1 (<32us) has started the counter 0 wdt_reset(); if (!(RST_PIN_REG & (1<<RST_PIN))) taste = 1; // user request stop of operation #if PROCESSOR_TYP == 1280 if (TCCR3B == 0) break; // timer 3 is stopped by interrupt #else if (TCCR0B == 0) break; // timer 0 is stopped by interrupt #endif } // one second is counted #if PROCESSOR_TYP == 1280 TCCR3B = 0; // stop timer 3, if not stopped by timer 1 compare interrupt ext_freq.w[0] = TCNT3; // add lower 16 bit to get total counts #else TCCR0B = 0; // stop timer 0, if not stopped by timer 1 compare interrupt ext_freq.b[0] = TCNT0; // add lower 8 bit to get total counts #endif #if PROCESSOR_TYP == 644 freq_count = ext_freq.dw; // save the frequency counter #endif #if (LCD_LINES > 3) lcd_line3(); lcd_clear_line(); lcd_line4(); lcd_clear_line(); lcd_clear_line2(); #else lcd_clear(); // clear total display #endif lcd_data('f'); lcd_equal(); // lcd_data('='); #if PROCESSOR_TYP == 644 if ((FDIV_PORT&(1<<FDIV_PIN)) == 0) { Display_Hz(ext_freq.dw, 7); } else { // frequency divider is activ Display_Hz(ext_freq.dw*FREQ_DIV, 7); } #else Display_Hz(ext_freq.dw, 7); #endif #if PROCESSOR_TYP == 644 lcd_space(); if ((FDIV_PORT&(1<<FDIV_PIN)) != 0) { lcd_data('/'); // Frequency divider is activ } else { lcd_space(); // Frequency divider is not activ } #endif FREQINP_DDR &= ~(1<<FREQINP_PIN); // switch frequency pin to input if (TCCR1B != 0) { // Exact 1000ms period is only with "end of period" from timer1 interrupt. // When stopped with the for loop, the time is too long because wait call does not // respect CPU time used for interrupts and loop itself. // For this case show ? behind the Hz. lcd_data('?'); } TCCR1B = 0; // stop timer 1 TIMSK1 = 0; // disable all timer 1 interrupts if ((ext_freq.dw < FMAX_PERIOD) && (ext_freq.dw > 0)) { // ************************************************************************* // ******** Period measurement by counting some periods ******************** // ************************************************************************* pinchange_max = ((10 * (unsigned long)ext_freq.dw) + MHZ_CPU) / MHZ_CPU; // about 10000000 clock tics pinchange_max += pinchange_max; // * 2 for up and down change FREQINP_DDR &= ~(1<<FREQINP_PIN); // switch frequency pin to input wait1ms(); // let capacitor time to load to 2.4V input #if PROCESSOR_TYP == 1280 TCNT3 = 0; // set counter 3 to zero ext_freq.dw = 0; // reset counter to zero TIFR3 = (1<<TOV3); // clear OV interrupt TIMSK3 = (1<<TOIE3); // enable OV interrupt // counter 3 ist started with first pin change interrupt pinchange_count = 0; EICRB = (0<<ISC61) | (1<<ISC60); // set int6 pin change EIFR |= (1<<INTF6); // clear interrupt 6 flag PCMSK_FREQ |= (1<<PCINT_FREQ); // enable int6 #else TCNT0 = 0; // set counter 0 to zero ext_freq.dw = 0; // reset counter to zero TIFR0 = (1<<TOV0); // clear OV interrupt TIMSK0 = (1<<TOIE0); // enable OV interrupt // counter 0 ist started with first pin change interrupt pinchange_count = 0; PCIFR = (1<<PCI_CLEAR_BIT); // clear Pin Change Status PCICR |= (1<<PCI_ENABLE_BIT); // enable pin change interrupt #endif sei(); PCMSK_FREQ |= (1<<PCINT_FREQ); // monitor PD4 PCINT20 or PB0 PCINT8 pin change for (ii=0;ii<250;ii++) { wait20ms(); wdt_reset(); if (!(RST_PIN_REG & (1<<RST_PIN))) taste = 1; // user request stop of operation if ((PCMSK_FREQ & (1<<PCINT_FREQ)) == 0) break; // monitoring is disabled by interrupt } /* end for ii */ #if PROCESSOR_TYP == 1280 TCCR3B = 0; // stop counter 3 PCMSK_FREQ &= ~(1<<PCINT_FREQ); // disable int6 ext_freq.w[0] = TCNT3; // add lower 16 bit to get total counts #else TCCR0B = 0; // stop counter 0 PCMSK_FREQ &= ~(1<<PCINT_FREQ); // stop monitor PD4 PCINT20 or PB0 PCINT8 pin change PCICR &= ~(1<<PCI_ENABLE_BIT); // disable the interrupt ext_freq.b[0] = TCNT0; // add lower 8 bit to get total counts #endif // lcd_clear_line2(); // wait50ms(); // let LCD flicker to #if (LCD_LINES > 3) lcd_line3(); // use line3 to report the period with 4-line LCD #else lcd_line2(); // report period on line 2 of 2-line LCD #endif lcd_data('T'); lcd_equal(); // lcd_data('='); ext_period = ((unsigned long long)ext_freq.dw * (200000/MHZ_CPU)) / pinchange_max; #if PROCESSOR_TYP == 644 if ((FDIV_PORT&(1<<FDIV_PIN)) != 0) { // frequency divider is activ, period is measured too long ext_period = ext_period / FREQ_DIV; } #endif if (pinchange_max > 127) { DisplayValue(ext_period,-11,'s',7); // show period converted to 0.01ns units } else { //prevent overflow of 32-Bit DisplayValue((unsigned long)(ext_period/100),-9,'s',7); // show period converted to 1ns units } if (ii == 250) { lcd_data('?'); // wait loop has regular finished } else { if (ext_period > 249500) { #if (LCD_LINES > 3) lcd_line4(); // use line 4 of 4-line LCD to report the computed frequency #else lcd_line1(); // overwrite line 1 of 2-line LCD to report the computed frequency #endif lcd_data('f'); lcd_equal(); // lcd_data('='); if (ext_period > 1000000000) { // frequency in 0.000001Hz (1e11*1e6)/(0.01ns count) freq_from_per = (unsigned long long)(100000000000000000) / ext_period; DisplayValue(freq_from_per,-6,'H',7); // display with 0.000001 Hz resolution } else { // prevent unsigned long overflow, scale to 0.0001 Hz // frequency in 0.0001Hz (1e11*1e4)/(0.01ns count) freq_from_per = (unsigned long long)(1000000000000000) / ext_period; DisplayValue(freq_from_per,-4,'H',7); // display with 0.0001 Hz resolution } lcd_data('z'); FREQINP_DDR &= ~(1<<FREQINP_PIN); // switch frequency pin to input } } } /* end if 1 < ext_freq < FMAX_PERIOD */ #if PROCESSOR_TYP == 644 if ((FDIV_PORT & (1<<FDIV_PIN)) == 0) { // frequency divider is not activ if ( ((freq_count >= FMAX_PERIOD) && (freq_count < ((unsigned long)FMAX_PERIOD*FREQ_DIV))) || (freq_count > FMAX_INPUT) ){ FDIV_PORT |= (1<<FDIV_PIN); // use frequency divider for next measurement } } else { // frequency divider is activ if ((freq_count < (FMAX_PERIOD/FREQ_DIV)) && ((range & 0x01) == 0)) { FDIV_PORT &= ~(1<<FDIV_PIN); // switch off the 16:1 divider } } #endif // taste += wait_for_key_ms(SHORT_WAIT_TIME/2); TIMSK0 = 0; // disable all timer 0 interrupts taste += wait_for_key_ms(2000); #ifdef WITH_ROTARY_SWITCH if ((taste != 0) || (rotary.incre > 2)) break; #else if (taste != 0) break; #endif } /* end for mm */ return; } // end GetFrequency()
void ApplySubnet() { IINCHIP_WRITE(SUBR, ((uint16)Subnet[0]<<8)+(uint16)Subnet[1]); wait1ms(1); IINCHIP_WRITE(SUBR2,((uint16)Subnet[2]<<8)+(uint16)Subnet[3]); }
// first discharge any charge of capacitors void EntladePins() { uint8_t adc_gnd; // Mask of ADC-outputs, which can be directly connected to GND unsigned int adcmv[3]; // voltages of 3 Pins in mV unsigned int clr_cnt; // Clear Counter uint8_t lop_cnt; // loop counter // max. time of discharge in ms (10000/20) == 10s #define MAX_ENTLADE_ZEIT (10000/20) for(lop_cnt=0;lop_cnt<10;lop_cnt++) { adc_gnd = TXD_MSK; // put all ADC to Input ADC_DDR = adc_gnd; ADC_PORT = TXD_VAL; // ADC-outputs auf 0 R_PORT = 0; // R-outputs auf 0 // R_DDR = (1<<PIN_RH3) | (1<<PIN_RH2) | (1<<PIN_RH1); // R_H for all Pins to GND R_DDR = (1<<PIN_RH3) | (1<<PIN_RL3) | (1<<PIN_RH2) | (1<<PIN_RL2) | (1<<PIN_RH1) | (1<<PIN_RL1); // R_H and R_L for all Pins to GND adcmv[0] = W5msReadADC(PC0); // which voltage has Pin 1? adcmv[1] = ReadADC(PC1); // which voltage has Pin 2? adcmv[2] = ReadADC(PC2); // which voltage has Pin 3? if ((PartFound == PART_CELL) || (adcmv[0] < CAP_EMPTY_LEVEL) & (adcmv[1] < CAP_EMPTY_LEVEL) & (adcmv[2] < CAP_EMPTY_LEVEL)) { ADC_DDR = TXD_MSK; // switch all ADC-Pins to input R_DDR = 0; // switch all R_L Ports (and R_H) to input #if FLASHEND > 0x3fff cell_mv[0] = adcmv[0]; // save the voltage of pin 1 cell_mv[1] = adcmv[1]; // save the voltage of pin 2 cell_mv[2] = adcmv[2]; // save the voltage of pin 3 #endif return; // all is discharged } // all Pins with voltage lower than 1V can be connected directly to GND (ADC-Port) if (adcmv[0] < 1000) { adc_gnd |= (1<<PC0); //Pin 1 directly to GND } if (adcmv[1] < 1000) { adc_gnd |= (1<<PC1); //Pin 2 directly to GND } if (adcmv[2] < 1000) { adc_gnd |= (1<<PC2); //Pin 3 directly to GND } ADC_DDR = adc_gnd; // switch all selected ADC-Ports at the same time // additionally switch the leaving Ports with R_L to GND. // since there is no disadvantage for the already directly switched pins, we can // simply switch all R_L resistors to GND // R_DDR = (1<<PIN_RL3) | (1<<PIN_RL2) | (1<<PIN_RL1); // Pins across R_L resistors to GND for(clr_cnt=0;clr_cnt<MAX_ENTLADE_ZEIT;clr_cnt++) { wdt_reset(); adcmv[0] = W20msReadADC(PC0); // which voltage has Pin 1? adcmv[1] = ReadADC(PC1); // which voltage has Pin 2? adcmv[2] = ReadADC(PC2); // which voltage has Pin 3? if (adcmv[0] < 1300) { ADC_DDR |= (1<<PC0); // below 1.3V , switch directly with ADC-Port to GND } if (adcmv[1] < 1300) { ADC_DDR |= (1<<PC1); // below 1.3V, switch directly with ADC-Port to GND } if (adcmv[2] < 1300) { ADC_DDR |= (1<<PC2); // below 1.3V, switch directly with ADC-Port to GND } if ((adcmv[0] < (CAP_EMPTY_LEVEL+2)) && (adcmv[1] < (CAP_EMPTY_LEVEL+2)) && (adcmv[2] < (CAP_EMPTY_LEVEL+2))) { break; } } if (clr_cnt == MAX_ENTLADE_ZEIT) { PartFound = PART_CELL; // mark as Battery // there is charge on capacitor, warn later! } #if DebugOut == 99 lcd_line4(); u2lcd(adcmv[0]; // lcd_string(utoa(adcmv[0], outval, 10)); lcd_space(); u2lcd(adcmv[1]; // lcd_string(utoa(adcmv[1], outval, 10)); lcd_space(); u2lcd(adcmv[2]; // lcd_string(utoa(adcmv[2], outval, 10)); #endif for(adcmv[0]=0;adcmv[0]<clr_cnt;adcmv[0]++) { // for safety, discharge 5% of discharge time wait1ms(); } } // end for lop_cnt }