Hur kan denna kod ge detta resultat

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
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:

Kod: Markera allt

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

SEROUT
	btfss	PIR1,TXIF
	bra	SEROUT

	movwf	TXREG
	return
Har nu testat denna kod och får samma problem. Med en delay på 256 cycler mellan varje tecken sändning så fungerar det. Utan denna delay blir bare de fyra första tecknen rätt (skriver nu ut siffrorna 0-9 plus Lf Cr i mainloop).
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 »

Det kan ju inte vara något annat än en bugg i programmet, så jag föreslår att du klistrar in ditt program här.
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: Hur kan denna kod ge detta resultat

Inlägg av jfri »

Marta skrev: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.
Menar du så här ?

Kod: Markera allt

AltPrintchar
    btfss   TXSTA,TRMT
    goto    AltPrintchar
    nop
    nop
    movwf   TXREG
    return
Bara de fyra första tecknen blir rätt då. Med en delay på 256 cycler mellan varje tecken blir det dock rätt
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: Hur kan denna kod ge detta resultat

Inlägg av jfri »

bearing skrev:Det kan ju inte vara något annat än en bugg i programmet, så jag föreslår att du klistrar in ditt program här.
Här är hela mitt nuvarande program. Kommenteras delay raden bort så blir bara de fyra första tecken rätt. Gäller både Printchar och AltPrintchar.

Kod: Markera allt

list p=18f458
 #include p18f458.inc
 config WDT=OFF, OSC=HS, LVP=Off, WDTPS = 128
        udata
count   res 1       ;for delay counter
lcount  res 1       ;for long delay counter
char    res 1       ; char to be transmitted
antal   res 1       ; number of char to be transmitted

Rst    CODE  0x00
    goto    start
START  CODE  0x20
start
    Call    Initiering
 
mainloop
    movlw   '0'         ;Intiera '0' som första tecken att sända
    movwf   char
    movlw   d'10'       ;Skriv totalt 10 tecken
    movwf   antal
nextdigit
    movf    char,W      ;tecken att sända till W
    Call    AltPrintchar   ;sänd tecken
    Call    Delay
    incf    char
    decfsz  antal
    goto    nextdigit
    movlw   '\n'        ;ny rad
    Call    Printchar
    movlw   '\r'        ;och första kolumn
    Call    Printchar

    goto    mainloop

AltPrintchar
    btfss   TXSTA,TRMT
    goto    AltPrintchar
    nop
    nop
    movwf   TXREG
    return

Printchar
lbl btfss   PIR1,TXIF
    goto    lbl
    movwf   TXREG
    return

LongDelay
    Call    Delay
    BANKSEL lcount
dl  decfsz  lcount
    goto    dl
    return

Delay
    BANKSEL count
dly decfsz  count
    goto    dly
    return

Initiering
    movlw   0xFF
    movwf   count
    movwf   lcount
    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
    bsf     TXSTA,TXEN,0
    bsf     PORTC,RC6,0     ;Sätt RC6 TX hög
    return
 END

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 »

Kan det ha med banker att göra?
Det finns inte några banksel i huvudprogrammet eller printchar-rutinerna, men det finns banksel i delay-rutinerna.

Dina räknare ligger väl i en bank, och TXREG m.fl i en annan.

EDIT: Jag borde inte ge mig in i trådar om processorfamiljer jag inte kan. Hela det här programmet använder ju Access Bank, så banksel är inte nödvändiga.

EDIT2:
Jag kan inte se något fel i koden. Jag skulle som felsökning använda simulatorn för att kolla hur länge den väntar i sendchar-rutinernas loopar. Simulatorn är överhuvudtaget bra att använda för att hitta buggar.
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 »

> udata

Notera att på en PIC18 använder man "udata_acs" för att specifikt allokera
minne från "access bank". Jag är lite osäker (och MPASM manualen är inte
helt tydlig) när det gäller hur "udata" fungerar på en PIC18. Det *kan* vara
så att "udata" allokerar ur den första *bankade* minnesarean (och alltså
behöver man BANKSEL).

Verifiera att variablerna hamnar dår du tror/vill via MAP filen.

Dessutom har så få variabler så ändra bara till "udata_acs"...

Å andra sidan så kommer sannolikt allokeringen att ske från bank0 i alla fall
(d.v.s den höga halvan av bank0) så det fungerar nog ändå utan BANKSEL,
när jag funderar på det. Men det beror bara på att du har så få variabler, det
är inget som hindrar "udata" att allokera från vilken bank som helst.

Jag gissar att programmen som det ser ut just nu fungerar lika bra/dåligt
utan någon BANKSEL alls.

Men, som sagt, i just detta fall (med bara 4 variabler) så finns det ingen anledning
att inte köra med "udata_acs", men jag tror inte att det får problemet att försvinna...
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: Hur kan denna kod ge detta resultat

Inlägg av jfri »

Jo genom att lägga till BANKSEL framför mina variabler char och antal så fick jag det att fungera utan delay. Tycker dock fortfarande att felet var märkligt.
Varför skrev den ut 0123 och sedan börja om på 0 igen bara för att de här BANKSEL saknades.
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 »

>Tycker dock fortfarande...

Ge f.. i att tycka så mycket, ta reda på hur det faktiskt är istället !
Har du kollat det jag föreslog ? D.v.s att dels kolla MAP filen var variablerna
faktiskt allokeras, samt att byta "udata" mot "udata_acs" ???

> Varför skrev den ut 0123 och sedan börja om på 0 igen bara för att de här BANKSEL saknades.

Du får göra en analys av hur bankerna var satta tillsammans med vilka adresser som
char och antal faktiskt hamnade på. Om du inte vill/kan/orkar/whatever läsa MAP filen
så kan du alla fall visa den här så får vi se.

Det är självklart ingen konstigt eller märkligt med någonting alls här, det är bara att ta reda
på vad som faktiskt hände.

Jag ser också att jag nog hade ett fel i förra inlägget. Om variabler allokeras med "udata" så
misstänker jag at de först allokeras i den del av bank0 som *inte* tillhör "access bank".
D.v.s f.o.m address x'60' upp uppåt, vilket verkar vara register som hör till CAN modulen.
Om det nu är så (igen, kolla MAP filen !!) så är det knappast att rekomendera.
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: Hur kan denna kod ge detta resultat

Inlägg av jfri »

Ja genom att använda udata_acs så fungerar det. När jag gör så allokeras minnes addresser 00-03 för mina variabler. Med bara udata 0x60-0x63
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 »

Perfekt ! Då har vi svaret. :-)
Och utan BANKSEL (eller om man köra via "access bank") så mappas 0x60 - 0x63
till register RXB0CON, RXB0SIDH, RXB0SIDL och RXB0EIDH med inte helt förväntat
resultat. Eftersom inte alla bitar i dessa register är R/W (och några är inte ens
definierade, så kommer du inte att få samma resultat tillbaka som du skrev till dom.

På köpet har du sett MAP filen och lite annat bra-att-ha. :-)
Skriv svar