Forum: Mikrocontroller und Digitale Elektronik ATmega328 Timer1- Konfigurationsproblem


von Pimi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
Leider funktioniert mein Timer immer noch nicht. Pure Verzweiflung!
Alle Komponenten meines Programms außer Timer 1 funktionieren.
Darum habe ich nur ein kleines Timer-Programm zugeschickt. Den Timer 
hier habe ich mit Code Vizard (SiSy-AVR) generiert. Das Programm sollte 
eine Markise steuern:
Wenn der Wind schwach ist, das heißt wenige als 10 Impulse am Interrupt 
D3 innerhalb von 5 Sekunden -> öffnet die Markise.
Bei starken Wind Markise schließt und die Windanzeige geht an.

Bitte um Hilfe!
Mit freundlichen Grüßen

von Karl H. (kbuchegg)


Lesenswert?

Pimi schrieb:
> Hallo,
> Leider funktioniert mein Timer immer noch nicht. Pure Verzweiflung!
> Alle Komponenten meines Programms außer Timer 1 funktionieren.
> Darum habe ich nur ein kleines Timer-Programm zugeschickt. Den Timer
> hier habe ich mit Code Vizard (SiSy-AVR) generiert.

Vergiss doch einfach mal dieses ganze SiSy Zeugs und diverse 
Code-Wizards. Verstehen wie die Dinge tatsächlich funktionieren kann 
durch keinen Wizard ersetzt werden!

Wenn ich sowas ....
1
   TCCR1B=0x05;   // Teiler 1/1024
2
   TCCR1B|=0x02;   // Modus: Zählen bis Vergleichswert
schon sehe, krieg ich die Krise und meine Bereitschaft da irgendwelchen 
Code zu analysieren tendiert rapide gegen 0.


Was ist denn nun?
1
#define   F_CPU   3686400
2
#include <avr\io.h>
3
#include <util\delay.h>
4
5
int main()
6
{
7
  Port auf Ausgang schalten
8
9
  while( 1 )
10
  {
11
    LED einschalten
12
    _delay_ms( 1000 );
13
    LED ausschalten
14
    _delay_ms( 1000 );
15
  }
16
}

blinkt deine LED mit 1 Sekunde an/aus oder blinkt sie nicht in diesem 
Zeitraster? Ehe das nicht stimmt hat es doch keinen Sinn irgendwelche 
weiteren Berechnungen oder Versuche mit Timerzeiten zu machen, weil dann 
etwas ganz Grundlegendes nicht stimmt! Dein µC taktet dann eben nicht so 
schnell, wie der Wert, mit dem alles andere berechnet wurde, aussagt. 
(Entweder das, oder der Optimizer ist nicht eingeschaltet)

Du kannst stundenlang irgendwelche Berechnungen darüber anstellen, wie 
weit du mit 250km/h fahren kannst bzw. wo du da am Sonntag Nachmittag 
überall hin einen Ausflug machen kannst. Wenn aber dein VW-Käfer (das 
Original) nun mal nicht mehr als 100km/h schafft, dann ist die ganze 
Rechnerei sinnlos und deine Ergebnisse werden gnadenlos falsch sein.

von Peter D. (peda)


Lesenswert?

Liefert der Sensor überhaupt prellfreie Impulse oder ist das ein 
Kontakt?

Laß Dir doch erstmal den Meßwert über UART oder ein LCD ausgeben.


Peter

von Pimi (Gast)


Lesenswert?

Hallo,

Karl Heinz Buchegger schrieb:
> TCCR1B=0x05;   // Teiler 1/1024
>    TCCR1B|=0x02;   // Modus: Zählen bis Vergleichswert
> schon sehe, krieg ich die Krise und meine Bereitschaft da irgendwelchen
> Code zu analysieren tendiert rapide gegen 0.

Danke für Ihre Hilfsbereitschaft!
Ich weiß dass bei mir fehlen die Grundkenntnisse. Bis jetzt war für mich 
das „Sisy Zeug“ sehr hilfreich. Ich weiß nicht mal wie ich das ganze 
Zeug lernen kann, bis jetzt fand ich keine entsprechende Literatur 
(C-Sprache), wo alles auf einfache art und weiße erklärt wird. Wenn du 
mir mit einem Tipp dabei helfen willst wäre ich sehr dankbar!

Den Fehler habe ich mit Hilfe behoben:
1.  Falsche Fuses
2.  Falsche Timerkonfiguration:
Ist:  TCCR1B=0x05;    // Teiler 1/1024
      TCCR1B|=0x02;   // Modus: Zählen bis Vergleichswert
korrekt heißt es
      TCCR1B=0x05;    // Teiler 1/1024
      TCCR1B|=0x08;   // Modus: Zählen bis Vergleichswert

An Alle die mir Helfen wollten.
Besten Dank!

von Jahat I. (jaib)


Lesenswert?

Hallo Pimi,

