Forum: Mikrocontroller und Digitale Elektronik c++ timer programmierhilfe


von Tim (Gast)


Lesenswert?

Also ich hab mir einen Timer nachgebaut. Der geht in Sekunden takt. ich 
will ihn aber in ms takt. Was muss ich in der .c verändern damit er das 
tut.
Hier ist die .c
1
/* Timer von 1-999 Sekunden
2
3
 * 3 7-Segment LEDs werden im Multiplexbetrieb angesteuert
4
5
#include <inttypes.h>    // uint8_t usw.
6
//#include <avr/io.h>
7
#include <avr/interrupt.h>  // Interrupts
8
#include <avr/signal.h>    // Interruptbehandlungsroutinen SIGNAL
9
#include <avr/delay.h>    // definiert _delay_ms und _delay_loop_2 
10
#include <avr/eeprom.h>    // EEPROM Zugriffe
11
12
#define delay_us(us)  _delay_loop_2 (((F_CPU/4000)*us)/1000)    // wartet µs
13
#define EEPROM  __attribute__ ((section (".eeprom")))        // für EEPROM-Zugriffe
14
15
/*
16
  Aufbau 7-Segment
17
18
//  Welcher Port an welchem Segement:
19
#define segm_a PD0
20
#define segm_b PD1
21
#define segm_c PD2
22
#define segm_d PD3
23
#define segm_e PD4
24
#define segm_f PD5
25
#define segm_g PD6
26
27
// Welcher Port an welcher Digit:
28
#define digit1 PC3    // Einer
29
#define digit2 PC4    // Zehner
30
#define digit3 PC5    // Hunderter
31
32
// An welchem Port sind Taster
33
#define btn_up    PB0
34
#define btn_down  PB1
35
#define btn_start  PB2
36
37
// An welchem Port hängt Relais
38
//#define relais PD7
39
40
// Ports definieren
41
#define port_segment  PORTD
42
#define port_digit    PORTC
43
#define port_keys    PORTB
44
#define dir_segment    DDRD
45
#define dir_digit    DDRC
46
#define dir_keys    DDRB
47
#define pin_keys    PINB
48
49
// Definiert, welche Segmente für die einzelnen Zahlenwerte aufleuchten sollen. HIGH-Aktiv
50
#define sign0 (1 << segm_a) | (1 << segm_b) | (1 << segm_c) | (1 << segm_d) | (1 << segm_e) | (1 << segm_f)
51
#define sign1 (1 << segm_b) | (1 << segm_c)
52
#define sign2 (1 << segm_a) | (1 << segm_b) | (1 << segm_g) | (1 << segm_e) | (1 << segm_d)
53
#define sign3 (1 << segm_a) | (1 << segm_b) | (1 << segm_g) | (1 << segm_c) | (1 << segm_d)
54
#define sign4 (1 << segm_f) | (1 << segm_g) | (1 << segm_b) | (1 << segm_c)
55
#define sign5 (1 << segm_a) | (1 << segm_f) | (1 << segm_g) | (1 << segm_c) | (1 << segm_d)
56
#define sign6 (1 << segm_a) | (1 << segm_f) | (1 << segm_g) | (1 << segm_e) | (1 << segm_d) | (1 << segm_c)
57
#define sign7 (1 << segm_a) | (1 << segm_b) | (1 << segm_c)
58
#define sign8 (1 << segm_a) | (1 << segm_b) | (1 << segm_c) | (1 << segm_d) | (1 << segm_e) | (1 << segm_f) | (1 << segm_g)
59
#define sign9 (1 << segm_a) | (1 << segm_b) | (1 << segm_c) | (1 << segm_d) | (1 << segm_g) | (1 << segm_f)
60
61
uint8_t num[] = { sign0, sign1, sign2, sign3, sign4, sign5, sign6, sign7, sign8, sign9 };
62
uint16_t startwert EEPROM;          // Speicherplatz für letzten Startwert im EEPROM
63
volatile uint16_t   display_value=0;    // Startwert. 
64
volatile uint8_t    run=0;          // =0 Counter Stop; =1 Counter läuft
65
volatile uint8_t    relais=0;        // =0 Relais off, =1 Relais on
66
volatile uint8_t    key_up=0,        // Puffer für Tastendrücke
67
          key_down=0,
68
          key_start=0;
69
70
/**
71
  @brief  Gibt Zahlenwert auf 7 Segment Display aus 
72
  @param   zahl
73
  @return  none
74
*/
75
void ausgabe (uint16_t zahl)
76
{
77
  uint16_t output = zahl;
78
  uint16_t warten = 500;    // Enable Zeit für einzelnes Segment. Zeit in der LED leuchten
79
  
80
  // Hunderter-Dezimalstelle
81
  if (zahl >= 100)
82
  {
83
    port_segment = relais | num[output/100];  // Zahlenwert darstellen zzgl. Zustand für PB7
84
    port_digit = (1 << digit3);          // 3. Digit HIGH
85
    delay_us(warten);              // LEDs müssen gewisse Zeit leuchten
86
    port_digit = 0;                // 3. Digit HIGH
87
  }
88
   output = output % 100;
89
  
90
  // Zehner-Dezimalstelle
91
  if (zahl >= 10)
92
  {
93
    port_segment = relais | num[output/10];    // Zahlenwert darstellen zzgl. Zustand für PB7
94
    port_digit = (1 << digit2);          // 2. Digit HIGH
95
    delay_us(warten);              // LEDs müssen gewisse Zeit leuchten
96
    port_digit = 0;                // 2. Digit HIGH
97
  }
98
   output = output % 10;
99
  
100
  // einer Dezimalstelle 
101
  port_segment = relais | num[output];      // Zahlenwert darstellen zzgl. Zustand für PB7
102
  port_digit =  (1 << digit1);          // 1. Digit HIGH
103
  delay_us(warten);                // LEDs müssen gewisse Zeit leuchten
104
  port_digit =  0;                // 1. Digit HIGH
105
106
  sei();              // Interrupts zulassen
107
}
108
109
/**
110
  @brief  Interruptbehandlung für Timer zum Displayrefresh
111
  @param   none
112
  @return  none
113
*/
114
SIGNAL (SIG_OVERFLOW0)
115
{
116
  cli();            // Interrupts nicht zulassen
117
  ausgabe (display_value);  // Zahl darstellen
118
}
119
120
/**
121
  @brief  Interruptbehandlung für Timer zur Tastenabfrage. 
122
      Für jede Taste erxistiert eine Variable, die inkrementiert wird, wenn Interrupt ausgelöst wird und Taste gedrückt ist
123
      Sind x Tastenimpulse zusammen, wird im Hauptprogramm die Taste als gedrückt angesehen
124
  @param   none
125
  @return  none
126
*/
127
SIGNAL (SIG_OVERFLOW2)
128
{
129
  cli();    // Interrupts nicht zulassen
130
  
131
  if (pin_keys & (1 << btn_up))    // Up-Taste gedrückt
132
    key_up++;
133
    
134
  if (pin_keys & (1 << btn_down))    // Down-Taste gedrückt
135
    key_down++;
136
    
137
  if (pin_keys & (1 << btn_start))  // Start-Taste gedrückt
138
    key_start++;
139
  
140
  sei();    // Interrupts zulassen
141
}
142
143
/**
144
  @brief  Interruptbehandlung für Timer für Sekundentakt bei gestartetem Counter
145
      Wird jede Sekunde einmal ausgelöst und dekrementiert den Zähler
146
  @param   none
147
  @return  none
148
*/
149
SIGNAL (SIG_OUTPUT_COMPARE1A)
150
{
151
  cli();              // Interrupts nicht zulassen
152
  TCNT1H=0;            // Timerstand zurücksetzen
153
  TCNT1L=0;
154
  
155
  display_value -= run;
156
}
157
158
int main(void)
159
{
160
161
  dir_digit = (1 << digit1) | (1 << digit2) | (1 << digit3);      // Ausgänge, für Digits
162
  dir_segment = 0xFF;                          // alles Ausgänge, für Segmente 
163
  dir_keys &= ~(1 << btn_up) & ~(1 << btn_down) & ~(1 << btn_start);  // Eingänge für Tasten
164
165
  // Timer für Displayrefresh
166
//  TCCR0 |= (1<<CS01);          //8-Bit Timer, Timer clock = system clock/8
167
  TCCR0 |= (1<<CS01) | (1<<CS00);    //8-Bit Timer, Timer clock = system clock/64
168
//  TCCR0 |= (1<<CS02);          //8-Bit Timer, Timer clock = system clock/256
169
//  TCCR0 |= (1<<CS02) | (1<<CS00);    //8-Bit Timer, Timer clock = system clock/1024
170
  TIFR |= (1<<TOV0);           //Clear TOV0 Timer/Counter Overflow Flag. clear pending interrupts
171
  TIMSK |= (1<<TOIE0);         //Enable Timer0 Overflow Interrupt
172
173
  // Timer für Tastenabfrage
174
  TCCR2 |= (1<<CS22) | (1<<CS20);    //8-Bit Timer, Timer clock = system clock/1024
175
  TIFR |= (1<<TOV2);           //Clear TOV2 Timer/Counter Overflow Flag. clear pending interrupts
176
  TIMSK |= (1<<TOIE2);         //Enable Timer2 Overflow Interrupt
177
  
178
  // Timer für Sekundentakt
179
  OCR1AH = 0x1E;            // 16Bit Timer Takt= 8MHz => 8.000.000/1024 = 7812,5 => 7,8125 Zählerschritte pro ms
180
  OCR1AL = 0x83;            // Vergleichswert laden: 1 Sekunde
181
  TIMSK |= (1<<OCIE1A);         // Interrupt wenn Timer Vergleichswert erreicht
182
183
  sei();              // Interrupts zulassen
184
185
  while (1)
186
  {
187
    if (key_up >= 50)        // Up-Taste gedrückt
188
    {
189
      display_value++;      // Wert +1
190
      if (display_value > 999)  // Wenn Überlauf => Wert=0
191
        display_value = 1;
192
      key_up = 0;          // Tastencounter leeren
193
    }
194
    if (key_down >= 50)      // Down-Taste gedrückt
195
    {
196
      if (display_value <= 1)    // Wenn Unterlauf => Wert=999
197
        display_value = 1000;
198
      display_value--;      // Wert -1
199
      key_down = 0;        // Tastencounter leeren
200
    }
201
202
    if (key_start >= 100)      // Start-Taste gedrückt
203
    {
204
      key_start = 0;        // Tastencounter leeren
205
      if (display_value == 0)    // wenn angezeigter Wert = 0 und Start gedrückt => ermittler zuletzt verwendeten Startwert und setze diesen
206
      {
207
        display_value = eeprom_read_word(&startwert);
208
      }
209
      else
210
      {
211
        run ^= 1;          // Wert XOR 1;  => Start/Stop
212
        if (run)          // Wenn Counter gestartet wird
213
        {
214
          if (display_value != eeprom_read_word(&startwert))    // wenn Start gedrückt und aktueller Startwert != letzter Startwert
215
            eeprom_write_word(&startwert, display_value);    // dann speichere neuen Startwert
216
        
217
          TCNT1H=0;            // Timerstand zurücksetzen, damit ab jetzt eine Sekunde zählt
218
          TCNT1L=0;
219
          TCCR1B = (1<<CS10)|(1<<CS12);  // Timer mit Div 1024 starten
220
          relais = 0x80;          // zusätzlich Relais HIGH 
221
        }
222
        else            // Counter angehalten
223
        {
224
          TCCR1B = 0;        // Timer Stop
225
          relais = 0x0;      // Relais LOW
226
        }
227
      }
228
    }
229
230
    if (display_value == 0)      // Timer abgelaufen
231
    {
232
      run = 0;          // Stop
233
      relais = 0x0;        // Relais LOW
234
    }
235
  }
236
}

Kann mir jemand Helfen ??????????

von Uwe .. (uwegw)


Lesenswert?

Die Zeilen
  // Timer für Sekundentakt
  OCR1AH = 0x1E;
  OCR1AL = 0x83;

lassen sich durch
OCR1A= 0x1E83;
ersetzen. Besser noch durch dezimal
OCR1A= 7811;
Hier wird festgelegt, wie weit der Zähler läuft. 7811 entspricht einer 
Sekunde, also änderst du den Wert auf 8, um etwa eine Milisekunde zu 
bekommen. Soll es genauer werden, sind noch weitere Änderungen nötig.

von Tim (Gast)


Lesenswert?

Danke werde es gleich ausprobieren

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.