Hur kan denna kod ge detta resultat

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Icecap
Inlägg: 26652
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Hur kan denna kod ge detta resultat

Inlägg av Icecap »

Det är just därför man inte ska använda den sorts kodning men TS anser att det är för jobbigt att göra en label :doh:

Det är väl roligare att det inte fungerar då...

Men på PIC18 blir det nog rätt - men jag är inte säker men TS verkar vara det. Bara konstigt att det inte fungerar ändå...
Nerre
Inlägg: 27235
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Hur kan denna kod ge detta resultat

Inlägg av Nerre »

Om jag förstår rätt så har picen 16-bitars instruktioner och argumentet till goto är antal bytes, så en instruktion bakåt blir 2 bytes.

Men som nån redan påpekat, det blir mycket mindre risk att göra fel om man använder en label.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Hur kan denna kod ge detta resultat

Inlägg av sodjan »

> Betyder inte goto $-2 att den hoppar till raden movwf TXREG?

Nej !
(På en PIC16 hade det dock varit korrekt)

jfri, byt för fasen till labels så att vi i alla fall slipper denna typ
av ganska onödiga frågor!

> Detta har inte behövts vid användning av USART på andra PIC. Och med
> dom så får man väl inte den önskade hastigheten på överföringen

Du missar ju poängen totalt !
Det är ju *felsökning* vi håller på med...

> ...vid användning av USART på andra PIC.

Detta är intressant. Har *allt* varit likadant för övrigt ?
D.v.s även samma verktyg på PC sidan o.s.v ?
Nerre
Inlägg: 27235
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Hur kan denna kod ge detta resultat

Inlägg av Nerre »

En del verkar tro att felsökning kan utföras enligt "If it doesn't work, try harder".

Det brukar gå betydligt bättre med "If it doesn't work, try another way".
Användarvisningsbild
Icecap
Inlägg: 26652
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Hur kan denna kod ge detta resultat

Inlägg av Icecap »

Och i detta forum brukar det hjälpa om man testar det föreslagna sätt och svarar på frågorna...
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Re: Hur kan denna kod ge detta resultat

Inlägg av Kaggen »

Vet inte varför du (trådskaparen) kollar sänd byte med TRMT? Det borde ju iofs också gå, men den kollar ju egentligen bara om shiftregistret är ledigt. Jag (och dom exempel jag sett) brukar kolla TXIF vilket betyder att TXREG registret är tomt och kan fyllas med nästa byte. Dessutom kollar jag TXIF *innan* jag skickar nästa byte. Det blir mer tidseffektivt eftersom man vanligen gör lite annat innan man slänger på nästa byte. Annars står ju controllern och dökör efter varje byte till ingen nytta.

Min utskriftrutin efter det jag initierat allt, som jag enbart normalt bara gör vid uppstart av uC, ser ut som nedan:

Kod: Markera allt

	movlw	'A'    ;Skriv ut ett 'A'
	call	SEROUT
	return

SEROUT
	btfss	PIR1,TXIF
	bra	SEROUT

	movwf	TXREG
	return
Jag bökar inte heller med BSR flaggorna/access bitarna efter instruktionerna. Jag använder oftast inte mer än 96 bytes RAM så då fixar assemblern det automagiskt. Vet inte heller riktigt varför du bökar med bsf PORTC,RC6,0? Enda anledningen jag kan tänka mig är att du kör mot någon underlig hårdvara? USARTen brukar fixa allt sådant själv annars. Jag har kört med ovanstående kod mot ett antal Windows/Linux burkars serieportar, och det funkar utmärkt utan att behöva lägga till "fulkod".

Håller med övriga att relativa hopp (och självmodifierande kod) var coolt när man började programmera. Sedan vart programmen mer komplicerade och CPUerna fick cache. Så jag växte upp och slutade med dumheterna. :)
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: Hur kan denna kod ge detta resultat

Inlägg av jfri »

