Forum: Mikrocontroller und Digitale Elektronik Integer via UART empfangen, auf 7-Segment ausgeben?


von HalloZusammen (Gast)


Lesenswert?

Hallo,

ich nutze einen EFM8 von Silabs und möchte mit meinem Code einen 
dreistelligen Integer über den UART empfangen und aufs 7-Segment Display 
ausgeben.

Der Ablauf soll in etwa so aussehen:
-Start: 000 (Display) in Schleife

- irgendwann dreistelligen Integer übergeben (momentan via Terminal 
TeraTerm, später über den UART TX eines zweiten Mikrocontrollers)

- erst wenn alle 3 Ziffern erhalten wurden, soll die aktualisierte 
Ausgabe aufs Display erfolgen. Beim Terminal würde ich gerne mit Enter 
bestätigen müssen.

- diese Ausgabe dann wieder in Schleife, bis ein neuer Wert empfangen 
wird


Schritt 1 funktioniert soweit. Wenn ich aber jetzt 3 Zahlen eingebe, 
tätigt er bei jeder Zahl eine Ausgabe ans Display, und nach der dritten 
Zahl steht obendrein nur [] [] 0 auf dem Display, was vermutlich der ISR 
zugrunde liegt. Hat jemand eine Idee, wie ich es hinbekomme, dass nur 
das dreistellige Paket "gesendet" und korrekt angezeigt wird? Danke & 
sorry für noch unausgereifte Codesegmente.

Grüße

1
// MAIN FILE
2
//-----------------------------------------------------------------------------
3
// Global Variables
4
//-----------------------------------------------------------------------------
5
6
uint8_t UART_Buffer_Size = 0;//shows actual usage/size of buffer
7
uint8_t Byte;
8
uint8_t Hunderter = 0;
9
uint8_t Zehner = 0;
10
uint8_t Einer = 0;
11
bool start = 0;
12
//-----------------------------------------------------------------------------
13
// SiLabs_Startup() Routine
14
//-----------------------------------------------------------------------------
15
void SiLabs_Startup (void)
16
{
17
18
}
19
 
20
//-----------------------------------------------------------------------------
21
// main() Routine
22
// ----------------------------------------------------------------------------
23
int main (void)
24
{
25
  //Enter default mode
26
  enter_DefaultMode_from_RESET();
27
  while(1)
28
  {
29
    if(start == 0) //start mode disabled as UART recieves data
30
    {
31
      display(Hunderter,Zehner,Einer);
32
    }
33
34
    //save UART data in display variables
35
    if(Hunderter!=UART_Buffer[0] && 0<=UART_Buffer[0]-48<=9)
36
    {
37
      Hunderter = UART_Buffer[0]-48;
38
    }
39
    if(Zehner!=UART_Buffer[1])
40
        {
41
          Zehner = UART_Buffer[1]-48;
42
        }
43
44
    if(Einer!=UART_Buffer[2])
45
        {
46
          Einer = UART_Buffer[2]-48;
47
        }
48
    //while(UART_Buffer_Size == 0)
49
    //{
50
      if(UART_Buffer_Size==2)
51
      {
52
        display(1,2,3);
53
      }
54
    //}
55
  }
56
}

Die ISR sieht folgendermaßen aus.
1
//-----------------------------------------------------------------------------
2
// Global CONSTANTS
3
//-----------------------------------------------------------------------------
4
#define UART_BUFFERSIZE        64
5
6
//-----------------------------------------------------------------------------
7
// Global Variables
8
//-----------------------------------------------------------------------------
9
10
uint8_t UART_Buffer[UART_BUFFERSIZE];
11
uint8_t UART_Input_First = 0;
12
uint8_t UART_Output_First = 0;
13
//-----------------------------------------------------------------------------
14
// UART0_ISR
15
//-------------------------------------------------------------------------
16
//
17
//-----------------------------------------------------------------------------
18
SI_INTERRUPT (UART0_ISR, UART0_IRQn)
19
{
20
  if (SCON0_RI == 1)
21
  {
22
    if( UART_Buffer_Size == 0)  {      // If new term is entered
23
     UART_Input_First = 0;    }
24
25
    SCON0_RI = 0;                           // Clear interrupt flag
26
27
    Byte = SBUF0;                      // Read a character from UART
28
29
    if (UART_Buffer_Size < UART_BUFFERSIZE)
30
    {
31
     UART_Buffer[UART_Input_First] = Byte; // Store in array
32
33
     UART_Buffer_Size++;             // Update array's size
34
35
     UART_Input_First++;             // Update counter
36
    }
37
  }
38
  if(UART_Buffer_Size>2) 
39
  {
40
    UART_Buffer_Size = 0; //reset counters
41
    UART_Input_First = 0;
42
      start = 1; //leave start mode
43
44
  }
45
}

