Forum: Mikrocontroller und Digitale Elektronik Verzögertes Schalten durch Timer mit Fallunterscheidung


von Dirk (Gast)


Lesenswert?

Hallo,
ich bin recht neu in der Mikrocontrollerprogrammierung und habe mich nun 
ein wenig mit dem Timer auseinander gesetzt ( benutze den Atmega88 ):

Zum Projekt:
Ich Programmiere bzw. Baue eine einstellbare Zeitverzögerte Schaltung. 
Ein- und Ausschaltverzögerung sind verschiedene Zeiten und sollen 
einstellbar von 0.1 - 399 millisekunden sein. Das Eingangssignal zum 
Ein- bzw Ausschalten kommt vom gleichem Pin.

Zum Programm:
Per Tastendruck werden 8 Variablen erhöht. Jeweils für die Ein- und 
Ausschaltverzögerung sollen die Variabeln den Wert 100ms 10ms 1ms und 
0.1ms Darstellen. Diese lasse ich an einem LCD anzeigen. Dies 
Funktioniert soweit und stelle deswergen nur den Quellcode für die 
Verzögerung mit dem Timer rein, da es sonst unübersichtlich werden 
könnte. (Natürlich könnt ich den anderen Teil nachlegen):
1
  //Tastenbfrage ob in Schaltmodus umspringen//
2
3
      if  ( EINGANG_UM != 1 )