Har nu försökt med att lägga in delays mellan teckenutskrifterna. Med en delay på 256 cycler så gick det att skriva ut 5 tecken i rad. Men försöker jag med ett sjätte tecken så tappas tecken bort. Minskar jag denna fördröjning så minskas också antalet tecken som kan skrivas felfritt. Men med en delay på 256*256 så verkar det gå att skriva ut så mycket man vill. Nu är frågan hur man får utskrift att fungera utan dessa delays som rimligen inte ska behövas?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Hur kan denna kod ge detta resultat

Inlägg av sodjan »

Det hela tyder på att din kontroll av om sändaren är "ledig" är fel.

Har du bara testat med 256 och 256x256 cykler ? Inte för att det
kanske behövs, men jag gissar att gränser går vid en fördröjning
som är i stort sett lika med sändningstiden för ett tecken.

Men, som sagt, jag säger att det ganska tydligt pekar på att du har
fel i kontrollen av om sändaren är ledig...

Är det av någon speciell anledning du inte har svarat på Kaggens
inlägg här direkt innan ? Det är ju inte orimligt att du har svaret där.
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7482
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Re: Hur kan denna kod ge detta resultat

Inlägg av Marta »

Testa att lägga till en eller två NOP mellan skrivning till TXREG och att Du testar om skiftregisteret är tomt. Det tar 1 maskincykel efter skrivning innan flaggan Du testar indikerar att skiftregistret är upptaget och då har nästa istruktion möjligtvis redan läst av denna. Är osäker på om holdinregistret blir ledigt direkt, då skulle det hur som helst fungera, eller väntar på baudrateklockan innan så sker för då blir det överskrivet.

Annars gör det på rätt sätt som redan sagts. Då förbereds nästa tecken medan sändningen pågår och holdingregistret kommer till användning så tecknen skickas back-to-back. Som Du gör kan Du prestandamässigt lika väl använda en mjukvaru-UART.
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: Hur kan denna kod ge detta resultat

Inlägg av jfri »

Kaggen skrev:Vet inte varför du (trådskaparen) kollar sänd byte med TRMT? Det borde ju iofs också gå, men den kollar ju egentligen bara om shiftregistret är ledigt. Jag (och dom exempel jag sett) brukar kolla TXIF vilket betyder att TXREG registret är tomt och kan fyllas med nästa byte. Dessutom kollar jag TXIF *innan* jag skickar nästa byte. Det blir mer tidseffektivt eftersom man vanligen gör lite annat innan man slänger på nästa byte. Annars står ju controllern och dökör efter varje byte till ingen nytta.

Min utskriftrutin efter det jag initierat allt, som jag enbart normalt bara gör vid uppstart av uC, ser ut som nedan:

Kod: Markera allt

	movlw	'A'    ;Skriv ut ett 'A'
	call	SEROUT
	return

SEROUT
	btfss	PIR1,TXIF
	bra	SEROUT

	movwf	TXREG
	return
Jag bökar inte heller med BSR flaggorna/access bitarna efter instruktionerna. Jag använder oftast inte mer än 96 bytes RAM så då fixar assemblern det automagiskt. Vet inte heller riktigt varför du bökar med bsf PORTC,RC6,0? Enda anledningen jag kan tänka mig är att du kör mot någon underlig hårdvara? USARTen brukar fixa allt sådant själv annars. Jag har kört med ovanstående kod mot ett antal Windows/Linux burkars serieportar, och det funkar utmärkt utan att behöva lägga till "fulkod".

Håller med övriga att relativa hopp (och självmodifierande kod) var coolt när man började programmera. Sedan vart programmen mer komplicerade och CPUerna fick cache. Så jag växte upp och slutade med dumheterna. :)
Vad jag kommer ihåg så började jag med att testa TXIF och kunde då inte skriva ett tecken felfritt. Då testade jag med TRMT och kunde skriva ut två tecken felfritt.
Ville försäkra mig att RC6 var hög från början. Men möjligt att det inte behövs utan att UARTEn sköter detta automatiskt.
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: Hur kan denna kod ge detta resultat

Inlägg av jfri »

sodjan skrev:Det hela tyder på att din kontroll av om sändaren är "ledig" är fel.