hast es schneller hin bekommen als ich dazu kam dir nen Lösungsvorschlag 
leider nur für den ATmega8 zusammenzuschustern :-( ich poste den 
trotzdem mal, vielleicht kommst ja dazu das mal auszuprobieren brauchst 
aber dafür schon das aktuellste Sisy ... interessiert mich unheimlich ob 
das geht oder ob die Klasse Button zu träge für deinen Windsensor ist.
1
//----------------------------------------------------------------------
2
// Titel     : Automatische Markisensteuerung, kleines Programm AVR C++
3
//----------------------------------------------------------------------
4
//----------------------------------------------------------------------
5
// Schaltung : Windsensor liefert einen Impuls je Umdrehung -> an PortD3 -> Zählen mit Interrupt
6
//             Schalter an PortC5 öffnet/schießt die Markise (es wird der soll-Zustand [High=offen; Low=geschlossen] ausgegeben)
7
// Funktion  : Markise ist offen:
8
//             Wenn innerhalb eines Intervalls 1 der Schwellwert überschrittenwird,
9
//             soll die Markise geschlossen werden.
10
//             Markise ist geschlossen:
11
//             Wenn innerhalb von 120xIntervall 1 der Schwellwert nicht überschritten wurde
12
//             soll die Markise geöffnet werden.
13
// Prozessor : ATmega328P
14
// Takt : 3686400 Hz
15
// Sprache : C++
16
//-------------------------------------------------------------------------
17
#define MAX_IMPULSE   10
18
#define MAX_INTERVALL  120
19
20
class Markise 
21
{
22
  public: void init()   {ddrC.bit0=1;}
23
  public: void close()  {portC.bit0=0;}
24
  public: void open()   {portC.bit0=1;}
25
  public: bool isOpen() {return portC.bit0;}
26
};
27
28
class Anzeige 
29
{
30
  public: void init() {ddrB.bit0=1;}
31
  public: void on()   {portB.bit0=0;}
32
  public: void off()  {portB.bit0=1;}
33
};
34
35
36
class Application : public Controller
37
{
38
    protected: Button     windsensor;
39
    protected: uint8_t    impulsCounter;
40
    protected: uint8_t    intervallCounter;
41
    protected: Markise    markise;
42
    protected: Anzeige    windAnzeige;
43
    
44
    public: void onStart()
45
    {
46
    windsensor.config(portD,bit3);
47
    impulsCounter=0;
48
    markise.init();    
49
    windAnzeige.init();
50
    }
51
    
52
    public: void onWork()
53
    {
54
        // leer
55
    }
56
    
57
    public: void onTimer1s()
58
    {
59
    if(markise.isOpen())
60
    {
61
      if(impulsCounter >= MAX_IMPULSE)
62
      {
63
        markise.close();  
64
        windAnzeige.on();  
65
      }
66
      intervallCounter=0;  // wenn offen werden die Intervalle nicht gezählt.
67
    }
68
    // wenn geschlossen
69
    else
70
    {
71
      intervallCounter++;
72
      // wenn zu windig
73
      if(impulsCounter >= MAX_IMPULSE)
74
      {
75
        intervallCounter=0;
76
      }
77
  
78
      if(intervallCounter >= MAX_INTERVALL)
79
      {
80
        markise.close();   
81
        windAnzeige.off();  
82
      }
83
    }
84
    impulsCounter = 0;  // Impulszähler für nächses Intervall zurücksetzen          
85
    }
86
    
87
    public: void onEvent(const Object& sender, uint8 data)
88
    {
89
    // Windsensor sollte wie ein Button arbeiten und jeder Impuls als Click ankommen,
90
    // Button ist bereits entprellt aber vielleicht zu langsam
91
    if ( sender == windsensor && data == Button::Click )
92
      impulsCounter++;        
93
    }
94
    
95
} app;

von Karl H. (kbuchegg)


Lesenswert?

Pimi schrieb:

> korrekt heißt es
>       TCCR1B=0x05;    // Teiler 1/1024
>       TCCR1B|=0x08;   // Modus: Zählen bis Vergleichswert

Nein.
Korrekt heisst es:

   TCCR1B = ( 1 << CS12 ) | ( 1 << CS10 );
   TCCR1B |= ( 1 << WGM12 );


Ob das WGM12 Bit nun das Bit 2 oder das Bit 4 ist, ist etwas was mich 
nicht interessieren braucht. Das Bit hat einen Namen! Und über den setze 
ich es.

Dann passieren dir auch nicht solche Bit-Unfälle.

Du hast jetzt am eigenen Leib erfahren, wie mühsam es ist, 
Hex-Konstanten wie 0x02 oder 0x05 mit dem Datenblatt in Übereinstimmung 
zu bringen und rauszukriegen, was da wirklich passiert. Benutze die 
Bitnamen und du schaltest zumindest eine Fehlerquelle erst mal aus.

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.