Forum: Compiler & IDEs UART-Interrupt Problem


von Ralf (Gast)


Lesenswert?

Hallo Leute!

Mit folgendem Code möchte ich alle LEDs meines STK500s einschalten, wenn 
irgendein Zeichen vom UART empfangen wird.
Wenn nichts empfangen wird, soll die Endlosschleife ein Lauflicht 
(später Schrittmotor) leuchten lassen.

Ich habe nun versucht, mit einem Terminal ein Zeichen zum Board zu 
schicken, leider reagiert es nicht (springt nicht in die 
Interrupt-Routine), sodass ständig nur das Lauflicht leuchtet.


Wisst ihr wo mein Fehler ist?

Hier ist mein Code:

1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <inttypes.h>
4
#include <avr/interrupt.h>
5
6
7
8
#define DELAY 50
9
10
void initialisiere_UART(void)
11
{
12
  UCSRB |= (1<<RXEN);                         // Senden/empfangen aktivieren
13
  UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);  
14
15
  UBRRH = 00;                             // Baudrate einstellen 9600 bei 8 MHz
16
  UBRRL = 51;
17
}
18
19
20
ISR (USART_RXC_vect) 
21
{
22
  
23
  PORTA =~(0xFF);
24
  _delay_ms(500);
25
  PORTA =~(0x00);  
26
  _delay_ms(500);    
27
}
28
29
30
31
32
void main (void)
33
{
34
  DDRA = 0xFF;
35
36
  PORTA = ~0x01;
37
38
  initialisiere_UART();
39
   
40
41
  sei();                  // Interrupt scharf schalten
42
43
44
  while(1)
45
  {
46
    PORTA = ~(0b00000001);
47
    _delay_ms(DELAY);
48
    PORTA = ~(0b00000011);
49
    _delay_ms(DELAY);
50
    PORTA = ~(0b00000010);
51
    _delay_ms(DELAY);
52
    PORTA = ~(0b00000110);
53
    _delay_ms(DELAY);
54
    PORTA = ~(0b00000100);
55
    _delay_ms(DELAY);
56
    PORTA = ~(0b00001100);
57
    _delay_ms(DELAY);
58
    PORTA = ~(0b00001000);
59
    _delay_ms(DELAY);
60
    PORTA = ~(0b00001001);
61
    _delay_ms(DELAY);
62
  }
63
64
}

von Ralf (Gast)


Lesenswert?

Ok, habe es herausgefunden, das Flag "RXCIE" im UCSRA-Register war nicht 
gesetzt, welches für Interrupts über UART zuständig ist.


Nun eine weitere Frage:

Mein Controller empfängt nun das Zeichen, springt auch in die 
Interrupt-Routine, leider kommt er aber aus der Interrupt-Routine nicht 
mehr raus.
(es blinken nun alle LEDs ( ~(0xFF) und ~(0x00)   ) )...

Wisst ihr woran das liegen könnte?

von Peter II (Gast)


Lesenswert?

du musst auch das zeichen abrufen was du empfangen hast.

von Ralf (Gast)


Lesenswert?

ah interessant! :)


Danke, hat geholfen.

Welch ein Mechanismus steckt denn da dahinter, dass man mitkriegt, ob 
ein Register ausgelesen wurde?


DAnke!

von Tom M. (tomm) Benutzerseite


Lesenswert?

Aus dem Datenblatt (hier zu atmegaXX8):

When the Receive Complete Interrupt Enable (RXCIEn) in UCSRnB is set, 
the USART Receive Complete interrupt will be executed as long as the 
RXCn Flag is set (provided that global inter- rupts are enabled). When 
interrupt-driven data reception is used, the receive complete routine 
must read the received data from UDRn in order to clear the RXCn Flag, 
otherwise a new interrupt will occur once the interrupt routine 
terminates.

Das RXC Flag wird gelöscht, indem die Daten abgeholt werden. Wie das in 
der Hardware verdrahtet ist - irgendwas mit FlipFlop.

von Ralf (Gast)


Lesenswert?

So...das Programm läuft jetzt soweit, allerdings habe ich noch zwei 
Problemchen:


Wenn ich die Taste "1", "2" oder "3" im Terminal drücke, dann ändert der 
Controller die Delaytime leider nicht.

Außerdem ist mein Flash jetzt schon 25 % voll! Woran liegt das?