4
      {
5
6
      //Status LED einschalten (ROT) //
7
8
      PORTB |= (1<<AUSGANG_ROT);
9
      PORTB &= ~(1<<AUSGANG_GRN);
10
11
      // Schaltzeiten Generieren (in Mikrosekunden) //
12
13
      ZeitEin = Ein4 * 100000 + Ein3 + 10000 + Ein2 * 1000 + Ein1 * 100;
14
      ZeitAus = Aus4 * 100000 + Aus3 + 10000 + Aus2 * 1000 + Aus1 * 100;
15
16
      _delay_ms(1000);
17
18
      // Warten aufs Schaltsignal oder Signal zum Zeiteinstellen //
19
      
20
        while (EINGANG_UM == 1)
21
        {
22
23
          // Abfrage Schaltsignal //
24
25
          if  ( EINGANG_SYN != 1 )
26
          {
27
          
28
            // Ausgang ist auf "Aus" und wird mit ZeitEin in Mikrosekunden verzögert eingeschaltet  //
29
30
            if  ( AUSGANG_SCHALTER != 1 )
31
            {
32
              // Anzahl benötigter Overflows//
33
34
              sollover = ZeitEin / 111;
35
36
37
              /* 8 Bit Timer 0 initialisieren.
38
              Vorteiler: 8, Overflow Modus.
39
              Erzeugte Frequenz: 18432000 / 8 / (2 ^ 8) = 9000Hz => 111 Mikrosekunden.
40
              Timer startenen
41
              */
42
43
              TCCR0B = (1<<CS01);
44
            
45
                while (anzahlover != sollover)
46
                {
47
                  // Prüfen ob Timer 1 einen Overflow hatte //
48
49
                  if (TIFR1 & (1<<TOV1))
50
                  {
51
52
                  // Flag löschen durch schreiben einer 1 an dessen Stelle //
53
54
                  TIFR1 = (1<<TOV1);
55
                  anzahlover = anzahlover + 1;
56
57
                  }
58
                }
59
60
              // Ausgang Ausschalten //
61
62
              PORTB |= (1<<AUSGANG_SCHALTER);
63
64
              //Timer ausschalten//
65
66
              TCCR0B = (0b00000000);
67
68
              // Variablen wieder auf 0 setzten //
69
            
70
              sollover = 0;
71
              anzahlover = 0;
72
73
74
            }  
75
  
76
77
            // Ausgang ist auf "Ein" und wird mit ZeitAus in Mikrosekunden verzögert ausgeschaltet  //
78
79
            else 
80
            {
81
              // Anzahl benötigter Overflows//
82
83
              sollover = ZeitAus / 111;
84
85
86
              /* 8 Bit Timer 0 initialisieren.
87
              Vorteiler: 8, Overflow Modus.
88
              Erzeugte Frequenz: 18432000 / 8 / (2 ^ 8) = 9000Hz => 111 Mikrosekunden.
89
              Timer startenen
90
              */
91
92
              TCCR0B = (1<<CS01);
93
            
94
                while (anzahlover != sollover)
95
                {
96
                  // Prüfen ob Timer 1 einen Overflow hatte //
97
98
                  if (TIFR1 & (1<<TOV1))
99
                  {
100
101
                  // Flag löschen durch schreiben einer 1 an dessen Stelle //
102
103
                  TIFR1 = (1<<TOV1);
104
                  anzahlover = anzahlover + 1;
105
106
                  }
107
                }
108
109
              // Ausgang Ausschalten //
110
111
              PORTB &= ~(1<<AUSGANG_SCHALTER);
112
113
              //Timer ausschalten//
114
115
              TCCR0B = (0b00000000);
116
117
              // Variablen wieder auf 0 setzten //
118
            
119
              sollover = 0;
120
              anzahlover = 0;
121
122
            }
123
124
125
          }
126
127
        _delay_ms(1000);
128
129
        }

Beschreibung:
Zuerst werden die Verzögerungszeiten aus den Variablen zusammengestellt;
Danach wird auf das Schaltsignal gewartet. Liegt dieses an wird ein 
Fallunterschied gemacht, ob der Ausgang ein- oder ausgeschaltet ist.
Dann wird ausgerechnet, wie viele Overflows benötigt werden, damit die 
Ein- bzw. Ausschaltzeit erreicht wird. Nach erreiche der Zeit wird der 
Ausgang umgeschaltet, der Timer gestoppt und die Anzahlt der Overflows 
auf 0 gesetzt.

Zu meinen Fragen:

- Ist das so Funktionstüchtig oder dicke Böcke drin?
- Was für empfehlungen hättet ihr um solch ein programm besser 
Programmieren?

Danke im voraus
Dirk

von Karl M. (Gast)


Lesenswert?

Hallo,

denke an eine Uhr mit z.B. 1 Sekunden Takte und rechne von der Start- 
die Endzeit aus und dies aktiviert dann deinen Ereignis.

Was soll das mit den 100µs werden ? Welcher Mensch kann die noch 
erfassen ?

von Karl M. (Gast)


Lesenswert?

Nun für deine Tastenabfragen sehe ich keine Tastenentprellung und keine 
Flankenerkennung.
Das ist schlecht.

von Dirk (Gast)


Lesenswert?

Was soll das mit den 100µs werden ? Welcher Mensch kann die noch
erfassen ?

Karl M. schrieb:
> denke an eine Uhr mit z.B. 1 Sekunden Takte und rechne von der Start-
> die Endzeit aus und dies aktiviert dann deinen Ereignis.
>

Also ich habe meine Rechnung mit 18,432 MHz Ausgelegt da ich solch ein 
Quarz an meinem Contoller habe und dann 1/8.

>
> Was soll das mit den 100µs werden ? Welcher Mensch kann die noch
> erfassen ?

 Dies soll eine Schaltung werden, womit ich einen Wechselstromschalter 
(bestehend aus 2 antiparalle Thyristoren und Ansteuerelektronik) 
schalten kann. Die 100µs benötige ich da ich zu verschiedenen 
Phasenwinkel Ein- bzw Auschalten möchte, um transiente Ladevorgänge bei 
zum Beispiel Einschalten einer Kondensatorbatterie Anschaulich machen zu 
können. Die Hardware also der Wechselstromschalter funktioniert soweit 
nur mit der Zeitverzögerung war ich ein bischen am holpern.

von Karl M. (Gast)


Lesenswert?

Hallo Dirk,

dir "Uhr" läuft natürlich mit 100µs Ticks und zählt entweder 16 Bit, 24 
Bit oder 32 Bit weit, bevor sie überläuft und bei 0 anfängt.

Mit einer Zählerweite von 16 Bit kannst Du:
2^16-1 * 100^-6s ~6,55s abbilden.

Sollte also lässig für 0,4s Verzögerung und On-Zeit reichen.

Eine Einstellung der Zeiten würde ich über einen Drehencoder mit Taster 
realisieren.

von Dirk (Gast)


Lesenswert?

Karl M. schrieb:
> Nun für deine Tastenabfragen sehe ich keine Tastenentprellung und keine
> Flankenerkennung.
> Das ist schlecht.

Die Tastenentprellung zur Zeiteinstellung habe ich in dem Anderem Teil 
des Programmes, das ich wie gesagt noch nicht reingestellt habe aber 
dieser Teil ist Funktionstüchtig.
Bei dem Schaltbefehl wird keine Tastenentprellung benötigt da dieser 
befehl von einem externen Steuergerät kommmt und über einem Optokoppler 
angeschlossen ist.

von Karl M. (Gast)


Lesenswert?

Hallo Dirk,

es gibt da so eine Regel: _delay_ms(1000) gehören in kein Programm !

Ausnahmen gibt es schon, aber diese sind dann eher im Bereich von ein 
paar µs, bei z.B. der Ansteuerung von LCD oder 1-Wire Protokollen.

von Dirk (Gast)


Lesenswert?

Karl M. schrieb:
> dir "Uhr" läuft natürlich mit 100µs Ticks und zählt entweder 16 Bit, 24
> Bit oder 32 Bit weit, bevor sie überläuft und bei 0 anfängt


Danke Schonmal
also ich hatte es so vertanden das es jede 111 Mikrosekunden zu einem 
Overflow kommt da:

18432000  8  (2 ^ 8) = 9000Hz => 111 Mikrosekunden.

um nun die Zeit Abzuwarten musst ich doch soviele Overflows abwarten:

Sollzeit/111Mikrosekunden = Anzahl der Overfolws

Oder liege ich dort auf dem Holzweg?

von Dirk (Gast)


Lesenswert?

Karl M. schrieb:
> es gibt da so eine Regel: _delay_ms(1000) gehören in kein Programm !

Kurz davor soll von dem Einstellmodus in dem ich die Zeit einstelle in 
den Warten-auf-Schaltbefehl-Modus gewechselt werden und nutze dies dort 
zur Tastenentprellung da der Übergang durch Tastendruck geschieht.

Soll man dafür auch keine delay-Funktion benutzen?

von Dirk (Gast)


Lesenswert?

Aber sonst sollte es soweit klappen? Oder gibt es da den ein oder 
anderen Fehler der sofort ins Auge sticht?

von holger (Gast)


Lesenswert?

>Aber sonst sollte es soweit klappen?

Probiere es aus und berichte.

von Karl M. (Gast)


Lesenswert?

Aus dem QRL zurück,

also ich habe mein Vorgehen beschrieben und würde auch die Zeitbasis auf 
~100µs einstellen. Ja das geht über den CTC Modus, so ein Atmel hat ja 
noch weitere Timer/ Zähler!

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.