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).Kaggen skrev:Kod: Markera allt
movlw 'A' ;Skriv ut ett 'A' call SEROUT return SEROUT btfss PIR1,TXIF bra SEROUT movwf TXREG return
Hur kan denna kod ge detta resultat
Re: Hur kan denna kod ge detta resultat
Re: Hur kan denna kod ge detta resultat
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.
Re: Hur kan denna kod ge detta resultat
Menar du så här ?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.
Kod: Markera allt
AltPrintchar
btfss TXSTA,TRMT
goto AltPrintchar
nop
nop
movwf TXREG
return
Re: Hur kan denna kod ge detta resultat
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.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.
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
Re: Hur kan denna kod ge detta resultat
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.
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.
Re: Hur kan denna kod ge detta resultat
> 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...
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...
Re: Hur kan denna kod ge detta resultat
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.
Varför skrev den ut 0123 och sedan börja om på 0 igen bara för att de här BANKSEL saknades.
Re: Hur kan denna kod ge detta resultat
>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.
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.
Re: Hur kan denna kod ge detta resultat
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
Re: Hur kan denna kod ge detta resultat
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.

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.