Hier der Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <inttypes.h>
4
#include <avr/interrupt.h>
5
6
7
8
unsigned int DelayTime = 400;
9
10
void initialisiere_UART(void)
11
{
12
  UCSRB |= (1<<RXEN) | (1<<RXCIE);                         // Senden/empfangen aktivieren
13
  UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1) ;  
14
15
  UBRRH = 00;                             // Baudrate einstellen 9600 bei 8 MHz
16
  UBRRL = 51;
17
}
18
19
20
ISR (USART_RXC_vect) 
21
{
22
  char empfangenesZeichen = UDR;
23
24
  switch(empfangenesZeichen)
25
  {
26
    case '1':  DelayTime = 50;
27
          break;
28
29
    case '2':  DelayTime = 100;
30
          break;
31
32
    case '3':  DelayTime = 200;
33
          break;
34
  }
35
}
36
37
38
  
39
40
void main (void)
41
{
42
43
    DDRA = 0xFF;
44
45
  initialisiere_UART();
46
   
47
48
  sei();                  // Interrupt scharf schalten
49
50
51
  while(1)
52
  {
53
    PORTA = ~(0b00000001);
54
    _delay_ms(DelayTime);
55
    PORTA = ~(0b00000011);
56
    _delay_ms(DelayTime);
57
    PORTA = ~(0b00000010);
58
    _delay_ms(DelayTime);
59
    PORTA = ~(0b00000110);
60
    _delay_ms(DelayTime);
61
    PORTA = ~(0b00000100);
62
    _delay_ms(DelayTime);
63
    PORTA = ~(0b00001100);
64
    _delay_ms(DelayTime);
65
    PORTA = ~(0b00001000);
66
    _delay_ms(DelayTime);
67
    PORTA = ~(0b00001001);
68
    _delay_ms(DelayTime);
69
  }
70
71
}

von Falk B. (falk)


Lesenswert?

@  Ralf (Gast)

>Wenn ich die Taste "1", "2" oder "3" im Terminal drücke, dann ändert der
>Controller die Delaytime leider nicht.

Weil deine Baudrate nicht stimmt, wenn man den RC-Oszillator nutzt.

http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART

>Außerdem ist mein Flash jetzt schon 25 % voll! Woran liegt das?

Dein _delay_ms() hätte gern konstante Argumente.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29

MFG
Falk

von Arne (Gast)


Lesenswert?

> dann ändert der Controller die Delaytime leider nicht.
volatile vergessen?

von Ralf (Gast)


Lesenswert?

Jap, lag wohl an dem volatile.

Wie könnte man das mit der Delaytime machen, damit die Werte "konstant" 
werden bzw. der Flashspeicher eben nicht zu sehr belegt wird?!


Gruß

Ralf

von Falk B. (falk)


Lesenswert?

@  Ralf (Gast)

>Wie könnte man das mit der Delaytime machen, damit die Werte "konstant"
>werden bzw. der Flashspeicher eben nicht zu sehr belegt wird?!

Glotzn ofmachn, geeene Fedbemm fressen und orweidn!
1
void long_delay(uint16_t ms)
2
{
3
    for(; ms>0; ms--) _delay_ms(1);
4
}

von Ralf (Gast)


Lesenswert?

Supooo :)


Danke!

von Ralf (Gast)


Lesenswert?

Soo...Heute wollte ich dann mal wieder eine kleine Änderung am Code 
vornehmen, leider ohne Erfolg.


Da ich gerne mittels Eingabe über das Terminal von "e" und "a" (ein, 
aus) den Motor einschalten und ausschalten möchte, habe ich folgendes 
gecodet.

Leider funktioniert es aber nicht.

Anfangs soll der Motor stillstehen. Sobald ein "e" gesendet wird, soll 
der Motor eingeschaltet werden. Sobald (währenddessen) ein "a" geschickt 
wird, soll der Motor ausgeschaltet werden.
Wenn man das Board einschaltet, soll der Motor stillstehen und der 
Controller auf einen Befehl warten
.
Wo liegt mein Problem?
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <inttypes.h>
4
#include <avr/interrupt.h>
5
6
7
8
volatile int DelayTime = 20;
9
10
void initialisiere_UART(void)
11
{
12
  UCSRB |= (1<<RXEN) | (1<<RXCIE);                         // Senden/empfangen aktivieren
13
  UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1) ;  
14
15
  UBRRH = 00;                             // Baudrate einstellen 9600 bei 8 MHz
16
  UBRRL = 51;
