Sida 2 av 3
Re: Hur kan denna kod ge detta resultat
Postat: 1 december 2011, 10:36:14
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
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å...
Re: Hur kan denna kod ge detta resultat
Postat: 1 december 2011, 10:36:56
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.
Re: Hur kan denna kod ge detta resultat
Postat: 1 december 2011, 10:40:44
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 ?
Re: Hur kan denna kod ge detta resultat
Postat: 1 december 2011, 10:46:01
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".
Re: Hur kan denna kod ge detta resultat
Postat: 1 december 2011, 11:52:38
av Icecap
Och i detta forum brukar det hjälpa om man testar det föreslagna sätt och svarar på frågorna...
Re: Hur kan denna kod ge detta resultat
Postat: 1 december 2011, 15:31:49
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.

Re: Hur kan denna kod ge detta resultat
Postat: 2 december 2011, 00:03:08
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?
Re: Hur kan denna kod ge detta resultat
Postat: 2 december 2011, 00:10:41
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.
Re: Hur kan denna kod ge detta resultat
Postat: 2 december 2011, 00:35:19
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.
Re: Hur kan denna kod ge detta resultat
Postat: 2 december 2011, 00:45:12
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.
Re: Hur kan denna kod ge detta resultat
Postat: 2 december 2011, 00:48:05
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.
Re: Hur kan denna kod ge detta resultat
Postat: 2 december 2011, 00:56:19
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.
Re: Hur kan denna kod ge detta resultat
Postat: 2 december 2011, 04:43:09
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.
Re: Hur kan denna kod ge detta resultat
Postat: 2 december 2011, 08:20:54
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.
Re: Hur kan denna kod ge detta resultat
Postat: 2 december 2011, 09:36:59
av bearing
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.