Forum: Mikrocontroller und Digitale Elektronik Offset Drehzahlauswertung


von Andreas H. (Gast)


Lesenswert?

Hallo zusammen,
Habe eine Frage zu einem Drehzahlauswertungsprogramm, das ich 
geschrieben habe. Die Auswertung läuft über einen Atmega 2560.
Mein Probem ist, dass ich bei dem vorliegenden Quellcode bereits bei 
Stillstand (Das heißt auf den Counter 1 geht kein Signal) eine Drehzahl 
von 428 1/min angezeigt bekomme.
Da ich nachher sehr hohe Drehzahlen auswerten möchte (bis 110000 1/min) 
fällt dieser Offset nicht so sehr ins Gewicht, allerdings würde ich 
gerne verstehen warum das so ist oder ob ein Fehler in meinem Programm 
vorliegt.
Gruß Andreas
1
#include <avr/io.h>
2
#include <inttypes.h>
3
#include <stdlib.h>
4
#include <avr/interrupt.h>
5
#include <string.h>
6
#define BAUD 9600UL
7
#define UBRR_BAUD   ((F_CPU/(8UL*BAUD))-1)
8
9
void uart_init(void)
10
{
11
    // Baudrate einstellen (Normaler Modus)
12
    UBRR3H = (uint8_t) (UBRR_BAUD>>8);
13
    UBRR3L = (uint8_t) (UBRR_BAUD);
14
  
15
  UCSR3A= (1<<U2X3);    // U2X auf LO
16
17
18
    // Aktivieren von receiver und transmitter
19
    UCSR3B = (1<<RXEN3)|(1<<TXEN3);
20
21
    // Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
22
    UCSR3C = (1<<UCSZ31)|(1<<UCSZ30);
23
}
24
25
int uart_putc(unsigned char c)
26
{
27
    while (!(UCSR3A & (1<<UDRE3)))  /* warten bis Senden moeglich */
28
    {
29
    }                             
30
 
31
    UDR3 = c;                      /* sende Zeichen */
32
    return 0;
33
}
34
35
void uart_puts (char *s)
36
{
37
    while (*s)
38
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
39
        uart_putc(*s);
40
        s++;
41
  }
42
}
43
44
int main(void)
45
{  
46
  TCCR3B = (1<<CS32) | (1<<WGM32);// | (1<<CS32); Timer 3 initalisieren (Prescaler 256)
47
  TCCR1B = (1<<CS11) | (1<<CS12); //Timer 1 initalisieren (fallende Flanke)
48
  TIMSK3 |= (1<<OCIE3B); //Timer 3 Compare erlauben
49
  uint16_t COUNTER = 31250;
50
  OCR3B = COUNTER;
51
  TCNT1=0;
52
  
53
  
54
    // USART initialisieren
55
    uart_init();
56
  
57
  sei(); //Interrupts erlauben
58
59
    while (1) //Unendliche Schleife
60
    {
61
    }
62
return 0;
63
}
64
65
char s[10]; //Feld für String initalisieren
66
67
ISR (TIMER3_COMPB_vect)
68
{
69
  
70
  uint32_t i=TCNT1; //Variable definieren und Timer 1 auslesen
71
  i=((i*60*2)/7); // Drehzahl ausrechnen mit Offsetkorrektur (Ausgabe in 1/min)
72
  ultoa( i, s, 10 ); //Variable in Ascii-Zeichen umwandeln
73
  strcat (s, "   "); //Leerzeichen einfügen
74
  uart_puts(s); //Variableninhalt ausgeben
75
  TCNT3=0;
76
  TCNT1=0; //Timer 3 und 1 gleich Null setzen
77
}

von Yalu X. (yalu) (Moderator)


Lesenswert?

Das ist evtl. eine Netzstörung (50 Hz · 60 s/min / 7 = 428 1/min).

von Karl H. (kbuchegg)


Lesenswert?

> Mein Probem ist, dass ich bei dem vorliegenden Quellcode bereits
> bei Stillstand (Das heißt auf den Counter 1 geht kein Signal)

Wenn ich den Code richtig verstanden habe, dann basiert deine 
Messmethode darauf, dass du den Timer 1 extern mit dem Signal takten 
lässt, während du dir mit dem Timer 3 eine Zeitbasis erstellst.


Offensichtlich kriegst du am Timer 1 daher Clock-Impulse, was sofort die 
Frage nach sich zieht: Was hast da da an externer Hardware 
angeschlossen?
Wenn der Eingang offen ist, dann ist alles klar. Du hast keinen Pullup 
Widerstand eingeschaltet, d.h. der Eingang fängt sich jede mickrige 
elektromagnetische Störung aus deiner Umgebung ein und taktet damit den 
Timer 1.

von Andreas H. (Gast)


Lesenswert?

Vielen Dank für die Hilfe. Es war natürlich der Pullup den ich vergessen 
hatte. Ein blöder Fehler von mir. :-)
Gruß Andreas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.