Sida 1 av 3

Hur kan denna kod ge detta resultat

Postat: 29 november 2011, 11:17:28
av jfri
Försöker skriva ut tecken till en PC rs232 port med denna kod för PIC 18F458. Använder en 25 MHz kristall som oscillator. Nedanstående kod förväntas skriva ut bokstäverna A B C. Resultatet blir istället att ACAC skrivs ut och att char count blir 8 (använder real term serial capture program 2.0.0.70). Detta begriper jag inte.
Kan nämna att samma koppling användts för ett C program som skriver ut text med printf utan dessa problem.

Kod: Markera allt

 list p=18f458
 #include p18f458.inc
 config WDT=OFF, OSC=HS, LVP=Off, WDTPS = 128
Rst    CODE  0x00
    goto    start
START  CODE  0x20
start
    Call    Initiering
   
    movlw   'A'
    Call    Printchar  
    movlw   'B'
    Call    Printchar
    movlw   'C'
    Call    Printchar
    bsf     PORTC,RC3,0     ;Tänd LED
mainloop 
    goto    mainloop

Printchar
    bsf     TXSTA,TXEN,0
    movwf   TXREG   
    btfsc   TXSTA,TRMT      
    goto    $-2
    bsf     PORTC,RC6,0     ;Sätt RC6 TX hög
    return

Initiering
    BANKSEL PORTC
    clrf    PORTC           ;Clear output data latches
    BANKSEL TRISC
    movlw   b'10000000'     ;Config RC7 RS as input for USART use
    movwf   TRISC
    BANKSEL PORTC
    movlw   b'01000000'     ;Sätt RC6 TX hög
    movwf   PORTC
    BANKSEL ADCON1
    movlw   b'10000000'     ;Right justified result
    movwf   ADCON1          ;Konfigurera alla AD pinnar till analoga
    BANKSEL ADCON0
    movlw   b'00111001'     ;Select AN7 ADC On
    movwf   ADCON0
    BANKSEL CMCON
    movwf   CMCON           ;Comparator off
    BANKSEL TRISD
    movlw   b'00000000'     ;Hela Port D utgång till DA
    movwf   TRISD
    BANKSEL TRISE
    movlw   b'00000100'     ;RE2 används som ADC
    movwf   TRISE
    ;USART
    movlw   b'10000000'
    movwf   RCSTA           ;Enable serial port
    movlw   b'00000110'
    movwf   TXSTA           ;BRGH=1 SYNC=0
    movlw   d'26'
    movwf   SPBRG           ;for 57600 baud
    return
 END


Re: Hur kan denna kod ge detta resultat

Postat: 29 november 2011, 11:45:59
av Icecap
Skulle precis svara men så hur koden är skrivit och då föll det.

Mina hatobjekt:
goto $-2 ; Är det problem att göra en label istället?

bsf TXSTA,TXEN,0 ; Den ska finnas i initieringen! Inte i utskriftrutinen!

bsf PORTC,RC6,0 ;Sätt RC6 TX hög ; Varför då? Den är ju redan hög! Det är vid initieringen man ska sätta den hög!

Re: Hur kan denna kod ge detta resultat

Postat: 29 november 2011, 11:47:52
av sodjan
> Resultatet blir istället att ACAC skrivs ut och att char count blir 8

Char count, är det något som RealTerm räknar ?
Kan du ställa om RealTerm i något "hexdump" läge så att
du ser vad dessa 8 tecken består av ?

> bsf PORTC,RC6,0 ;Sätt RC6 TX hög

Varför ?

Re: Hur kan denna kod ge detta resultat

Postat: 30 november 2011, 09:00:22
av jfri
Icecap skrev: Mina hatobjekt:
goto $-2 ; Är det problem att göra en label istället?
Inte mitt hatobjekt. Behöver skriva mer för att använda labels och det kan bli väldigt många labels i ett program om man har många sådana här små loopar.
Icecap skrev:
bsf TXSTA,TXEN,0 ; Den ska finnas i initieringen! Inte i utskriftrutinen!

bsf PORTC,RC6,0 ;Sätt RC6 TX hög ; Varför då? Den är ju redan hög! Det är vid initieringen man ska sätta den hög!
Har ändrat det men resultatet är detsamma

Re: Hur kan denna kod ge detta resultat

Postat: 30 november 2011, 09:06:44
av jfri
sodjan skrev:> Resultatet blir istället att ACAC skrivs ut och att char count blir 8

Char count, är det något som RealTerm räknar ?
Kan du ställa om RealTerm i något "hexdump" läge så att
du ser vad dessa 8 tecken består av ?
?
Ja så förstår jag det. Om jag ändrar display as till hex så skrivs hex koderna ut för tecknen ACAC men char count blir då 4. Har sett att det finns två ascii val (förstår inte varför). Det ena av dessa ger ett char count dubbelt så stort som antalet skrivna tecken.
sodjan skrev:>
> bsf PORTC,RC6,0 ;Sätt RC6 TX hög

Varför ?
En start bit ska vara hög och gå låg. Har för mig att i ett gammalt program jag gjort behövde detta göras för att det skulle fungera.

Re: Hur kan denna kod ge detta resultat

Postat: 30 november 2011, 09:19:50
av sodjan
> Har sett att det finns två ascii val (förstår inte varför).

Unicode ?

> En start bit ska vara hög och gå låg. Har för mig att i ett gammalt program jag gjort behövde detta göras för att det skulle fungera.

Glöm det där. USART'en sköter allt på rätt sätt. Försök inte "hjälpa" den...

När du ändrade och skrev något annat än "ABC", vad fick du då ?
För det har du väl gjort ? Det gäller ju att hitta ett mönster i det hela...