17
}
18
19
20
ISR (USART_RXC_vect) 
21
{
22
  char empfangenesZeichen = UDR;
23
24
  switch(empfangenesZeichen)
25
  {
26
    case 'a':  motor_ausschalten();
27
          break;
28
29
    case 'e':  motor_einschalten();
30
          break;
31
    
32
    case '1':  DelayTime = 5;
33
          break;
34
35
    case '2':  DelayTime = 10;
36
          break;
37
38
    case '3':  DelayTime = 30;
39
          break;
40
  }
41
}
42
43
44
45
void motor_einschalten(void)
46
{
47
  sei();
48
  
49
  while(1)
50
  {
51
    PORTA = ~(0b00000001);
52
    _delay_ms(DelayTime);
53
    PORTA = ~(0b00000011);
54
    _delay_ms(DelayTime);
55
    PORTA = ~(0b00000010);
56
    _delay_ms(DelayTime);
57
    PORTA = ~(0b00000110);
58
    _delay_ms(DelayTime);
59
    PORTA = ~(0b00000100);
60
    _delay_ms(DelayTime);
61
    PORTA = ~(0b00001100);
62
    _delay_ms(DelayTime);
63
    PORTA = ~(0b00001000);
64
    _delay_ms(DelayTime);
65
    PORTA = ~(0b00001001);
66
    _delay_ms(DelayTime);
67
  }
68
    
69
}
70
  
71
72
void motor_ausschalten(void)
73
{
74
  
75
  sei();
76
  PORTA = ~(0x00);
77
78
}
79
80
81
82
83
void main (void)
84
{
85
    DDRA = 0xFF;
86
87
  initialisiere_UART();
88
   
89
    sei();                  // Interrupt scharf schalten
90
  
91
92
}

von Stefan E. (sternst)


Lesenswert?

Wozu sollen die sei() in motor_einschalten und motor_ausschalten gut 
sein?

_delay_ms mit einer Variable als Parameter ist ein no-go. Bitte 
Dokumentation zu der Funktion lesen.

Dein Hauptproblem hier ist aber die fehlende Endlosschleife in main.

von Ralf (Gast)


Lesenswert?

das mit der delay_ms und den Variablen habe ich bereits gelesen und 
werde es auch ändern.

Aber was ist das Problem, dass in der main keine Endlosschleife ist?
Ich schalte doch den Interrupt scharf (sei()), sodass ein Interrupt 
kommen kann wann und wie er will, oder sehe ich das falsch?


Was stimmt in meinem Code denn (außer der delay_ms) nicht , dass es 
nicht so funktioniert wie ich es gerne hätte? ;)


Gruß
Ralf

von Stefan E. (sternst)


Lesenswert?

Ralf schrieb:
> Aber was ist das Problem, dass in der main keine Endlosschleife ist?
> Ich schalte doch den Interrupt scharf (sei()), sodass ein Interrupt
> kommen kann wann und wie er will, oder sehe ich das falsch?

Aber ohne die Endlosschleife verlässt du main() (beendest also quasi das 
Programm), und der exit-Code der AVR-Libc beinhaltet ein cli(), schaltet 
also deine Interrupts gleich wieder ab.

von Ralf (Gast)


Lesenswert?

Und wie ist nun die Lösung zu meinem Problem?

von Stefan E. (sternst)


Lesenswert?

Ralf schrieb:
> Und wie ist nun die Lösung zu meinem Problem?

Ach komm, das kannst du auch alleine lösen.
Ich wiederhole das Problem nochmal:
"Du hast keine Endlosschleife in main()."

Zusätzlicher Hinweis: eine Schleife kann auch leer sein.

von Karl H. (kbuchegg)


Lesenswert?

@Ralf

>> Und wie ist nun die Lösung zu meinem Problem?
>
> Ach komm, das kannst du auch alleine lösen.
> Ich wiederhole das Problem nochmal:
> "Du hast keine Endlosschleife in main()."
>
> Zusätzlicher Hinweis: eine Schleife kann auch leer sein.

Allerdings will man das eigentlich gar nicht.

> Ach komm, das kannst du auch alleine lösen.

Wenns nur das wäre. Der ganze Programmaufbau ist Mist.
Die Arbeit kommt in die Hauptschleife in main (oder später mal in eine 
Interrupt Funktion die von einem Timer angetrieben wird). Der UART 
Interrupt wertet meinetwegen das empfangene Zeichen aus und stellt ein 
paar globale Variablen (Flags) so, dass in der Hauptschleife das 
Richtige getan wird.

Delays in einer ISR sind ein absolutes NoNo. (ausser vielleicht ganz 
kurze delays im µs Bereich). Und eine Endlosschleife in einer ISR, die 
dann wieder durch einen anderen Interrupt unterbrochen wird ... dafür 
sollte man dir den µC gleich wieder wegnehmen :-)

von Ralf (Gast)


Lesenswert?

Dass dieses Projekt wohl eines meiner Ersten mit Mikrocontrollern ist, 
solltet ihr vielleicht wissen.

Dass ihr den Controller in- und auswändig kennt, das glaube ich euch 
gerne und schätze es sehr.
Doch immer vom hohen Ross auf die "Kleinen" abfällig zu kommentieren 
finde ich nicht unbedingt angebracht a la:
> Wenns nur das wäre. Der ganze Programmaufbau ist Mist.

Traurig. Wirklich traurig.

von Karl H. (kbuchegg)


Lesenswert?

Ralf schrieb:
> Dass dieses Projekt wohl eines meiner Ersten mit Mikrocontrollern ist,
> solltet ihr vielleicht wissen.

Ist ok. Jeder muss mal anfangen

> Dass ihr den Controller in- und auswändig kennt, das glaube ich euch
> gerne und schätze es sehr.

Das hat mit 'dem Controller' an sich nichts zu tun.

> Doch immer vom hohen Ross auf die "Kleinen" abfällig zu kommentieren
> finde ich nicht unbedingt angebracht a la:
>> Wenns nur das wäre. Der ganze Programmaufbau ist Mist.
>
> Traurig. Wirklich traurig.

Aber die Wahrheit :-)
Und ob es dir gefällt oder nicht, deinem µC ist es völlig wurscht ob es 
dein erster Kontakt mit ihm ist oder nicht. Der schlägt erbarmungslos 
zu. In deinem Fall wird nach dem (geschätzten) 300sten hintereinander 
empfangenen Zeichen 'e' Schluss mit lustig sein und dein µC wird 
erbarmungslos abstürzen oder eventuell noch schlimmere Sachen machen.

Also.
Der Grundaufbau 'jedes' µC-Programmes sieht so aus
1
int main()
2
{
3
   Hardware initialisieren und einstellen
4
5
   eventuell sei(), wenn mit Interrupts gearbeitet wird
6
7
   while( 1 ) {
8
 
9
      Hier drinn wird die eigentliche Arbeit gemacht
10
11
   }
12
}

Wenn es Interrupts gibt, dann machen deren Funktionen relativ wenig 
Arbeit selber. Wenn sie auf den Rest des Programmes einen Einfluss 
haben, dann maximal so, dass sie in globalen Variablen Kennwerte 
hinterlassen, die den Programmteil in main() der innerhalb der 
Hauptschleife steht, dazu veranlassen das Richtige zu tun.
1
volatile uint8_t Irgendwas;
2
3
ISR( ... )
4
{
5
  ...
6
  Irgendwas = ...
7
}
8
9
int main()
10
{
11
   Hardware initialisieren und einstellen
12
13
   sei();
14
15
   while( 1 ) {
16
 
17
      Hier drinn wird die eigentliche Arbeit gemacht
18
19
      if( Irgendwas == ... ) {
20
        mach die spezielle Arbeit, die von der ISR angefordert wurde
21
      }
22
23
   }
24
}

Das ist dein grundsätzlicher Programmaufbau. Es gibt auch Ausnahmen und 
es gibt auch Variationen dazu. Aber die nächsten 20 bis 30 Projekte 
wirst du praktisch immer gut fahren, wenn du dich an diesen 
Programmaufbau hältst.


AVR-GCC-Tutorial

von Karl H. (kbuchegg)


Lesenswert?

1
uint8_t MotorStep[] = { 0b00000001, 0b00000011, 0b00000010, 0b00000110,
2
                        0b00000100, 0b00001100, 0b00001000, 0b00001001 };
3
uint8_t curStep;
4
5
volatile uint8_t DelayTime;
6
volatile uint8_t MotorRunning;
7
8
void delay( uint8_t ms )
9
{
10
  uint8_t i;
11
  for( i = 0; i < ms; ++i )
12
    _delay_ms( 1 );
13
}
14
15
void initialisiere_UART(void)
16
{
17
  UCSRB |= (1<<RXEN);                         // Senden/empfangen aktivieren
18
  UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);  
19
20
  UBRRH = 00;                             // Baudrate einstellen 9600 bei 8 MHz
21
  UBRRL = 51;                             // diese Konstanten besser vom Compiler