von W.S. (Gast)


Lesenswert?

HalloZusammen schrieb:
> ich nutze einen EFM8 von Silabs und möchte mit meinem Code einen
> dreistelligen Integer über den UART empfangen und aufs 7-Segment Display
> ausgeben.

Dann tu es doch einfach!

Und wenn du das nicht aus eigener Kraft kannst, dann lerne zuvörderst 
das Programmieren.

Du wirst in deinem Leben nichts programmieren können, wenn du nicht 
zuvor das Programmieren erlernt hast. Das sollte doch klar sein.

Nochwas:
Zum Benutzen eines EFM8 oder irgend eines anderen elektronischen 
Bauteils sollte man zuvörderst soviel schaltungstechnik erlernt haben, 
daß man mit den gewählten Bauelementen tatsächlich umgehen kann.

Das ist _"essenziell"_ (um Sherlock Holmes mal einzudeutschen)

W.S.

von monkey666 (Gast)


Lesenswert?

HalloZusammen schrieb im Beitrag #5767048                    // Read a 
character from UART
>
>     if (UART_Buffer_Size < UART_BUFFERSIZE)
>     {
>      UART_Buffer[UART_Input_First] = Byte; // Store in array
>
>      UART_Buffer_Size++;             // Update array's size
>
>      UART_Input_First++;             // Update counter
>     }
>   }
>   if(UART_Buffer_Size>2)
>   {
>     UART_Buffer_Size = 0; //reset counters
>     UART_Input_First = 0;
>       start = 1; //leave start mode
>
>   }
> }

Ja, du darfst erst senden, wenn alle Zeichen vorhanden sind.
Also das letzte Zeichen Enter prüfen!

von Stefan F. (Gast)


Lesenswert?

Wenn du dein Programm mit dem Debugger schrittweise ausführst, siehst du 
sicher schnell selbst, wo es Hakt.

von HalloZusammen (Gast)


Lesenswert?

> Ja, du darfst erst senden, wenn alle Zeichen vorhanden sind.
> Also das letzte Zeichen Enter prüfen!

Hab das mal in der ASCII Tabelle gesucht. Also meinst du, es muss der 
Carriage Return als viertes Zeichen noch übergeben werden? Danke!

von HalloZusammen (Gast)


Lesenswert?

W.S. schrieb:
> HalloZusammen schrieb:
>> ich nutze einen EFM8 von Silabs und möchte mit meinem Code einen
>> dreistelligen Integer über den UART empfangen und aufs 7-Segment Display
>> ausgeben.
>
> Dann tu es doch einfach!
>
> Und wenn du das nicht aus eigener Kraft kannst, dann lerne zuvörderst
> das Programmieren.
>
> Du wirst in deinem Leben nichts programmieren können, wenn du nicht
> zuvor das Programmieren erlernt hast. Das sollte doch klar sein.
>
> Nochwas:
> Zum Benutzen eines EFM8 oder irgend eines anderen elektronischen
> Bauteils sollte man zuvörderst soviel schaltungstechnik erlernt haben,
> daß man mit den gewählten Bauelementen tatsächlich umgehen kann.
>
> Das ist _"essenziell"_ (um Sherlock Holmes mal einzudeutschen)
>
> W.S.

Eine Antwort zur Sache hätte auch gereicht, aber hier im Forum geht es 
ja bekanntlich nicht ohne.

