Vanuit de PC stuur ik Bytes naar een PIC16F876A.
Deze bytes komen onvolledig in het register 'IN'
Alleen de honderdtal (Dec) wordt gelezen.
Voorbeeld:
Code Reg. In
---- -------
15 0
99 0
100 1
188 1
199 1
200 2
225 2
Code:
;Baud Rate = 9600, No Parity, 1 Stop Bit
bsf STATUS,RP0 ;Bank 1
movlw D'129' ;Baudrate = 9600 bps
movwf SPBRG ;
movlw B'00100100' ;BRGH = High
movwf TXSTA ;enable Async Transmission, set brgh
bcf STATUS,RP0 ;Bank 0
movlw B'10010000' ;enable Async Reception
movwf RCSTA ;
Receive bcf STATUS,RP0
btfss PIR1,RCIF
goto Receive
movf RCREG,W
movwf IN
RETURN
Wat doe ik verkeerd ?
Zo op het eerste gezicht weinig, aannemende dat je een 20 MHz Xtal gebruikt. Je test alleen niet op een overrun (als de PC al zend zonder dat de PIC ontvangt) waarmee je de UART op tilt kan helpen. Je gebruikt een level converter ?
gradtje
Ja... en toen ?
Het lijkt me in orde, op de bcf STATUS,RP0 na dan, deze hoort niet in de receive routine maar nog bij het initialiseren. Maar in dit geval mag zal dat geen invloed hebben.
Kun je ook vertellen hoe je de data verstuurt, want daar kan het ook mis gaan natuurlijk.
[Bericht gewijzigd door gradtje op ]
Ik ben net ook vanmiddag mijn eerste stapjes aan het zetten met de PIC USART. Ik ben zelf bezig op de PIC16F648A, ik neem aan dat de USART bij alle PIC16's hetzelfde werkt.
De code die ik nu heb doet wat ie moet doen, en kopieer ik hieronder in. Ik had besloten dat ik wilde starten met een simpele echo om alles te testen.
Twee dingen die in mijn code anders zijn dan in de jouwe (ik weet overigens niet of het daaraan ligt)
1. De configuratie van de USART gebeurt in mijn code in een aantal losse stapjes, zoals het is beschreven in de manual. In jouw code wordt het hele byte van de controle registers in één keer geschreven.
2. RCREG is een two-deep FIFO register. Als je dus één byte binnen hebt gehaald en je leest 'm direct uit, dan heb je niet die ene byte te pakken. Ik lees RCREG dus evt. twee keer uit.
Hoop dat je er wat aan hebt,
Frans
PROCESSOR p16f648a
INCLUDE p16f648a.inc
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC
ERRORLEVEL -302
ORG H'0000'
; 1. TRISB<1> and TRISB<2> should both be set to '1' to configure
; the RB1/RX/DT and RB2/TX/CK pins as inputs. Output drive,
; when required, will be controlled by peripheral circuitry.
BSF STATUS, RP0
BSF TRISB, 1
BSF TRISB, 2
BCF STATUS, RP0
; 2. Initialize the SPBRG register for the appropriate baud rate.
; If a high-speed baud rate is desired, set bit BRGH.
; Running at 20Mhz, 115200 Baud => SPBRG = D'10', BRGH = '1'
BSF STATUS, RP0
MOVLW D'10'
MOVWF SPBRG
BSF TXSTA, BRGH
BCF STATUS, RP0
; 3. Enable the asynchronous serial port by clearing bit SYNC and
; setting bit SPEN
BSF STATUS, RP0
BCF TXSTA, SYNC
BCF STATUS, RP0
BSF RCSTA, SPEN
; 4. We'll work without interrupts; clearing the interrupt enable flags
BSF STATUS, RP0
BCF PIE1, TXIE
BCF PIE1, RCIE
BCF STATUS, RP0
; 5. We'll use 8N1 transmission without addressing,
; clearing the 9th bit enable flags and address enable flag
BSF STATUS, RP0
BCF TXSTA, TX9
BCF STATUS, RP0
BCF RCSTA, RX9
BCF RCSTA, ADEN
; 6. Enable the transmission by setting bit TXEN. Enable reception by
; setting bit CREN
BSF STATUS, RP0
BSF TXSTA, TXEN
BCF STATUS, RP0
BSF RCSTA, CREN
main_loop
BTFSS PIR1, RCIF
GOTO $-1
MOVF RCREG, W
; Make sure we empty the two-deep FIFO register RCREG completely
BTFSC PIR1, RCIF
MOVF RCREG, W
MOVWF TXREG
BTFSS PIR1, TXIF
GOTO $-1
GOTO main_loop
END
Op 14 januari 2006 16:22:29 schreef gradtje:
Kun je ook vertellen hoe je de data verstuurt, want daar kan het ook mis gaan natuurlijk.
Met HyperTerminal en met een eigen gemaakt programmatje.
Edit:
Ik gebruik inderdaad een 20 Mhz kristal.
Deze code:
Receive bcf STATUS,RP0
btfss PIR1,RCIF
goto Receive
movf RCREG,W
movwf IN
RETURN
Vervangen door:
Receive BTFSS PIR1, RCIF
GOTO $-1
MOVF RCREG, W
;Make sure we empty the two-deep FIFO register RCREG completely
BTFSC PIR1, RCIF
MOVF RCREG, W
MOVWF TXREG
BTFSS PIR1, TXIF
GOTO $-1 ;
movwf IN ;
RETURN
Geeft geen verschil
Op 14 januari 2006 16:41:43 schreef Frans77:
1. De configuratie van de USART gebeurt in mijn code in een aantal losse stapjes, zoals het is beschreven in de manual. In jouw code wordt het hele byte van de controle registers in één keer geschreven.
Dat mag gewoon.
2. RCREG is een two-deep FIFO register. Als je dus één byte binnen hebt gehaald en je leest 'm direct uit, dan heb je niet die ene byte te pakken. Ik lees RCREG dus evt. twee keer uit.
Dat is dus gewoon niet waar, een keer lezen is genoeg, anders gooi je een ontvangen byte weg.
Kan het zijn dat er een Interrupt optreed ?
Dit werkt namelijk ook niet:
MAIN CALL Receive ;wait for a char
MOVFW IN ;Ontvangen Data in W Reg. plaatsen
;CALL send ;send the char
MOVLW D'42'; ;'*' Deze regels toegevoegd !
MOVWF IN ; Deze regels toegevoegd !
MOVFW IN ;Ontvangen Data in W Reg. plaatsen
CALL Bin2bcd ;Deze omzetten naar BCD (3 Digits)
CALL DISPLAY_1
CALL DISPLAY_2
CALL DISPLAY_3
GOTO MAIN
Uitleg:
-Er wordt 1 Byte (RS232) ingelezen
-Deze Byte wordt weer verzonden (RS232, deze komt ook aan)
-Code wordt omgezet in 3 BCD digits
-Deze op 3, 7 segm. digits tonen
Door de 2 Nieuwe regels zou de code 042 op de displays moeten komen, maar dit geeft de code 0 !
Ik heb een code van de PC naar de PIC verzonden (anders blijft deze in een lus bij 'Receive')
Er gebeurd dus iets tussen
MOVLW D'42';
en
Het aansturen van de Displays
Wat doet dit ?
;PROVIDE A SETTLING TIME FOR START UP
clrf dataL ;Korte wacht routine ?
settle decfsz dataL,F
goto settle
movf RCREG,W
movf RCREG,W
movf RCREG,W ; flush receive buffer
Probleem gevonden !
De oorzaak was een sluiting op het test bordje.
Toch nog 2 vragen:
-Waarvoor dient het stukje code net boven deze post ?
-Als ik teveel data snel achter elkaar stuur, dan loopt de verbinding vast. Hoe kan ik dat voorkomen ?
Op 14 januari 2006 21:13:45 schreef MMSoft:
-Als ik teveel data snel achter elkaar stuur, dan loopt de verbinding vast. Hoe kan ik dat voorkomen ?
Door mijn reply goed te lezen 
Ok, maar kan je iets duidelijker zijn ?
Hoe pak ik dat aan...
Dit kom ik nog wel eens tegen in voorbeelden,
waarvoor dient dit ?
;PROVIDE A SETTLING TIME FOR START UP
clrf dataL ;Korte wacht routine ?
settle decfsz dataL,F
goto settle
movf RCREG,W
movf RCREG,W
movf RCREG,W ; flush receive buffer
[Bericht gewijzigd door MMSoft op ]
Die meerdere uitlezingen van RCREG kan ik wel plaatsen; het is een 2-deep FIFO register en op deze manier wordt het helemaal leeg gemaakt. Die setteling time daarvoor begrijp ik ook niet echt.
Groeten,
Frans
T.Assies
Ik zie dingen die je nooit voor mogelijk hield. Ik maak ze mogelijk. Ik kan je pijn en lijden laten zien. In tegenslag vind ik hoop, in de verhalen die ik hoor inspiratie. Ik kan je veel vertellen. Wat ik doe? Ik ontdek. Mijn wereld is jouw wereld.
bij de laatste regel staat RETURN, ik neem aan dat recieve in het programma wordt aangeroepen. Maar de eerste keer loopt het programma er gewoon langs. En dan krijg je een RETURN zonder dat er een CALL is geweest, en dit resulteerd in een Stack underflow. Je moet dus zorgen dat je de functie recieve aanroept met een Call en er niet "gewoon langsloopt"
Videomodulator
AKA Naftebakje @Tweakers.net --- Zonder dwarsliggers geen spoor
Je moet altijd alle registers goed checken, er kan altijd wat mislopen, en dat zie je in een paar flags (in de datasheet staat wat je moet doen om te verhelpen, een buffer overflow zal bij het uitlezen van de buffer automatisch weer op nul komen bijvoorbeeld). En inderdaad, er kunnen in principe 3 bytes tegelijk binnenkomen als ik het me nog goed herinner, dus goed controleren of je alle bytes die zijn binnengekomen al hebt behandeld.
Ik heb trouwens bij mijn eerste progje (was meteen een eindwerk, allereerste ervaring met programmeren van µP) telkens de errors en dergerlijke meteen uitgezonden in het progje. Dus constant de vlaggen checken die errors aanduiden, en als er een error is deze meteen uitzenden via RS232, daardoor zie je in hyperterminal meteen wat er gebeurt (als je een moeilijk stuk maakt, elke stap een karakter terugzenden, dan weet je waar je weer een s ipv een c hebt gezet).
Onderstaande code geeft regelmatig vreemde tekens terug, de verbinding loopt nu echter niet vast !
Als ik alleen op Overrun controleer, dan loopt de verbinding regelmatig vast.
;Afvragen of de Interrupt is veroorzaakt door de USART
BTFSS INTCON,PEIE ;Peripheral Interrupt ?
GOTO M010 ;Nee (dan een Timer 2 Interrupt)
BTFSC RCSTA,FERR ;Framing Error ?
GOTO M001 ;Nee
GOTO M002 ;Ja --> USART Ressetten
M001: BTFSC RCSTA,OERR ;Overrun Error ?
GOTO IntDone ;Nee (wat was het dan ?) --> Einde
;Ja --> USART Ressetten
M002: ;USART Ressetten
BCF RCSTA,CREN ;CREN clearen (Schakel USART UIT)
BSF RCSTA,CREN ;CREN setten (Schakel USART IN )
GOTO IntDone ;Einde
M010: Timer 2 afhandeling ......