Verzögertes Schalten durch Timer mit Fallunterscheidung

Gast #4624703
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
Gast #4624708
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 ?
Gast #4624721
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.
Gast #4624723
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.
Gast #4624725
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.
Gast #4624730
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.
Gast #4624734
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?
Gast #4624737
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?
Gast #4624867
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!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren