Två stopbitar på 2313

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
chille
Inlägg: 2469
Blev medlem: 25 juni 2003, 20:54:41
Ort: Stockholm
Kontakt:

Två stopbitar på 2313

Inlägg av chille »

Jag lyckas inte få ut något vettigt ur databladet. Hur gör man för att få två stopbitar på en 2313? :(

Det skabbar lite när man ska ta emot, speciellt när många bytes skickas på rad. Sägs ska funka bättre med två stopbitar.
Användarvisningsbild
rickeboy
Inlägg: 678
Blev medlem: 13 augusti 2003, 09:12:17
Ort: Göteborg / Karlskrona
Kontakt:

Inlägg av rickeboy »

Har inte svaret har dock en förfrågan om man skulle kunna få se lite exempel på hur du har gjort med UART koden etc... om du nu skriver i C förstås :)

Du kanske har för hög baud och att det är det som gör att mottagaren inte hinner med typ... en gissning dock... :)

//Rille
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Om det är för att förbättra mottagningen på 2313'en så kan du lika gärna låta den stå kvar på 1 stopbit, det viktiga är att du ställer om den enhet (PC?) som sänder till 2 stoppbitar.

När 2313'en har tagit emot en stoppbit så är ju den glad och nöjd och signalerar att det finns data att hämta. Sedan skickar ju PC'n ut en stoppbit till vilket 2313'en ignorerar vilket gör att den har ytterligare en bit-period på sig att processera datat.
Michel
Inlägg: 436
Blev medlem: 3 februari 2004, 18:08:04
Ort: Stockholm

Inlägg av Michel »

Snackar vi UART (rs232) kommunikation?
Om inte - glöm allt nedan
:oops:
---

Är du säker på att du inte menar pariteten?
Paritetsbiten användes på hedenhös tid för att upptäcka fel i kommunikationen.

Normalt så brukar man köra med 8N1 (8 databitar, ingen paritet, 1 stoppbit)
Eventuellt kan du initiera UARTen till att köra med en paritetsbit och då blir data 1 bitlängd längre.
Lite mer tid att processa föregående byte, men ligger du så nära gränsen bör man nog även titta på optimeringar av koden.


Hur fort kör du?
Hur fort går processorn?
Använder du pollad eller interruptbaserad kommunikation?
Hur mycket saker / vad gör du i interruptrutinen?
Kommer dina seriedata i block eller kontinuerligt?

Som nämnts ovan - om möjligt, ge oss lite exempelkod så vi ser vad du försöker göra.[/i]
Användarvisningsbild
chille
Inlägg: 2469
Blev medlem: 25 juni 2003, 20:54:41
Ort: Stockholm
Kontakt:

Inlägg av chille »

Okej. Kan inte svara på alla frågor just nu, men jag kompletterar väl tråden om en timma.

Kör 19200 8N2 (µC:n är konfad för 1stop bit, PC:n skickar två). Körde 9600 baud förut med samma problem, nästan lite problem mer tror jag. Tar emot datat via interrupt. Interruptrutinen är en enkel som först tar emot en byte (som anger storleken på paketet), sen fyller den en buffer med resterande bytes. Skickar jag i block verkar det funka OK så länge jag inte skickar enbart 0xFF i blocket. Skickar jag kontinuerligt så skabbar det lite. Och i värsta fall hänger UART:en sig medans resterande kod funkar lite halvt.

Tänkte först också det var interruptrutinen som var för lång. Men jag kortade ner den till max 100 klockcykler (uppskattar jag det till) och den krånglar fortfarnade. Lite snabb räkning säger att det finns ungefär 10k klockcykler per byte UART:en tar emot att bearbeta datan med.


Några saker som står på todolistan att testa nu:
Paritetsbit
Konfa µC:n för två stopbitar
Lägga in lite exmpelkod här :-)
Plocka bort all kod utom UART-delen för att se om det _kan_ vara något annat som krånglar.

Ett fulhack är ju helt enkelt att inte låta PC:n flooda som stryk ibland. Men jag vill gärna skriva koden ordentligt, så jag vet hur jag ska lösa det nästa gång jag stöter på samma problem.

EDIT:
När jag tänker efter så körs den i 4MHz med en vanlig kristall + kondingar. Kanske man skulle hänga på en 8MHz resonator? Hade vart bra med en 10MHz dock, då det är maxhastigheten på en 2313.

Kod: Markera allt

.equ SPEED         = 4		; CPU Speed
.equ BAUD          = 19200	; Baudrate
	; Initialize UART
	ldi	temp, ((SPEED * 1000000) / (16 * BAUD)) - 1
	out	UBRR, TEMP
	ldi	TEMP, (1<<RXCIE)+(1<<RXEN)+(1<<TXEN)
	out	UCR,TEMP

Kod: Markera allt

;---------------------------------------
; UART Recieve

UART_RXC:
	; Push registers and sreg
	push TEMP
	in TEMP, SREG
	push TEMP

	; Recieve
	in	TEMP, UDR			; Get the serial input data

	tst BUFPOS				; Test for 0
	brne bufadd				; If not, fill into it

	; Start fill buffer
	mov BUFPOS, TEMP		; Recieve TEMP bytes..
	ldi ZL, low(buffer)		; .. Save at this position
	ldi ZH, high(buffer)	;
	
	rjmp RXC_RETURN			; Return

bufadd:
	st Z+, TEMP				; Save to buffer
	dec BUFPOS				; Decrease buffer pointer
	tst BUFPOS				; If buffer = 0
	breq nisseapa			; If recieved everything, parse
	rjmp RXC_RETURN

nisseapa:
	ser PAR   ; Parsa skiten om den här är satt. förut anropade jag rutinen direkt här, men jag kortade ner den och gjorde anropet utanför interrupten

	; Pop registers and sreg
RXC_RETURN:
	pop TEMP
	out SREG, TEMP
	pop TEMP
	reti
Användarvisningsbild
erixon
Inlägg: 380
Blev medlem: 27 augusti 2003, 10:21:58

Inlägg av erixon »

Vad har du som omvandlare mellan PC och AVR? har de jorden ansluten mellan varan?

Det låter mer som signalen melllan PC och AVR är kass om inte baudraten är helt åt skogen....

Jag kan aldrig påmina mej om att haft problem med uarten på AVR mot PC...
Michel
Inlägg: 436
Blev medlem: 3 februari 2004, 18:08:04
Ort: Stockholm

Inlägg av Michel »

Jag är förbryllad över dina '2 stoppbitar'.

Startbiten indikerar start av datat.
Stoppbiten markerar slutet av datat.
Däremellan kan man ha 7 eller 8 databitar samt paritet eller ingen paritet.

En 'alternativ standard' som finns på vissa uart's - är 1 startbit, 8 databitar, 1 programmerbar bit och 1 stoppbit.
Denna mod (mode 2 på dallas 80C320 t.ex.) används ofta för att kunna addressera flera UARTS i ett master- / slav-system.

Jag antar att det bara är ett smart utnyttjande av den (normalt) oanvända paritetsbiten.

Aldrig har jag sett 2 stoppbitar.
Interruptrutinen är en enkel som först tar emot en byte (som anger storleken på paketet), sen fyller den en buffer med resterande bytes.
Skilj på 'hårdvarunivån' (uarten, RS232 protokollet samt stoppbitens vara eller icke vara) och din egen protokollnivå (meddelandelängdbyten och själva meddelandet)
Skickar jag i block verkar det funka OK så länge jag inte skickar enbart 0xFF i blocket.
Om du kan skicka allt utom just bara 0xFF helt korrekt borde det inte vara fel på överföringen - annars skulle rimligtvis alla tecken / bytes bli fel.
Skickar jag kontinuerligt så skabbar det lite. Och i värsta fall hänger UART:en sig medans resterande kod funkar lite halvt.
Låter mer som fel inställda kommunikationsparametrar.

Har du kontroll över PC programmet som skickar datat och har möjlighet att modifiera det till något 'normalt' (typ 8N1) först - för att få ordning på din mottagningskod?
Är du säker på att data 'ser bra ut' i mottagande ända? Titta på det med ett oscilloskop eller liknande. Skicka 0xAA / 0xFF då det ger signaler som är lätta att studera.
Vissa handskrivna gamla DOS-program skickade bitarna för tätt. Det finns regler för hur lång tid som måste gå mellan föregående byte's stoppbit och nästa byte's startbit.

19200 är inte så himla snabbt och du har ju samma problem vid 9600, så jag tror inte baudraten är för hög eller att det är drivkretsarna som inte hänger med.

Tar du någon matning ifrån RS232-gränssnittet?

--

Själv har jag kört i 230k en gång. Attans vad fort det gick för seriesnöret.
8)
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Det är inget att vara förbryllad över.

På en "standard" RSR232-port så är det:
Alltid 1 startbit
Mellan 5 och 8 databitar
Antingen ingen paritetsbit eller 1 partietsbit som är jämn eller udda
Och slutligen 1, 1.5 eller 2 stoppbitar.

Att det står nånstans i specen man måste ha en paus mellan varje tecken,dvs att man inte kan sända tecknena back-to-back, är nog det mest osannorlika jag sett i dag (och förmodligen resten av veckan också :-).

Du tror inte att hårdvaran skulla ta hand om en sådan viktigt fuktion om den vad nödvändig?

Det blir absolut inga problem med synkroniseringen eller något liknande med tanke på att en inaktiv linje ligger på logisk 1-nivå. Startbitten drar ner den till 0'a. Sedan följer databittarna och slutligen stopbitten som är en bitlucka med 1-nivå.

Kod: Markera allt

IDLE STAR  D0   D1   D2   D3   D4   D5   D6   D7  STOP STAR  D0 
----+    +----+----+----+----+                   +----+
    |    |                   |                   |    |
    +----+                   +----+----+----+----+    +----+----
Michel
Inlägg: 436
Blev medlem: 3 februari 2004, 18:08:04
Ort: Stockholm

Inlägg av Michel »

Och slutligen 1, 1.5 eller 2 stoppbitar.
Se där. :vissla:

Nu är du nämner det så klingar det bekant...
:oops:

Jag har dock aldrig sett någon som utnyttjar mindre än 7 databitar och mer än en stoppbit under mina +25 aktiva år.

Varför man skulle behöva mer än en stoppbit?
För 'padding' av 5 databitar?
Du tror inte att hårdvaran skulla ta hand om en sådan viktigt fuktion om den vad nödvändig?
Beror på vad det är för hårdvara / mjukvara som genererar och tar emot signalerna.

Dock kan jag hålla med om att det är ganska oväsentligt i detta fallet, eftersom det gäller en modern PC med dedikerad hårdvara.
Användarvisningsbild
chille
Inlägg: 2469
Blev medlem: 25 juni 2003, 20:54:41
Ort: Stockholm
Kontakt:

Inlägg av chille »

erixon:
Ja, PC och AVR har samma jord.

Michel:
0xFF är omöjligt att skicka. Då blir det fel direkt. Andra tal funkar bra om man inte skickar dom för fort.

Fel inställd kommunikationsparameter? Nä det tror jag inte då både AVR och PC har samma. Kör för tillfället 19200 8N2, körde 9600 8N1 förut.

Jag kollade förut med osciloskop. Men eftersom jag har ett "vanligt" så är det svårt att hinna se om det ser bra ut. Men det verkade vara en logiksignal med rätt spänningar iaf. Skulle kunna bära ner apparaten till skolan och testa med minnesosciloskopen. Då kan jag printa ut grafen och ta med hem och visa sen också :)

matseng:
Det ska inte stå i speccen att man inte kan göra så. Utan jag hade bara hört någonstans att en AVR kunde få problem om man gjorde så. Varför vet jag inte, för den borde inte tappa sync med tanke på att den har både start- och stopbitar.




Ska ut och felsöka lite mer nogrant nu. Tänkte göra så att AVR:en loopar tillbaka all data. Och även att den loopar tillbaka buffern innan den parsas. Har fortfarande inte testat att ändra partitetsbiten, så det ska jag också göra.



EDIT:
Efter diverse tester har jag konstaterat att det är min kod som är fel. Troligtvis nånstans i min rutin för att ta emot och lägga på en buffer. Hårdvaran funkar som den ska. Har loopat tillbaka ett par kilobytes utan att en enda bit blev fel :)
Skriv svar