Re: Hur kan denna kod ge detta resultat

Postat: 30 november 2011, 11:43:14
av jfri
T.ex om jag skriver A B C D så blir resultatet A D A D. Skriver jag bara två tecken A B så blir det A B A B. Lägger jag in raderna för att skriva C D inuti loopen så skrevs bara en massa C ut. Vid försök att en gång skriva ABCDEF skrevs istället FAFA

Re: Hur kan denna kod ge detta resultat

Postat: 30 november 2011, 11:56:59
av sodjan
Låter som något timing strul.
Antingen har du fel när du kollar att/om USART'en är ledig
eller så är det baudrate fel (inte så troligt, det verkar stämma).

Om du lägger in en rejäl delay mellan varje tecken så att det
inte enbart är sänd-flaggan som styr, vad händer då ?
(Och har du inte testat det redan ?)

Vad *har* du egentligen gjort för felsökning ?

Re: Hur kan denna kod ge detta resultat

Postat: 30 november 2011, 12:46:29
av Nerre
Oscilloskop är guld när man felsöker sånt där. Bara att skicka samma tecken oavbrutet.

Jag skrev en fungerande serieportsrutin i assembler till ABC80 när jag gick på högstadiet, så det är inte så himla komplext. Den körde visserligen bara 300 bps, men där använde jag alltså inte ens en UART utan bitbangade. (Assemblerrutinen anropades sen från basic för att skicka och ta emot tecken, tror vi pollade vid mottagning t.o.m.)

Har du kollat i hedumpen vad du får för värden och skrivit upp dem i binär form för att se?

Att skicka A (0x40) är kanske inte smartaste för felsökning. Det är ju 0100000 binärt.

0x0F (Ctrl-O), 0x33 ("3")och 0x55 ("U") kan vara vettigare mönster att testa med. Fast då måste du ju köra hexdumpläget när du tar emot.

Binärt blir de:
0x0F=00001111
0x33=00110011
0x55=01010101

Då är det lättare att se om det är timingfel, om bitar blir förskjutna eller överlappar.

Re: Hur kan denna kod ge detta resultat

Postat: 30 november 2011, 14:02:34
av jesse
Det tycks gå långsamt framåt här.... Har det hänt något?
Blir det bättre med t.ex. 10 ms fördröjning mellan varje tecken?

Skriv ut en lägre sträng (t.ex. "Hello World\n") , dröj i en sekund och upprepa.
Vad är det för baudrate?

Re: Hur kan denna kod ge detta resultat

Postat: 30 november 2011, 14:43:57
av sodjan
> Blir det bättre med t.ex. 10 ms fördröjning mellan varje tecken?

Jag skrev :

> Om du lägger in en rejäl delay mellan varje tecken så att det
> inte enbart är sänd-flaggan som styr, vad händer då ?

Är det inte (i princip) samma sak ?

> Vad är det för baudrate?

Från förstainlägget :

> movlw d'26'
> movwf SPBRG ;for 57600 baud

En rellevant fråga är ju så klart om fenomenet är *oberoende* av baudrate.

Men det är ju också en sådan där skitsak som man så klart testar *innan*
man kastar sig över ett forum...

Re: Hur kan denna kod ge detta resultat

Postat: 1 december 2011, 10:08:53
av jfri
sodjan skrev:Låter som något timing strul.
Antingen har du fel när du kollar att/om USART'en är ledig
eller så är det baudrate fel (inte så troligt, det verkar stämma).

Om du lägger in en rejäl delay mellan varje tecken så att det
inte enbart är sänd-flaggan som styr, vad händer då ?
(Och har du inte testat det redan ?)

Vad *har* du egentligen gjort för felsökning ?
Jag har försökt med 9600 baud (samma konstiga resultat) och att skriva ut olika antal skilda tecken både i och utanför loopen för att kunna se ett mönster i det hela. Och jag ser faktiskt inget mönster. Endast en del av mina tecken skrivs ut och det ibland i fel ordning.
Försökte med föreslaga 0x0F 0x33 0x55 inuti loopen och fick detta hex utskrift resultat
0F 33 0F 0F 55 55 33 33 0F 55 55 55 33 0F 0F 55 FF
Har inte ännu försökt med delay mellan varje tecken (jo bortsett från ett pat NOP instruktioner). 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

Re: Hur kan denna kod ge detta resultat

Postat: 1 december 2011, 10:12:00
av Icecap
Men... det är ju en fråga om det fungerar med ett delay mellan varje tecken! Detta för att veta vari felet består.

Re: Hur kan denna kod ge detta resultat

Postat: 1 december 2011, 10:17:16
av Nerre
På den där hexutskriften ser man ju att de enskilda tecknen blir rätt, det som händer är att du tappar tecken. En modern dator ska inte ha problem med att ta emot data i 9600, så mest troligt är att du tappar tecken vid sändningen.

Som Sodjan skrev: Kan det vara så att du skriver över UARTens sändbuffert innan den hunnit sända tecknet?


Men sen menade ju inte jag att du skulle skicka de där tecknen tillsammans, utan var för sig.

Alltså först prova att skicka en massa 0x0F, sen en massa 0x33 och sen en massa 0x55. Men i det här fallet kan vi se felet ändå, inget av de där tecknen kan ju misstolkas som ett annat av dem på grund av timingfel.

Re: Hur kan denna kod ge detta resultat

Postat: 1 december 2011, 10:26:14
av bearing

Kod: Markera allt

    movwf   TXREG   
    btfsc   TXSTA,TRMT     
    goto    $-2
Betyder inte goto $-2 att den hoppar till raden movwf TXREG?
(Vilket inte är meningen, antar jag.)