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 ?

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

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"

Dit heb ik verwijderd, toch loopt de verbinding nog regelmatig vast.

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 ......