uc: increase sampling rate to 625Hz on ADC0 and ADC1. Use CTC for finetuning frequency.

This commit is contained in:
Bart Van Der Meerssche 2010-03-25 14:16:04 +00:00
parent 03eee97e37
commit 24d8104aac
3 changed files with 80 additions and 59 deletions

View File

@ -81,19 +81,20 @@ AVRDUDE_PROGRAMMER = usbtiny
MCU = atmega48 MCU = atmega48
F_CPU = 1000000 F_CPU = 1000000
# #
# Predefine the TYPE and SENSORx C macros in main.h via this Makefile. Override the # Predefine the TYPE and SENSORx C macros in main.h via this Makefile.
# defaults on the command line by typing: # Override the defaults on the command line by typing:
# make TYPE=xxxx SENSOR0=yyyy ... # make TYPE=xxxx SENSOR0=yyyy ...
# #
TYPE = 2301 DBG = 0
METERCONST = 7091 #
TYPE = 2300501
# #
SENSOR0 = 0123456789abcdef0123456789abcde0 SENSOR0 = 0123456789abcdef0123456789abcde0
SENSOR1 = 0123456789abcdef0123456789abcde1 SENSOR1 = 0123456789abcdef0123456789abcde1
SENSOR2 = 0123456789abcdef0123456789abcde2 SENSOR2 = 0123456789abcdef0123456789abcde2
SENSOR3 = 0123456789abcdef0123456789abcde3 SENSOR3 = 0123456789abcdef0123456789abcde3
# #
CEXTRA = -D TYPE=$(TYPE) -D METERCONST=$(METERCONST) -D POWERCONST=$(POWERCONST) -D 'SENSOR0="$(SENSOR0)"' -D 'SENSOR1="$(SENSOR1)"' -D 'SENSOR2="$(SENSOR2)"' -D 'SENSOR3="$(SENSOR3)"' CEXTRA = -D DBG=$(DBG) -D TYPE=$(TYPE) -D 'SENSOR0="$(SENSOR0)"' -D 'SENSOR1="$(SENSOR1)"' -D 'SENSOR2="$(SENSOR2)"' -D 'SENSOR3="$(SENSOR3)"'
##################################################################################### #####################################################################################
##################################################################################### #####################################################################################

View File