22
                                          // berechnen lassen !
23
}
24
25
ISR (USART_RXC_vect) 
26
{
27
  char empfangenesZeichen = UDR;
28
29
  switch(empfangenesZeichen)
30
  {
31
    case 'a':  MotorRunning = 0;
32
          break;
33
34
    case 'e':  MotorRunning = 1;
35
          break;
36
    
37
    case '1':  DelayTime = 5;
38
          break;
39
40
    case '2':  DelayTime = 10;
41
          break;
42
43
    case '3':  DelayTime = 30;
44
          break;
45
  }
46
}
47
48
void main (void)
49
{
50
  DDRA = 0xFF;
51
52
  MotorRunning = 0;
53
  DelayTime = 30;
54
  curStep = 0;
55
56
  initialisiere_UART();
57
   
58
  sei();                  // Interrupt scharf schalten
59
60
  while( 1 ) {
61
    if( MotorRunning ) {
62
      PORTA = ~( MotorStep[curStep] );
63
      curStep++;
64
      if( curStep == 8 )
65
        curStep = 0;
66
      delay( DelayTime );
67
    }
68
  } 
69
}

von Steffen H. (avrsteffen)


Lesenswert?

Hallo Karl Heinz

Das hast du super erklärt! Und sogar gleich eine Lösung angeboten.. Da 
hat es der Ralf aber einfach. Ob er damit jetzt noch einen Lerneffekt 
hat?

Hoffen wir es mal.

Steffen

von Steffen H. (avrsteffen)


Lesenswert?

Ach ja, wie würde es denn aussehen wenn "MotorRunning" nicht gleich ein 
ganzes Byte einnehmen würde sondern wirklich nur ein Flag (Bit) in einem 
Byte? Mal angenommen das Byte sollte "Control" heißen und das Flag 
"MotorRunning" ?

Lerne nämlich auch gerade "C"

Gruß Steffen

von Karl H. (kbuchegg)


Lesenswert?

Steffen H. schrieb:
> Ach ja, wie würde es denn aussehen wenn "MotorRunning" nicht gleich ein
> ganzes Byte einnehmen würde sondern wirklich nur ein Flag (Bit) in einem
> Byte?

Grundsätzlich ist die kleinste Einheit, die du in C ansprechen kannst 
immer ein komplettes Byte. Willst du auf einzelne Bits runter, dann 
musst du mittels | bzw & die entsprechende Bitposition ausmaskieren.

>  Mal angenommen das Byte sollte "Control" heißen und das Flag
> "MotorRunning" ?

OK. Für die Bitposition benutze ich ein #define, damit ich mir keine 
Zahlen merken muss :-) Bin ja auch schon älter und ausserdem wird so der 
Code schon mal einen ersten Schritt in Richtung selbstdokumentierend 
nehmen.
1
#define MOTOR_RUNNING 0   // Bit 0 in Control
2
volatile uint8_t  Control;
3
4
ISR( ... )
5
{
6
7
   ....
8
9
   switch 'a':
10
     Control &= ~( 1 << MOTOR_RUNNING );    // Bit löschen
11
     break;
12
13
   switch 'b'
14
     Control |= ( 1 << MOTOR_RUNNING );     // Bit setzen
15
     break;
16
17
   ....
18
}
19
20
21
....
22
23
int main()
24
{
25
  ....
26
  while( 1 ) {
27
28
    if( Control & ( 1 << MOTOR_RUNNING ) ) {
29
      ...
30
    }
31
  }
32
}

Ganz normale Bit-Setz, Bit-Lösch und Bit-Abfrage Operationen, wie sie in 
jedem Programm zu Hauf vorkommen. Nur war bei dir wahrscheinlich Bit 
setzen bzw. Bit löschen meistens auf einen Port bezogen um damit einen 
Portpin zu schalten. Aber die Syntax ist ja nicht auf Ports beschränkt. 
Die Operationen setzen bzw. löschen bzw. fragen ein Bit ab. Wo das 
zugehörige Byte herkommt interessiert ja die Operationen nicht.

von Steffen H. (avrsteffen)


Lesenswert?

Danke Karl Heinz.
Mir ist nämlich aufgefallen das in C schnell mal ein ganzes Byte für nur 
ein Bit herhalten muss. Ich finde die Lösung über nur einem Bit besser, 
da man nicht so viel Resourcen verschwendet, natürlich nur wenn noch ein 
paar Flags mehr in das Byte "Control" kommen. Also geht es in C genauso 
einfach wie in asm.

