Ich bau zur Zeit einen Frequenzzähler mit einem ATMEGA 328P.
Als Zähler wird der 16Bit Timer 1 Verwendet der vom Messsignal getaktet wird.
Ca. alle 8ms wird der aktuelle Zählerstand ausgelesen und zu dem Ergebnis dazuaddiert.
Nach 200ms wird dann das Ergebnis auf dem Display ausgegeben.
Im Prinzip funktioniert das Ganze, allerdings schwanken die Messwerte ziemlich stark.
Bei einer Eingangsfrequenz vom 1MHz werden Werte von 999810 bis über 1001300 angezeigt.
Ich hätte einen Fehler von +- 1 Count * 5 also +-5Hz erwartet.
Da der TCNT1 zu keiner Zeit manipuliert wird, sollten sich eventuelle Taktglitches ausgleichen.
Es läuft auch keine 2te Interruptroutine die das Timing stören könnte.
Zur Zeit betreibe Ich den Controller mit der internen 8MHz Quelle, aber das die so Jittert kann Ich mir nicht vorstellen.
Messfehler durch die interne ungenaue Taktung sind natürlich klar, aber Jitter?!
Mein parallel angeschlossener Frequenzzähler zeigt übrigens stabile 1000000Hz an, die nur an der letzten stelle +/- 1 sind.
Also sollte mein DDS Signalgenerator i.O. sein.
Anbei der zur Zeit benutzte Quelltext für Studio 7:
Code:
/*
* RDS_Frequenzzaehler.c
*
* Created: 02.01.2021 13:55:13
* Author : wKrug
*/
#define F_CPU 8000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "oled_ssd1306.c"
volatile uint32_t measure , result ;
volatile uint16_t oldcount = 0;
//volatile uint8_t measpoint = 0;
volatile uint8_t f_flag = 0;
volatile uint8_t f_loopcount;
// Timer2 output compare interrupt service routine
// Runs any 8ms
ISR (TIMER2_COMPA_vect)
{
uint16_t newcount;
newcount = TCNT1;
measure +=(newcount-oldcount);
oldcount=newcount;
f_loopcount++;
if(f_loopcount>24) //was 24 New measure any 200ms at 16MHz
{
result=measure;
measure = 0;
f_loopcount=0;
f_flag = 1;
}
}
void show_display(void)
{
uint32_t temp32;
char text [11];
temp32 = result * 5;
temp32 = (temp32 * 51)/100; //******** Hier für 8MHz + Taktausgleich int Osz************
ltoa (temp32,text,10);
//strcat(text,"kHz");
while (strlen (text) < 7)
strcat (text," ");
oled_font_size(3);
oled_gotoxy(0,0);
oled_write_str(text);
//oled_write("%lu",(unsigned long) measure);
/*oled_font_size(1);
oled_gotoxy(0,1);
oled_write("2 Z Text");
oled_font_size(3);
oled_gotoxy(0,3);
oled_write("4Text");
oled_font_size(0);
_delay_ms(100);*/
PORTB ^= (1<<PB5);//Port B5 toggelt
}
int main(void)
{
// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=Out Bit4=In Bit3=In Bit2=In Bit1=Out Bit0=In
DDRB=(0<<DDB7) | (0<<DDB6) | (5<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=0 Bit0=T
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
// Port C initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRC=(0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);
// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (1<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=0 Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);
// Timer/Counter 0 initialization
// Clock source: Disabled
// Mode: Fast PWM top=0xFF
// OC0A output: Non-Inverted PWM
// OC0B output: Disconnected
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: T1 pin Rising Edge
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (1<<CS12) | (1<<CS11) | (1<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
// Mode: CTC top=OCR2A
// OC2A output: Disconnected
// OC2B output: Disconnected
// Timer Period: 12,544 ms
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (1<<CS22) | (1<<CS21) | (1<<CS20);
TCNT2=0x00;
OCR2A=0x7C;
OCR2B=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0);
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1);
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=(0<<OCIE2B) | (1<<OCIE2A) | (0<<TOIE2);
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (0<<INT0);
PCICR=(0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);
// USART initialization
// USART disabled
UCSR0B=(0<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (0<<RXEN0) | (0<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
ADCSRB=(0<<ACME);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR1=(0<<AIN0D) | (0<<AIN1D);
// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);
// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);
// Globally enable interrupts
/* Replace with your application code */
DDRB |= (1<<PB5);
oled_init();
oled_gotoxy(0,0);
sei();
while (1)
{
if(f_flag)
{
f_flag=0;
show_display();
}
}
}
Wenn Ihr gute Ideen hab, woran es liegen könnte - Immer her damit!
Lesezeichen