@ -73,43 +73,49 @@ ISR(PCINT2_vect) {
**/ **/
// interrupt service routine for ADC // interrupt service routine for ADC
ISR(TIMER2_OVF_vect) { ISR(TIMER2_COMPA_vect) {
#if DBG > 0
PORTD |= (1<<PD4);
#endif
// read ADC result // read ADC result
// add to nano(Wh) counter // add to nano(Wh) counter
if (muxn < 2) { MacU16X16to32(aux[muxn].nano, METERCONST, ADC);
MacU16X16to32(aux[muxn].nano, METERCONST, ADC);
if (aux[muxn].nano > WATT) { if (aux[muxn].nano > WATT) {
measurements[muxn].value++; measurements[muxn].value++;
aux[muxn].pulse = true; aux[muxn].pulse = true;
aux[muxn].nano -= WATT; aux[muxn].nano -= WATT;
aux[muxn].pulse_count++; aux[muxn].pulse_count++;
}
if (timer == SECOND) {
aux[muxn].nano_start = aux[muxn].nano_end;
aux[muxn].nano_end = aux[muxn].nano;
aux[muxn].pulse_count_final = aux[muxn].pulse_count;
aux[muxn].pulse_count = 0;
aux[muxn].power = true;
}
} }
// rotate the available ADC input channels (0 to 7) if (timer == SECOND) {
aux[muxn].nano_start = aux[muxn].nano_end;
aux[muxn].nano_end = aux[muxn].nano;
aux[muxn].pulse_count_final = aux[muxn].pulse_count;
aux[muxn].pulse_count = 0;
aux[muxn].power = true;
}
// cycle through the available ADC input channels (0 and 1)
muxn++; muxn++;
if (!(muxn &= 0x7)) timer++; if (!(muxn &= 0x1)) timer++;
if (timer > SECOND) timer = 0; if (timer > SECOND) timer = 0;
// but only use ADC0 and 1 ADMUX &= 0xF8;
if (muxn < 2) { ADMUX |= muxn;
ADMUX &= 0xF8; // start a new ADC conversion
ADMUX |= muxn; ADCSRA |= (1<<ADSC);
// start a new ADC conversion
ADCSRA |= (1<<ADSC);
}
}
#if DBG > 0
PORTD &= ~(1<<PD4);
#endif
#if DBG > 1
aux[muxn].nano = WATT+1;
timer = SECOND;
#endif
}
// interrupt service routine for analog comparator // interrupt service routine for analog comparator
ISR(ANALOG_COMP_vect) { ISR(ANALOG_COMP_vect) {
uint8_t i; uint8_t i;
@ -197,7 +203,10 @@ void setup()
// enable INT0 and INT1 interrupts // enable INT0 and INT1 interrupts
EIMSK = (1<<INT0) | (1<<INT1); EIMSK = (1<<INT0) | (1<<INT1);
#if DBG > 0
// re-use PD4 pin for tracing interrupt times
DDRD |= (1<<DDD4);
#else
// PD4=PCINT20 configuration // PD4=PCINT20 configuration
// set as input pin with 20k pull-up enabled // set as input pin with 20k pull-up enabled
PORTD |= (1<<PD4); PORTD |= (1<<PD4);
@ -205,6 +214,7 @@ void setup()
PCMSK2 |= (1<<PCINT20); PCMSK2 |= (1<<PCINT20);
//pin change interrupt enable 2 //pin change interrupt enable 2
PCICR |= (1<<PCIE2); PCICR |= (1<<PCIE2);
#endif
// analog comparator setup for brown-out detection // analog comparator setup for brown-out detection
// PD7=AIN1 configured by default as input to obtain high impedance // PD7=AIN1 configured by default as input to obtain high impedance
@ -216,10 +226,20 @@ void setup()
// bandgap select | AC interrupt enable | AC interrupt on rising edge (DS p.243) // bandgap select | AC interrupt enable | AC interrupt on rising edge (DS p.243)
ACSR |= (1<<ACBG) | (1<<ACIE) | (1<<ACIS1) | (1<<ACIS0); ACSR |= (1<<ACBG) | (1<<ACIE) | (1<<ACIS1) | (1<<ACIS0);
// Timer2 normal operation // Timer2 set to CTC mode (DS p.146, 154, 157)
// Timer2 clock prescaler set to 1 => fTOV2 = 1000kHz / 256 / 1 = 3906.24Hz (DS p.158) TCCR2A |= 1<<WGM21;
TCCR2B |= (1<<CS20); #if DBG > 0
TIMSK2 |= (1<<TOIE2); // Toogle pin OC2A=PB3 on compare match
TCCR2A |= 1<<COM2A0;
#endif
// Set PB3 as output pin
DDRB |= (1<<DDB3);
// Timer2 clock prescaler set to 8 => fTOV2 = 1000kHz / 256 / 8 = 488.28Hz (DS p.158)
TCCR2B |= (1<<CS21);
// Enable output compare match interrupt for timer2 (DS p.159)
TIMSK2 |= (1<<OCIE2A);
// Increase sampling frequency to 1250Hz (= 625Hz per channel)
OCR2A = 0x63;
// disable digital input cicuitry on ADCx pins to reduce leakage current // disable digital input cicuitry on ADCx pins to reduce leakage current
DIDR0 |= (1<<ADC5D) | (1<<ADC4D) | (1<<ADC3D) | (1<<ADC2D) | (1<<ADC1D) | (1<<ADC0D); DIDR0 |= (1<<ADC5D) | (1<<ADC4D) | (1<<ADC3D) | (1<<ADC2D) | (1<<ADC1D) | (1<<ADC0D);

View File

@ -24,7 +24,7 @@
# define POWER 1 # define POWER 1
# define WATT 1000000000 # define WATT 1000000000
# define SECOND 487 // rounded down from 488.28125 - 1 # define SECOND 624 // 625Hz - 1
#ifndef SENSOR0 #ifndef SENSOR0
#define SENSOR0 "0123456789abcdef0123456789abcde0" #define SENSOR0 "0123456789abcdef0123456789abcde0"
@ -43,33 +43,33 @@
#endif #endif
#ifndef TYPE #ifndef TYPE
#define TYPE 2301 #define TYPE 2300501
#endif #endif
#ifndef METERCONST #ifndef METERCONST // @ 625Hz sampling rate
#if TYPE == 2201 // 220V - 1-phase @ 488.28Hz sampling rate #if TYPE == 2200501
#define METERCONST 6783 #define METERCONST 5299
#warning "220V - 1-phase selected. METERCONST set to 6783" #warning "220V - 50A - 1-phase selected. METERCONST set to 5299"
#elif TYPE == 2203 // 220V - 3-phase @ 488.28Hz sampling rate #elif TYPE == 2200503
#define METERCONST 6721 #define METERCONST 5251
#warning "220V - 3-phase selected. METERCONST set to 6721" #warning "220V - 50A - 3-phase selected. METERCONST set to 5251"
#elif TYPE == 2301 // 230V - 1-phase @ 488.28Hz sampling rate #elif TYPE == 2300501
#define METERCONST 7091 #define METERCONST 5540
#warning "230V - 1-phase selected. METERCONST set to 7091" #warning "230V - 50A - 1-phase selected. METERCONST set to 5540"
#elif TYPE == 2303 // 230V - 3-phase @ 488.28Hz sampling rate #elif TYPE == 2300503
#define METERCONST 7026 #define METERCONST 5489
#warning "230V - 3-phase selected. METERCONST set to 7026" #warning "230V - 50A - 3-phase selected. METERCONST set to 5489"
#elif TYPE == 2401 // 240V - 1-phase @ 488.28Hz sampling rate #elif TYPE == 2400501
#define METERCONST 7399 #define METERCONST 5780
#warning "240V - 1-phase selected. METERCONST set to 7399" #warning "240V - 50A - 1-phase selected. METERCONST set to 5780"
#elif TYPE == 2403 // 240V - 3-phase @ 488.28Hz sampling rate #elif TYPE == 2400503
#define METERCONST 7331 #define METERCONST 5727
#warning "240V - 3-phase selected. METERCONST set to 7331" #warning "240V - 50A - 3-phase selected. METERCONST set to 5727"
#endif #endif
#endif #endif