Ich lerne schon seit relativ langer Zeit das Programmieren und versuche 
mich an Beispielen, aber wenn dann irgendwann einmal ein Brett vorm Kopf 
ist, erweitere ich hin und wieder legitimerweise mein Wissen durch das 
anderer, die schon ähnliche Projekte umgesetzt haben.

von W.S. (Gast)


Lesenswert?

HalloZusammen schrieb:
> Eine Antwort zur Sache hätte auch gereicht,

Das war eine Antwort zur Sache!

Du kannst nämlich noch immer nicht programmieren, wie du deutlich im 
Eröffnungspost dargestellt hast. Programmieren heißt nicht, irgendwelche 
Ausdrücke in irgend einer Programmiersprache hinzuschreiben, sondern 
Programmieren heißt, Software zu planen - und das möglichst richtig. 
Stattdessen hast du einfach geradeaus drauflos gewurstelt ("Der Ablauf 
soll in etwa so aussehen...")

Ja, ich weiß, systematisch vorzugehen und nicht wie ein Floh 
herumzuhüpfen, ist zum Anfang vielen Leuten eher lästig. Die wollen 
schon mal das Dach sehen, ohne die Mauern drunter und auch ohne das 
Fundament.

Also der Reihe nach:
1. lernen und dann tun, wie man den Chip sinnvoll aufsetzt. Also wie man 
den Pins des Chips die zuvor geplante Funktion zuweist und wie man den 
Takt des Ganzen aufsetzt und wie man die benötigten Peripherieteile mit 
selbigem versorgt.

2. lernen und dann tun, wie man für die nötigsten Peripherien passende 
Lowlevel-Treiber konzipiert. Für die serielle Kommunikation per UART 
oder USART eben einen Treiber, der zu sendende Daten so behandelt, daß 
man sich aus höheren Programmschichten nicht mehr um deren Details 
kümmern muß. Also zwischenspeichern, per Interrupt senden - und das 
Gleiche für den Empfangstrakt.

3. lernen und dann tun, wie man Struktur in serielle Kommunikationen 
hineinkriegt. Also entweder ein Kommandoprogramm, das ankommende Zeichen 
zu einer Kommandozeile auflaufen läßt und echot und dann beim Zeilenende 
(CR) selbige auswertet - oder für Maschinenzwecke ein anderes Verfahren, 
das so gestaltet ist, daß es selbstsynchronisierend funktioniert.

4. lernen und dann tun, wie man eine Anzeige aus 7 Segment-Elementen 
ansteuert und benutzt.

So herum wird das was, und du lernst dabei auch, systematisch 
vorzugehen.

W.S.

von monkey666 (Gast)


Lesenswert?

HalloZusammen schrieb:
> Ja, du darfst erst senden, wenn alle Zeichen vorhanden sind.
> Also das letzte Zeichen Enter prüfen!
>
> Hab das mal in der ASCII Tabelle gesucht. Also meinst du, es muss der
> Carriage Return als viertes Zeichen noch übergeben werden? Danke!

Für das was du vorhast reichts.
Du brauchst ein array der länge 5 inkl /0
Du machst eine Schleife und scannst die Zeichen.
Überpruefst ob auch als char 0-9 eingegeben wurde.
Wenn ja Eintrag in Array, sonst ignorieren.
Wenn alle Zeichen da sind, schaust du ob das letzte Zeichen den Wert von 
CR hat.
Wenn ja Daten in Array schicken.

Einfaches Programm keine Hexerei.

von monkey666 (Gast)


Lesenswert?

HalloZusammen schrieb:
>
>
> Hab das mal in der ASCII Tabelle gesucht. Also meinst du, es muss der
> Carriage Return als viertes Zeichen noch übergeben werden? Danke!

Für das was du vorhast reichts.
Du brauchst ein array der länge 5 inkl /0
Du machst eine Schleife und scannst die Zeichen.
Überpruefst ob auch als char 0-9 eingegeben wurde.
Wenn ja Eintrag in Array, sonst ignorieren.
Wenn alle Zeichen da sind, schaust du ob das letzte Zeichen den Wert von 
CR hat.
Wenn ja Daten in Array schicken.

Einfaches Programm keine Hexerei.

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.