Sida 1 av 2

RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 02:39:58
av jesse
Korkad fråga, kanske, men jag börjar tröttna på mina serieportsterminalprogram i PCn. :evil:

Jag brukar ansluta mina AVR till PC via UART och använder mig av flera olika terminalprogram beroende på vilken dator / vilket OS jag har för tillfället. Det jobbiga är att alla terminalprogram verkar reagera olika på "ny rad", så jag funderat på vad som är det mest vedertagna sättet att signalera "ny rad"... alla terminaler beter sig nämligen olika, och det är inte alltid det går att ändra inställningarna.

om jag skickar '\n' som "ny rad" så kommer "HyperTerminal" att byta rad, men ej börja från början på den raden.

print("Hej\nhej\nhej");

ger

Kod: Markera allt

Hej
   hej
      hej
Då har jag ändrat till \n\r istället - print("Hej\n\rhej\n\rhej");

Kod: Markera allt

Hej
hej
hej
Men i vissa linuxterminaler tolkar både \n och \r som ny rad, var för sig... då får jag

Kod: Markera allt

Hej

hej

hej
Och då får inte texten plats i fönstret....

Jag antar att jag måste leva med detta, men vilket är det vanligaste sättet att skicka data. Det borde väl vara med bara '\n' ? Och så får man försöka anpassa terminalen därefter? (Nästa problem är väl Å,Ä och Ö :x )

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 03:35:21
av stekern
Jag antar att du menar \r\n och inte \n\r

Jag brukar ha i min putchar rutin följande kod:

Kod: Markera allt

uint8_t uart_putchar(uint8_t c) {
 
    if (c == '\n')
        uart_putchar('\r');
    ...
}
så lägger den automatiskt på \r vid \n

Annars brukar jag ofta låta mcun bara skicka \r och sen låta terminalprogrammet lägga på \n
(finns en sån inställning i hyperterminalen).
Det underlättar sen även egenskrivna tolkningsprogram som bara behöver bry sig om \r
som radbrytare (oavsett om det är windows eller linux)

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 03:46:34
av bearing
Jag är rätt säker på att den där inställningen gör att Hyperterminalen gör om LF (Line Feed '\n') till CR LF (Carriege Return with Line Feed '\r\n'). Men det är ju möjligt att den även gör om ensamma CR till CR LF.

Det är så vitt jag vet LF som används i UNIX, medans CR LF används av Microsoft.

Hittade den här artikeln som verkar bekräfta min uppfattning.
http://en.wikipedia.org/wiki/Newline

Jag ser en fördel av att CR flyttar markören till början av raden utan att flytta den nedåt, då kan man nämligen göra program som t.ex. uppdaterar aktuell rad i realtid.

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 04:22:17
av stekern
Jag är rätt säker på att den lägger på LF på CR, inställningen heter "Append line feeds to incoming line ends".
Jo, det stämmer att LF är "hoppa till början av ny rad" under unix.

Att använda CR ensamt är dock det som funkar bäst (för mig) under de flesta omständigheterna.

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 10:48:52
av jesse
stekern: trodde först att du hade kopierat min kodsnutt, den var nästan identisk... :) det är så den ser ut nu. Men den gör \n\r. Kanske kan testa att vända på den och skriva \r\n om det gör nån skillnad?

med \n\r så tycker alla mina linuxterminaler att dom ska mata fram två rader. Verkar alltså som om de tycker att även \r är en radmatning, fast den borde ignoreras.

\n är väl LF = 0x0d, och \r =CR = 0x0a ???

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 13:51:19
av sodjan
Väldigt rörigt här... :-)

Det är uppenbart att många som aldrig har sett en vanlig skrivmaskin eller
en äldre skrivarmodell har lite svårt att koppla CR res LF till "verkligheten". :-)

LF = "Line Feed", d.v.s matning av "valsen" en rad (tänkt vrida på ratten
till vänster på en vanlig skrivmaskin. Positionen där vagnen ("carriage") står
ändras alltså inte. Alltså helt enligt jesses första exempel !

CR = "Carrage Return", d.v.s retur av vagnen ("carrage") till början av raden.
CR i sig innebär ingen ny rad/line feed! Bara att skrivhuvudet/vagnen/carriage
går tillbaka till läget längst till vänster på raden.

I UNIX är LF markeringen för "new line" i filer, en sorts record-avgränsare.
Främst är det rellevant vid läsning och tolkning av just filer, där ett
ensamt LF utgör rad/post/record avgränsare. Detta blir lite av ett problem
om man t.ex kör en sådan fil direkt ut till en terminal, därav de olika
möjligheterna att automatiskt låta terminalen lägga till en CR efter varje LF.

När det gäller tolkningen av CR och LF av terminalprogram/emulatorer, så
är det rimliga default läget att det fungerar just enligt den ursprungliga
betydelsen av CR resp LF. Alltså så som jesse såg det i sina första två exempel.

Sedan så har de flesta vettiga terminalprogram/emulatorer inställningar för
att justera tokningen av CR, LF, CRLF och så vidare så att det funegrar som man vill.

> med \n\r så tycker alla mina linuxterminaler att dom ska mata fram två rader.

Ja, men det beror på att de har ett inbyggt fel för att vara enklare att använda från UNIX.
D.v.s att de gör både en CR och en LF efter ett ensamt LF.

Sen så kan det ju även vara programvaran/kompilatorn som tolkar "\n" som CRLF,
men det borde väl vara ett ensamt LF !?

> "Append line feeds to incoming line ends".

Synnerligen korkad förklaring. Vad *är* ett "line end" ??
Är det inte just ett "line feed" ("LF") ? I alla fall i UNIX...

> medans CR LF används av Microsoft.

Det har inte ett skit med Microsoft att göra !
Definitionerna av CR och LF är mycket äldre än Microsoft...

Problemet med "\n" är att det inte har en definition. Det kan generera lite
olika tecken/teckensekvenser beroende på vilken plattform det används på.

Om du vill vara helt säker så är det bättre att skriva dit h'0D' och/eller h'0A'
själv istället. Då fungerar det alltid...

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 14:22:52
av stekern
sodjan skrev:Synnerligen korkad förklaring. Vad *är* ett "line end" ??
Är det inte just ett "line feed" ("LF") ? I alla fall i UNIX...
Tjaa, det får du ta med utvecklarna av hyperterminalen, så står iaf...
sodjan skrev: Det har inte ett skit med Microsoft att göra !
Definitionerna av CR och LF är mycket äldre än Microsoft...
Att de är äldre än Microsoft hindrar väl inte att Microsoft använder det (såväl som andra)
sodjan skrev: Problemet med "\n" är att det inte har en definition. Det kan generera lite
olika tecken/teckensekvenser beroende på vilken plattform det används på.

Om du vill vara helt säker så är det bättre att skriva dit h'0D' och/eller h'0A'
själv istället. Då fungerar det alltid.
Just därför gillar jag att bara skicka '\r' eftersom det är mindre sannolikt (även om det inte är garanterat) att generera olika sekvenser
beroende på underliggande system.
Men jag håller med, vill man vara säker på värdet, skriv 0x0A eller 0x0D.
Men å andra sidan så kan ju den ospecifika '\n' eller '\r' vara bra om man vill att koden skall generera nåt vettigt på en plattform som inte använder ascii.

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 14:34:15
av blueint
\n i Unix-terminal ska ge nyrad+vänsterpositionering. Så en extra \r ska endast upprepa en vänsterpositionering och därmed inte göra någon skillnad.

I annat fall så krävs \r för vänsterpositionering och sedan \n för nyrad.

Kikar man i textfiler för MS-DOS är dom fyllda med \r\n medan unix dito har \n. I MS-DOS används dessutom Ctrl-Z som Slut-På-Fil (EOF) i många lägen, kanske försvunnet iom MS-Win.

Sen i 99,99% av fallen har jag endast sett kombinationen \r\n inte \n\r. Det kan ev ställa till det annars.

LF = Line Feed så vitt jag vet.
Utvecklarna av hyperterminal har fått saker om bakfoten. Det är iaf ett av programmen jag undviker i MS-Win miljö.

CR = \r = 0x0D
LF = \n = 0x0A

http://en.wikipedia.org/wiki/Newline

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 14:36:03
av jesse
jag får väl testa enbart \r och se hur det går... kanske den inte matar på ny rad utan bara skriver över den gamla raden? (tror nog den gör så i Windows HyperTerminal faktiskt).

Nu råkar det gå att skriva char LF = '\n'; och det innebär att den inte kan trycka in fler än ett tecken, och jag antar att det är 0x0a, enligt ASCII-tabellen.

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 16:17:31
av sodjan
> Kikar man i textfiler för MS-DOS är dom fyllda med \r\n medan unix dito har \n.

Ja, men det är en lite annan sak/fråga. D.v.s hur man "record-avgränsar" textfiler
i olika system/plattformar. Det har ingenting direkt med att göra hur en terminal
ska/bör hantera CR resp LF. Och det finns flera andra sätt att avgränsa
rader/poster/records än att ha LF eller CR/LF sist på varje rad/record.

Sen så är det så klart så att det finns kopplinger mellan filformatet i Unix
och hur en "Unix-terminal" (vad det nu är för något) hanterar det. Är det
någon speciell terminalemulator ?

> CR = \r = 0x0D
> LF = \n = 0x0A

Ja, förrutom att "\n" betyder "new line" vilket har lite olika betydelse beroende på plattform.
Det betyder inte alltid just (och enbart) 0x0A...

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 16:27:54
av blueint
Ett tips är att definiera radslut i C som "char lf[3];" och sedan använda "strcpy(lf,"\r\n");". Motsvarande i perl vore "$lf="\r\n";" samt "print "Hej".$lf;" osv..

På det sättet kan man hantera olika smaker av \r\n och koncentrera sig på andra saker i programmeringen.

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 16:41:53
av sodjan
Dessutom, så länge man håller sig inom en viss "värld" (Microsoft, Unix o.s.v)
så brukar nog de defaults som gäller där fungera help OK... :-)

Verktyg som är specifikt tänkta för att fungera över "gränser" som t.ex
FTP har i sin spec tagit hänsyn till detta och när man t.ex kör ASCII i FTP
så får man den rad-avgränsning som gäller i resp miljö på varje sida.

Andra verktyg som ZIP/UNZIP har flaggor/switchar för att (om man vet
att det är ett problem) ändra LF -> CR/LF eller tvärtom.

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 17:29:14
av säter
Får man ställa en fråga som är helt OT?

Får passa på när expertisen är på plats ang. den utökade ASCII-tabellen.

Varför används ALT-157 för Ø i Windows Anteckningar?
Medan ALT-237 används i DOS?
Är det olika tabeller?

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 17:34:58
av blueint
Finns olika "codepages" för DOS (CP850). Och antagligen samma för grafiskmiljö dito.

Re: RS232 comport: ny rad? putChar('\n');

Postat: 6 oktober 2010, 17:43:24
av sodjan
OK i denna tabell http://www.asciitabell.se/
så ligger tecknet på andra värden... :-)

PÅ denna sida http://en.wikipedia.org/wiki/%C3%98
nämns inte koderna 157 eller 237 alls...