USART_Polling_oder_Interrupt

Gast #1614826
Hallo!

Habe da ein Problem:
Ich will mit folgendem Code den USART betreiben.
Unglücklicherweise las ich, dass bei Auftreten von mehreren ISRs dieser 
Sourcecode ungeeignet ist (sprich: Der Stack wird zusammengehaut) etc.

Wie man ersehen kann benutzt der Code schon einen Timer overflow 
interrupt. Meine Frage an euch Experten ist es, ob ich vl. evtl. evtl. 
doch nicht noch den USART-Recieve_ISR einfügen kann? (=Ich habe in 
dieser Routine nichts anderes vor, als UDR in eine andere Variable 
umzuspeichern und ein Flagbyte zu setzen?
Durch Abfrage des Flags in TestC soll dann der Wert abgearbeitet werden.
Eine Alternative ist die Pollingmethode,  jedoch befürchte ich, dass die 
Variable überschrieben werden könnte?
Mein MCU ist ein atmega32.
1
/// Includes //////////
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4

5
/// Data Types /////////
6
typedef unsigned char u8;
7
typedef unsigned int u16;
8
typedef struct task
9
{
10
   // pointer to a function
11
   void (*pfunc) (void);
12
   // delay before the first call
13
   u16 delay;
14
   // interval between subsequent runs
15
   u16 period;
16
   // flag indicating time to run
17
   u8 run;
18
}task;
19

20
struct USART
21
{ unsigned char empfangen;
22
unsigned char wert;
23
}
24

25
/// Defines ///////////
26
// 25msec period 256-180 
27
// 7.3728MHz and /1024 prescaler
28
#define StartFrom       76
29
// maximum number of tasks
30
#define MAXnTASKS       20
31

32
/// Globals ///////////
33
volatile task TaskArray[MAXnTASKS];
34

35
/// Prototypes ////////
36
void InitUART (u16 baud);
37
void TransmitByte (u8 data);
38
void InitScheduler (void);
39
void UpdateScheduler(void);
40
void DeleteTask (u8 index);
41
void AddTask (void (*taskfunc)(void), u16 taskdelay, u16 taskperiod);
42
void DispatchTask (void);
43

44
void TestA (void);
45
void TestB (void);
46
void TestC (void);
47

48
/// Main //////////////
49
int main(void)
50
{
51
   InitUART (23);
52
   InitScheduler();
53
        
54
   // populate task array       
55
   AddTask (TestA, 0, 3);
56
   AddTask (TestB, 1, 4);
57
   AddTask (TestC, 4, 0);
58
        
59
   // enable interrupts
60
   sei();
61
        
62
   while (1) 
63
   {
64
      DispatchTask();
65
   }            
66
}
67

68
void InitUART (u16 baud)
69
{
70
   UBRRH = (u8)(baud>>8);                                                        
71
   UBRRL = (u8)baud;
72
   UCSRB = (1<<RXEN)|(1<<TXEN);              
73
   UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
74
//hier ist noch der Recieveinterrupt zu aktivieren
75
}
76

77

78

79
void InitScheduler (void)
80
{
81
   u8 i;
82
   
83
   // timer prescaler clock/1024
84
   TCCR0 |= (1<<CS02)|(1<<CS00);
85
   // clear pending interrupts
86
   TIFR = 1<<TOV0;
87
   // enable timer0 overflow interrupt
88
   TIMSK |= 1<<TOIE0;
89
    // load timer0
90
   TCNT0 = StartFrom;
91

92
   // clear task array
93
   for (i=0; i<MAXnTASKS; i++) DeleteTask(i);
94
}
95

96
void DeleteTask (u8 j)
97
{
98
   TaskArray[j].pfunc = 0x0000;
99
   TaskArray[j].delay = 0;
100
   TaskArray[j].period = 0;
101
   TaskArray[j].run = 0;
102
}
103

104
void AddTask (void (*taskfunc)(void), u16 taskdelay, u16 taskperiod)
105
{
106
   u8 n=0;
107

108
   // find next available position
109
   while ((TaskArray[n].pfunc != 0) && (n < MAXnTASKS)) n++;
110

111
   // place task
112
   if (n < MAXnTASKS)
113
   {
114
      TaskArray[n].pfunc = taskfunc;
115
      TaskArray[n].delay = taskdelay;
116
      TaskArray[n].period = taskperiod;
117
      TaskArray[n].run = 0;   
118
   }
119
}
120

121
SIGNAL(SIG_OVERFLOW0)
122
{
123
   u8 m;
124

125
  
126
   
127
   // load timer
128
   TCNT0 = StartFrom;
129
   
130
   for (m=0; m<MAXnTASKS; m++)
131
   {
132
      if (TaskArray[m].pfunc)
133
      {   
134
         if (TaskArray[m].delay == 0) 
135
         {
136
            TaskArray[m].run = 1;
137
            TaskArray[m].delay = TaskArray[m].period;
138
         }
139
         else TaskArray[m].delay--;
140
      }
141
   }
142
}
143
ISR(USART_RECv_vect)
144
{
145
USART.empfangen=1;
146
USART.wert=UDR;
147
}
148
void DispatchTask (void)
149
{
150
   u8 k;
151
   
152
   for (k=0; k<MAXnTASKS; k++)
153
   {
154
      if (TaskArray[k].run == 1)
155
      {
156
         // run task
157
         (*TaskArray[k].pfunc)();
158
         // clear run flag
159
         TaskArray[k].run = 0;
160
      }
161
   }
162

163
}
164

165
void TestA (void)
166
{
167
   
168
}
169

170
void TestB (void)
171
{
172
   
173
}
174

175
void TestC (void)
176
{
177
  //Abfrage, ob was Empfangen
178

179
if(USART.empfangen){
180
// hier geschieht die Verarbeitung
181

182

183
//Ende der Verarbeitung
184
USART.empfangen=0;
185
}
186
}


mfg

PS: Freu mich auf die Antworten
#1616461
Hi
ich finde den Weg, (trotz keiner allgemein gültigen Formel) den UART 
Empfang per ISR zu händeln, völlig richtig. Es geht auch nix verloren, 
wenn der empfangene Wert in einen Ringpuffer eingetragen wird. Wenn der 
Timer nicht grad im µS-bereich liegt, dürfte er höchstens mal kurz 
holpern, aber er dürfte nicht verloren gehen. Ist aber ein wenig 
abhängig von der Taktfrequenz.
Gruß oldmax

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.