Har du bara testat med 256 och 256x256 cykler ? Inte för att det
kanske behövs, men jag gissar att gränser går vid en fördröjning
som är i stort sett lika med sändningstiden för ett tecken.

Men, som sagt, jag säger att det ganska tydligt pekar på att du har
fel i kontrollen av om sändaren är ledig...

Är det av någon speciell anledning du inte har svarat på Kaggens
inlägg här direkt innan ? Det är ju inte orimligt att du har svaret där.
Jag missade Kaggens inlägg men har nu svarat.
Försökte med delay mindre än 256 och fick större fel redan vid 0xE0 har jag för mig.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Hur kan denna kod ge detta resultat

Inlägg av sodjan »

Du behöver normalt aldrig flippra med TX/RX pinnarna "manuellt".
USART'en sköter det.

> Försökte med delay mindre än 256 och fick större fel redan vid 0xE0 har jag för mig.

Ja visst, med det var inte det jag menade.
Du kan räkna om dina baudrate (57 Kbaud ?) till "cyckler/tecken".
Där någonstans ligger sannolikt gränsen för fungerar/fungerar inte.

57 kbaud => ca 5.700 tecken per sekund.
Eller ett tecken på ca 175 microsek.
25 Mhz => cykeltid på ca 0.16 microsekund.
175/0.16 => ca 1.100 cykler per sänt tecken.

Så vid ett delay någonstans kring 1.100 cykler bör gränsen ligga
för felfri överföring. Om det är det problem som det ser ut som.
Marta har en bra poäng också !

Generellt är det fel (som någon påpekade) att testa om bufferten
en ledig i slutet av sändrutinen. Gör det i början istället och spara tid.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Hur kan denna kod ge detta resultat

Inlägg av jesse »

Men herregud... det måste väl finnas ett standardsätt att kolla flaggan innan man skickar ett tecken?
Jag sysslar inte med PIC så jag kan inte säga hur, men man ska väl inte behöva diskutera hur det ska göras?
Det borde finnas ett sätt, och det ska vara idiotsäkert.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Hur kan denna kod ge detta resultat

Inlägg av sodjan »

Absolut, det är bara att RTFM så vet man hur man ska göra... :-)

TRMT flaggan som testas nu anger att sänd registeret är tomt och
att själva I/O pinnen är "idle".

TXIF som är vettigare att använda anger att bufferten *före*sänd
registret är ledigt och ger ett bättre "flöde". Med TRMT så används
dubbelbuffringen i princip inte alls.

TRMT använder man när man måste veta att TX linen är "tyst" t.ex om
man använder linjen till något annat eller switchar mellan flera olika
mottagare eller liknande. För smidigast sändning så kör man med TXIF
(eller kör interrupt rakt av med sändning från en ring-buffert).

Jag tycker att nuvarande kod ska skrotas helt och skrivas om från början.
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Hur kan denna kod ge detta resultat

Inlägg av bearing »

Kod: Markera allt

    movwf   TXREG   
    btfsc   TXSTA,TRMT     
    goto    $-2
Enligt databladet är TRMT 1 i vila. När skiftregistret fylls blir TRMT 0, och sedan åter 1 när shiftregistret är ledigt.
btfsc ska alltså bytas till btfss.

Figure 18-2 och 18-3 ger intrycket att det är en fördröjning mellan skrivningen till TXREG och växlingen av TRMT, men jag kan inte se det dokumenterat i text. Jag håller med Kaggen och övriga att det är bättre att inleda skrivrutinen med att kolla flaggan.

EDIT: Jag tycker också det verkar bättre att använda TXIF istället för TRMT, eftersom att TXIF tillåter att bufferten utnyttjas. Det går alltså att skriva två tecken i snabb följd utan att vänta. Om TRMT används kommer alltid bufferten stå tom, så att varje tecken måste inväntas.

Att ABC blev AC verkar helt logiskt. Först skrevs A direkt till skiftregistret. Sedan skrevs B till bufferten. Efter det skrevs B över med C i bufferten. Slutligen, när A hade skickats lästes bufferten som innehöll C in i shiftregistret.
Skriv svar