USART Ausgabe per hTerm am PC

  • Friedenstaube
    "Es gibt keinen Weg zum Frieden, denn Frieden ist der Weg." - Mahatma Gandhi

Hero_123

Mitglied
17 Sep 2010
183
3
18
Sprachen
  1. ANSI C
Hallo!

Mein ATMega8 sendet per USART Daten an den PC; auf dem PC verwende ich hTerm. Angezeigt wird bei hTerm (das Komma ist der Trenner - die angezeigten Werte
entsprechen den Buchstaben):

angezeigt wird:
46, 46, 47, 115, 108, 97, 118, 101,

angezeigt werden sollte:
., ., /, s, l, a, v, e,

meine USART Funktionen:



CodeBox C
/* Ausgabe der per SPI gesendete Werte ueber USART an PC */
static void sende_wert1(uint8_t *wert, uint8_t laenge) {
    uint8_t i_send;                /* Zaehlervariable fuer Senden */
    i_send = 0;
    char temp_buf[6];            /* buffer in dem Wert gespeichert wird */
    while(i_send < laenge) {
        utoa(wert[i_send], temp_buf, 10);    /* uint8_t in char wandeln */
        usart_puts(temp_buf);                /* schreib den Wert raus */
        usart_puts(", ");                    /* Komma & blank */
        i_send++;                            /* zaehl weiter */
    }
    usart_puts("\n");            /* Zeilenumbruch */
}

/* Funktion, um String auf Terminal auszugeben */
 void usart_puts(char *s) {
    while (*s) {                           /* solange nicht Stringende erreicht */
        usart_putc(*s);                    /* schreib das Zeichen aufs Terminal */
        s++;                            /* Zeichen um 1 weiter zaehlen */
    }
}

/* Funktion, um Character auf Terminal auszugeben */
 void usart_putc(unsigned char c) {
    while(!(UCSRA & (1 << UDRE))) {
    }
    UDR = c;
}



warum werden nicht die Buchstaben angezeigt bzw was muss ich ändern, damit die Buchstaben angezeigt werden? Es liegt m.E. nicht an den hTerm Einstellungen (habe schon alles ausprobiert) :confused:

mfg

Hero_123
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1,331
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Nabend,
hast Du es schon mal mit TeraTerm probiert?
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1,331
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Aus Performance Gründen würde ich Dir empfehlen eine eigene Funktion zu schreiben um auf ASCII zu convertieren.
Ist ziemlich easy. Es sei denn du benötigst die Funktion noch irgendwo für was anderes?
 

Mikro23

Aktives Mitglied
2 Jan 2017
378
33
28
Großraum Hannover
Sprachen
  1. ANSI C
  2. Assembler
utoa(...) wandelt einen Zahlwert in den ASCII-Wert der Ziffern um.

Aus ‘L‘ zur Basis 10 wird die Zeichenkette “76“.
Aus ‘L‘ zur Basis 16 wird die Zeichenkette “4C“.
Aus ‘L‘ zur Basis 2 wird die Zeichenkette “1001100“ etc.

Nimm

CodeBox C
sprintf(buffer, “%c“, wert);

Da kannst Du auch gleich noch das Komma ranhängen.


CodeBox C
sprintf(buffer, “%c, “, wert);

(Obwohl – wenn Du schon den ASCII-Wert als Zahl hast, kannst Du ihn auch mit putc(…) direkt ausgeben...)
 
Zuletzt bearbeitet:

Janiiix3

Aktives Mitglied
28 Sep 2013
1,331
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#

Dirk

Administrator
Teammitglied
28 Jan 2007
4,327
159
63
Mittelhessen, Giessen
Sprachen
  1. ANSI C
  2. C++
  3. C#
  4. Java
  5. Kotlin
  6. Pascal
  7. Assembler
  8. PHP
Hallo,

ja "umgewandelt" werden muss nichts. HTerm ist auf ASCII Ausgabe eingestellt und dann einfach direkt die Zeichen übertragen.



CodeBox C
void usart_puts(char *s)  // einen ganzen String
void usart_putc(unsigned char c)  // ein einzelnes Zeichen

utoa() ist ein Schritt zu viel, siehe auch die Erläuterung von @Mikro23
utoa(...) wandelt einen Zahlwert in den ASCII-Wert der Ziffern um.


Dirk :ciao:
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1,331
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
ja "umgewandelt" werden muss nichts.
Wenn er seine Integer Werte nicht in einen String oder druckbare Zeichen umwandelt, wird er mit seiner aktuellen Ausgabe Funktion nicht viel Spaß haben.
 

Dirk

Administrator
Teammitglied
28 Jan 2007
4,327
159
63
Mittelhessen, Giessen
Sprachen
  1. ANSI C
  2. C++
  3. C#
  4. Java
  5. Kotlin
  6. Pascal
  7. Assembler
  8. PHP
Hallo Jan,

anscheinend soll nur ein String ausgegeben werden, direkt ascii.
angezeigt wird:
46, 46, 47, 115, 108, 97, 118, 101,

angezeigt werden sollte:
., ., /, s, l, a, v, e,

Grund für das Problem ist die "Umwandlung" zur Basis 10 mit utoa für jedes Zeichen und die Ausgabe des Ergebnisses als String.

Wenn natürlich ein Integerwert als äquivalenter Ascii String ausgegeben werden soll, muss man "umwandeln".
 

Hero_123

Mitglied
17 Sep 2010
183
3
18
Sprachen
  1. ANSI C
Hallo Dirk, hallo Mikro23, hallo Janiix3

Vielen Dank für Eure Hilfe!

Zu meinem "Problem" - auf Tastendruck schickt mein Slave ATMeg8 den Filenamen und das Datum per SPI an den Master ATMega8, dieser gibt dann den Filenamen und das Datum am PC und auf einem LCD Display aus.

Der Slave schickt diese Daten als uint8_t Werte per SPI und beim Master müssen diese Werte eben dann umgewandelt werden, damit der String ausgegeben werden kann...

Mit der von Mikro23 vorgeschlagenen Lösung
Nimm

CodeBox C
sprintf(buffer, “%c“, wert);

funktioniert es (Anzeige der Buchstaben), aber der Code wird um einiges größer (von ca 2800 byte wächst er auf ca 3800 byte ...)

mfg

Hero_123
 

Mikro23

Aktives Mitglied
2 Jan 2017
378
33
28
Großraum Hannover
Sprachen
  1. ANSI C
  2. Assembler
aber der Code wird um einiges größer
Natürlich. Die stdio-Funktionen sind ziemlich umfangreich...

Aber wie Dirk auch schon schrieb

CodeBox C
sprintf(buffer, “%c“, wert);
usart_puts(buffer);
macht im Endeffekt nichts anderes als

CodeBox C
usart_putc(wert)
(Nur mit weniger Aufwand)
 

Hero_123

Mitglied
17 Sep 2010
183
3
18
Sprachen
  1. ANSI C
Hallo Mikro23

Vielen Dank für Deine Hilfe / Hinweis :good3:


Natürlich. Die stdio-Funktionen sind ziemlich umfangreich...

Aber wie Dirk auch schon schrieb

CodeBox C
sprintf(buffer, “%c“, wert);
usart_puts(buffer);
macht im Endeffekt nichts anderes als

CodeBox C
usart_putc(wert)
(Nur mit weniger Aufwand)

Ich habe den Hinweis von Dirk irgendwie nicht so richtig ... :(

Habe es jetzt nochmal gemäß Deinem Post #10 gemacht (mit "usart_putc(wert)" - fkt natürlich!!
Lerneffekt - genau lesen .... und eine unnötige lib kann sehr viel Speicher fressen

mfg

Hero_123
 

Hero_123

Mitglied
17 Sep 2010
183
3
18
Sprachen
  1. ANSI C
Hallo

Ich habe nun ein etwas seltsames Phänomen - ich übertrage im zyklischen Programm 20 Bytes (stehen in einem Array) mit der unter #1 aufgeführten Funktion "sende_wert1" (Aufruf ca alle 70ms); Anzeige per hTerm (mit 115200 Baud).
Wenn ich das von hTerm ausgegebene in eine Textdatei schreiben lasse (siehe "atmega8_14a.txt" unten) sind immer wieder Pausen von 16ms und ich weiß nicht, woher die kommen (z.B bei 10:51:51.373: => 10:51:51.389: oder 10:51:51.545: => 10:51:51.561)

Ist das ein Problem des hTerm / PC oder wird es durch mein Programm verursacht?
USART Senden ist per polling (im zykl. Progamm), USART Empfang durch den RXCIE - Interrupt (nutz ich aber derzeit nicht)....

verwendete ISR:
INT0 => INT0_vect
INT1 => INT1_vect
TIMER0 => TIMER0_OVF_vect
TIMER1 => TIMER1_COMPA_vect
TIMER2 => TIMER2_OVF_vect
SPI => SPI_STC_vect
USART => USART_RXC_vect

F_CPU - 3686411UL Frequenz AVR & Quartz
USART - BAUD 115200UL
I2C - SCL_CLOCK 100000L
ADC - Frequenzvorteiler 32 => 115200
SPI - (1<<SPIE)|(1<<SPE) SPI Slave Mode, SCK = CK/16 = 230400

mfg

Hero_123
 

Anhänge

  • atmega8_14a.txt
    1.3 KB · Aufrufe: 2

TommyB

Team Bitschubse
17 Mai 2010
2,151
80
48
39
127.0.0.1 ;)
Sprachen
  1. C#
  2. VB.Net
  3. LunaAVR
  4. Assembler
  5. Python
Ich weiß nicht ob es jetzt für dich zutrifft, aber generell gesagt:
Es werden ja eigentlich nur Bytes übertragen. Immer ein Byte (+Start und Stopbit). Ein anderes Frame Konstrukt ist der Hardware (dem UART, dem UART zu USB, was auch immer) unbekannt. Daher wird immer eine kleine Zeit gewartet, die Daten gesammelt (häufig nur 4 Bytes) bevor es an die Software übergeben wird (hier HTerm). Also entweder ist der Puffer voll, oder die Zeit ist um (x mS), dann Buffer weiter reichen, sonst weiter warten. Daher kann es auch zu Verzögerungen kommen.
Viel wichtiger ist ja aber ob du auch das empfängst was du empfangen solltest.

Erfahrungsgemäß: Perfektes Timing unter Windows / MacOS / Linux? Vergiss es. Irrelevant welche Anwendung. Grade durch das Multitasking *hust* wirst du nie genaue Zeiten erreichen.

Technische Information:
Irrelevant welches OS, alle agieren ähnlich. Reflektiert auf einen AVR (der ja Single-Core ist) wäre es ungefähr so:
Irgendein Timer feuert alle x mS einen Interrupt. Dann wird Anwendung 1 ausgeführt. Aber nur für x mS. Noch eine Anwendung am laufen? Dann bekommt diese jetzt Rechenzeit. ... Irgendwann gibt es keine Anwendungen mehr, also beginnt das Spiel von vorne, bis alle zurückgemeldet haben dass sie keine Arbeit mehr zu tun haben. Jetzt kann die CPU in Sleep, bis zum nächstem Interrupt.
100% exakt ist es so natürlich nicht, aber so kann man es sich vorstellen.
Streng genommen gibt es einen Message Quere der nach und nach abgearbeitet wird. Aber halt nur wenn irgendeine Core grade Zeit hat.
Und durch dieses Multitasking - was eigentlich nur ein getimtes Wechseln zwischen den Prozessen ist - bekommst du nie exakte Zeiten.
Stark vereinfacht!
 

Hero_123

Mitglied
17 Sep 2010
183
3
18
Sprachen
  1. ANSI C
Hallo TommyB

Vielen Dank für Deine Erklärung :)

Ich weiß nicht ob es jetzt für dich zutrifft, aber generell gesagt:
Es werden ja eigentlich nur Bytes übertragen. Immer ein Byte (+Start und Stopbit). Ein anderes Frame Konstrukt ist der Hardware (dem UART, dem UART zu USB, was auch immer) unbekannt. Daher wird immer eine kleine Zeit gewartet, die Daten gesammelt (häufig nur 4 Bytes) bevor es an die Software übergeben wird (hier HTerm). Also entweder ist der Puffer voll, oder die Zeit ist um (x mS), dann Buffer weiter reichen, sonst weiter warten. Daher kann es auch zu Verzögerungen kommen.
Viel wichtiger ist ja aber ob du auch das empfängst was du empfangen solltest.