Steffen

von Karl H. (kbuchegg)


Lesenswert?

Das ist die Version, die du als C-Neuling machen wirst.

Wenn deine C-Kentnisse umfangreicher sind (werden) (Lehrbücher lesen und 
studieren!), dann wirst du das anders schreiben und dem Compiler mehr 
Arbeit aufhalsen :-)
1
struct control_ {
2
  uint8_t motorRunning : 1;
3
  uint8_t motorDirection : 1;
4
}
5
6
volatile struct control_ Control;
7
8
ISR( ... )
9
{
10
11
   ....
12
13
   switch 'a':
14
     Control.motorRunning = 1;
15
     break;
16
17
   switch 'e'_
18
     Control.motorRunning = 0;
19
     break;
20
21
   switch '+':
22
     Control.motorDirection = 0;
23
     break;
24
25
   switch '-':
26
     Control.motorDirection = 1;
27
28
   ....
29
}
30
31
....
32
33
// zur Vereinfachung der Schreibweise wieder ein paar Makros
34
#define MOTOR_RUNNING    Control.motorRunnnig
35
#define MOTOR_DIRECTION  Control.motorDirection
36
37
int main()
38
{
39
  ....
40
  while( 1 ) {
41
42
    if( MOTOR_RUNNING ) {
43
      if( MOTOR_DIRECTION ) {
44
        ...
45
      }
46
      else {
47
        ...
48
      }
49
    }
50
  }
51
}

von Karl H. (kbuchegg)


Lesenswert?

Steffen H. schrieb:
> Danke Karl Heinz.
> Mir ist nämlich aufgefallen das in C schnell mal ein ganzes Byte für nur
> ein Bit herhalten muss. Ich finde die Lösung über nur einem Bit besser,
> da man nicht so viel Resourcen verschwendet, natürlich nur wenn noch ein
> paar Flags mehr in das Byte "Control" kommen. Also geht es in C genauso
> einfach wie in asm.

Kommt drauf an.
Wenn du die Bytes im SRAM hast, dann ist es kein Problem dafür jeweils 
ein komplettes Byte zu benutzen. Wenn du den Platz nicht hast, dann muss 
man wohl oder übel zusammenlegen.

die Überlegung
* du bekommst für nicht benutztes SRAM kein Geld zurück
* Bits auszumaskieren bringt zwar ein paar Bytes SRAM, kostet
  aber immer etwas Programmcode. Umsonst ist nun mal nur der Tod

von Steffen H. (avrsteffen)


Lesenswert?

Karl Heinz Buchegger schrieb:
>* du bekommst für nicht benutztes SRAM kein Geld zurück
Da hast du Recht (-:

Aber diese Sache mit einem Struct anzugehen finde ich ja toll:
1
struct control_ {
2
  uint8_t motorRunning : 1;
3
  uint8_t motorDirection : 1;
4
}
Das sieht dann auch sehr übersichtlich aus.
1
   switch 'a':
2
     Control.motorRunning = 1;
3
     break;
4
5
   switch 'e'_
6
     Control.motorRunning = 0;
7
     break;
8
9
   switch '+':
10
     Control.motorDirection = 0;
11
     break;
12
13
   switch '-':
14
     Control.motorDirection = 1;
 -> Und wieder was dazu gelernt..

Dank an dieses tolle Forum! Hier lernt mann mehr als in manch einem 
Studium!

Weiter so..

von 2ter Gast (Gast)


Lesenswert?

1
switch 'a':
2
     Control.motorRunning = 1;
3
     break;
4
5
   switch 'e'_
6
     Control.motorRunning = 0;
7
     break;
8
9
   switch '+':
10
     Control.motorDirection = 0;
11
     break;
12
13
   switch '-':
14
     Control.motorDirection = 1;

wie hast Du das mit den switch anweisungen hinbekommen? :-)

von Ralf (Gast)


Lesenswert?

Hallo Karl-Heinz!


Vielen Dank für deinen umfangreichen Lösungsansatz, finde ich wiederum 
super, dass du mir so geholfen hast.

Ich werde den Programmablauf mal so in etwas übernehmen und testen.

Ob es für mein Referat allerdings nicht etwas zu umfangreich ist (Leute, 
die noch NIE etwas von einem Mikrocontroller gehört haben), wage ich zu 
bezweifeln :-/
Denn der Code selbst würde wohl schon die Zeit des Referats (10-12 
Minuten) sprengen.



Gruß
Ralf

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.