Erfahrungsgemäß: Perfektes Timing unter Windows / MacOS / Linux? Vergiss es. Irrelevant welche Anwendung. Grade durch das Multitasking *hust* wirst du nie genaue Zeiten erreichen.

Das ist soweit klar, und auch, dass das perfekte Timing unter Windows etc nicht möglich ist.
Mich haben eben diese 16ms irritiert.

mfg

Hero_123
 

Hero_123

Mitglied
17 Sep 2010
183
3
18
Sprachen
  1. ANSI C
Hallo LotadaC

LA - nein, ich habe keinen - mein einziges Messgerät ist ein 10€ Multimeter :rolleyes:.
Ich weiß, damit komme ich wohl nicht allzu weit
Kannst Du einen günstigen LA / Oszi empfehlen - ich möchte nicht mehr als 100€ ausgeben, dafür werde ich wohl nichts brauchbares bekommen?

mfg

Hero_123
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3,524
68
48
Marwitz
Sprachen
  1. BascomAVR
  2. Assembler
OT:
Zu günstig kann ich nichts sagen - der Original-Saleae-Logic8, den ich damals bei Dirk gekauft habe, war für mich preiswert. Ich weiß bzw wußte, daß diverse Nachbauten die Saleae-Software nutzen (und deutlich(!!) billiger sind) - ich hatte mich trotzdem für das Original entschieden.

Egal - die Dinger gibt's nicht mehr. Die derzeit verfügbaren mit beschränkten analogen Eingängen (hatten die alten Logics gar nicht) sind meiner Erinnerung nach deutlich teurer. Ob sie es Dir wert sind, mußt Du selbst entscheiden; ich hab den alten, und werde deswegen nicht in einen neuen investieren.

Möglicherweise kann Dir jemand das mal loggen, wenn Du das HEX-File hochlädst - ich hab meinen Bastel"keller" allerdings nach dem Einzug noch nicht eingerichtet...

P.S. @Dirk : Ihr habt auch keine alten mehr, oder? Was hab ich damals eigentlich dafür bezahlt?
 

TommyB

Team Bitschubse
17 Mai 2010
2,151
80
48
39
127.0.0.1 ;)
Sprachen
  1. C#
  2. VB.Net
  3. LunaAVR
  4. Assembler
  5. Python
Ein Oszi für unter 100 wird schwierig, zumindest als Neuware (klar tuen es die 20 Jahre alten vom Flohmarkt auch noch).
Zuhause hab ich jetzt nur dieses hier, aber Vorsicht: 60€ ist preiswert, aber 1MHz Samplerate... Für Audiosignale gut genug, Bussysteme eher weniger. Dafür schön klein und portabel.

Multimeter kommen für mich nur welche mit USB in Frage. Bei mir aktuell das PeakTech 2025 (~45€), 4075 (~370€) und (leider nur Leihgabe
) 4096 (~550€).
Ein Uni-T Gerät ging postwendend zurück. Und Fluke ist 'ne ganz andere Preisklasse.

LA hab ich selber leider nicht. Aber es würde ein Saleae werden, dank @Dirk und @LotadaC ;)
Ein paar Pins auf n Logic Level zu testen sollte für jeden popeligen Controller kein Problem sein. Das Problem ist die Software die dahinter steckt und die Daten auswertet. Und da scheinen die Federführend zu sein.
 

Dirk

Administrator
Teammitglied
28 Jan 2007
4,327
159
63
Mittelhessen, Giessen
Sprachen
  1. ANSI C
  2. C++
  3. C#
  4. Java
  5. Kotlin
  6. Pascal
  7. Assembler
  8. PHP
P.S. @Dirk : Ihr habt auch keine alten mehr, oder? Was hab ich damals eigentlich dafür bezahlt?
Oh, das weiß ich nicht, da müsste ich nachschauen.

Es ist aber wahrscheinlich sowieso inzwischen für viele uninteressant, der kleinste ist anscheinend der Logic8 und kostet 350€ (netto) und den Logic4 gibt es anscheinend nicht mehr, die "alten" Logic sowieso schon lange nicht mehr.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)