Répondre à la discussion
Affichage des résultats 1 à 17 sur 17

utilisation de buffer sur PIC



  1. #1
    noisyboxes

    utilisation de buffer sur PIC


    ------

    bonjour à tous,
    je voudrais savoir comment faire pour récupérer des données qui ont été stocké dans un buffer.
    je recoit des données via le module usart de mon pic16f876a que je stocke dans une buffer, incrémenté tant qu'une certaine donnée n'a pas été reçue (66).
    or j'ai besoin ensuite de toutes les données stckées en vue d'un traitement.
    problème, je ne sais pas comment faire...
    si vous pouviez m'aider!!.
    voivi mon bout de programme:

    ;DECLARATION DES VARIABLES
    ;-------------------------
    ;zone de 16 octets
    ;-----------------
    CBLOCK 0x70
    bufptr : 1 ;pointeur
    ENDC

    ;zone de 96 octets
    ;-----------------
    CBLOCK 0x110
    bufin : D'10' ;zone de stockage des données
    ENDC



    ;lire octet reçu
    ----------------
    bsf STATUS,IRP ; pointer bank 2 et 3 en indirect
    movf bufptr,w ; charger le pointeur de destination
    movwf FSR ; charger pointeur d'adresse
    movf RCREG,w ; charger l'octet recu
    movwf INDF ; sauvegarde de l'octet reçu


    ;test sur le dernier caractère (vérif trame finie)
    ;-------------------------------------------------
    movf INDF,w ; charger l'octet reçu
    xorlw 0x66 ; comparer avec dernier attendu
    btfsc STATUS,Z ; verif résultat de l'opération (identique)
    goto findemess ; si oui aller à findemess


    ;incrémenter le pointeur
    ;-----------------------
    incf bufptr,f ; incrementer pointeur
    movf FSR,w ; charger pointeur

    findemess
    movlw LOW bufin ; adresse de depart du buffer
    movwf bufptr ; prochain octet sera le premier


    merci...

    -----

  2. Publicité
  3. #2
    umfred

    Re : utilisation de buffer sur PIC

    Pour lire un "buffer" (en fait en utilisant FSR et INDF , on stocke dans la partie RAM du PIC), on procède de la même façon que l'écriture dans ce buffer sauf qu'au lieu d'écrire dedans, on lit dedans.

    ;lire octet dans le buffer
    ----------------
    bsf STATUS,IRP ; pointer bank 2 et 3 en indirect
    movf bufptr,w ; charger le pointeur de destination
    movwf FSR ; charger pointeur d'adresse
    movf INDF,W ; lire le buffer
    movwf RCREG ; stocker dans RCREG (par exemple)

  4. #3
    noisyboxes

    Re : utilisation de buffer sur PIC

    ok, merci,
    mais comment je fais pour lire l'octet suivant??
    et à quoi ça ser de declarer "bufin" dans la zone de banque2?

  5. #4
    umfred

    Re : utilisation de buffer sur PIC

    Citation Envoyé par noisyboxes Voir le message
    mais comment je fais pour lire l'octet suivant??
    il faut incrémenter soit le FSR, soit le "bufptr", comme tu as fait pour la lecture:
    ;incrémenter le pointeur
    ;-----------------------
    incf bufptr,f ; incrementer pointeur
    movf FSR,w ; charger pointeur
    et à quoi ça ser de declarer "bufin" dans la zone de banque2?
    En fait, je pense que tes données sont stockés à partir de l'adresse RAM 0x110 (en bank2) et bufin représente l'adresse de départ de la zone de stockage.

  6. #5
    noisyboxes

    Re : utilisation de buffer sur PIC

    est-ce que ce code est bon alors??
    je suis censé recevouir un caractère 61 ou 62, suivi de 66 et allumer une led en conséquence.


    ;***************************** ****************************** *****************
    ; ROUTINE TRAME reception SERIE *
    ;***************************** ****************************** *****************
    receptrame

    clrwdt ;effacer watchdog
    ;lire octet reçu
    ;----------------
    bsf STATUS,IRP ; pointer bank 2 et 3 en indirect
    movf bufptr,w ; charger le pointeur de destination
    movwf FSR ; charger pointeur d'adresse
    movf RCREG,w ; charger l'octet recu
    movwf INDF ; sauvegarde de l'octet reçu


    ;test sur le dernier caractère (vérif trame finie)
    ;-------------------------------------------------
    movf INDF,w ; charger l'octet reçu
    xorlw 0x66 ; comparer avec dernier attendu
    btfsc STATUS,Z ; verif résultat de l'opération (identique)
    goto findemess ; si oui aller à findemess


    ;incrémenter le pointeur
    ;-----------------------
    incf bufptr,f ; incrementer pointeur
    movf FSR,w ; charger pointeur
    return
    findemess
    movlw LOW bufin ; adresse de depart du buffer
    movwf bufptr ; prochain octet sera le premier
    bcf STATUS,RP0 ; passage en banque0
    return

    trait
    ; rechercher la fin du message
    ; ----------------------------
    clrwdt
    movlw LOW bufin-1 ; pointer sur début du message-1
    movwf FSR ; dans pointeur
    bsf STATUS,IRP ; pointer banques 3 et 4 en indirect
    trait2
    incf FSR,f ; pointer sur suivant
    movf INDF,w ; charger caractère
    xorlw 0x66 ; comparer
    btfss STATUS,Z ; tester si car = 0x66
    goto trait2 ; non, suivant
    decf FSR,w ; oui, prendre pointeur trouvé-1
    movwf octet1 ; sauver dans octet1
    decf FSR,w
    movwf octet2
    trait3
    movf octet1,w
    xorlw 0x61
    btfss STATUS,Z
    goto $+2
    bsf LED
    return
    xorlw 0x62
    btfss STATUS,Z
    goto $+2
    bsf LED2
    return

  7. A voir en vidéo sur Futura
  8. #6
    umfred

    Re : utilisation de buffer sur PIC

    ça m'a l'air correct.
    Néanmoins, je ne pense pas qu'il soit utile (a priori) de rechercher à nouveau la valeur 0x66 dans la partie traitement (trait), car si on a reçu cet octet, bufptr repointe directement sur le 1er octet de la trame reçu.

    une petite astuce au passage: Si tu veux savoir assez facilement si tu as reçu cette octet, tu peux utiliser l'intruction "retlw 1" et tester w au retour du sous programme appelant "receptrame"; si w=1 alors tu as reçu 0x66, sinon tu ne l'a pas reçu. (bien sur il faut faire "retlw 0" dans le cas contraire.
    Ce qui donne:
    Code:
    ;incrémenter le pointeur
    ;-----------------------
    incf bufptr,f ; incrementer pointeur
    movf FSR,w ; charger pointeur
    retlw 0 ;w=0, donc on n'a pas reçu la fin de trame
    findemess
    movlw LOW bufin ; adresse de depart du buffer
    movwf bufptr ; prochain octet sera le premier
    bcf STATUS,RP0 ; passage en banque0
    retlw 1 ;w=1, donc on a reçu la fin de trame

  9. Publicité
  10. #7
    noisyboxes

    Re : utilisation de buffer sur PIC

    merci beaucoup UMFRED de passer du temps sur mes post!!

    seulement il ya un hic, j'ai testé mon programme cet aprèm, et ça ne marche (ça aurait été trop beau...)

    et bien sur je ne comprends pas trop pourquoi...vu que je ne comprends déja pas tout sur l'histoire de ces buffers..
    j'ai donc essayé autre chose, je sauvegarde chaque octet reçu directement dans une variable.
    je me souviens plus trop mais c'est du style:


    je déclare mes variables
    octet1 : 1
    octet2 : 1 ...

    et ensuite dans mon prog je charge octet1(puis2) avec RCREG directement

    par contre je ne teste plus la fin du message (je pense que c'est impossible de cette façon...
    et ensuite je fais mon traitement tout bête, du genre si octet1=66 et octet2=62, je met LED1 à 1 et LED2 à 0 etc...
    or je ne sais pas (j'ai pas testé) si je peut faire ça avec x octet reçu,
    ça vous parez possible???
    sinon si quelqu'un peut m'éclairer encore plus sur les buffer...je suis preneur aussi!

    merci en tout cas pour tout

  11. #8
    umfred

    Re : utilisation de buffer sur PIC

    Pour voir ce qui ne marche pas, il faudrait tester en pas à pas ton programme et voir ce qu'il se passe dans les divers registres.

    je pense qu'il y a un problème à l'affection marqué en gras dans ce qui suit:
    trait
    ; rechercher la fin du message
    ; ----------------------------
    clrwdt
    movlw LOW bufin-1 ; pointer sur début du message-1
    movwf FSR ; dans pointeur
    bsf STATUS,IRP ; pointer banques 3 et 4 en indirect
    trait2
    incf FSR,f ; pointer sur suivant
    movf INDF,w ; charger caractère
    xorlw 0x66 ; comparer
    btfss STATUS,Z ; tester si car = 0x66
    goto trait2 ; non, suivant
    decf FSR,w ; oui, prendre pointeur trouvé-1
    movwf octet1 ; sauver dans octet1
    Je pense qu'à ce moment là, W= 0 car est issu de l'opération xorlw 0x66: il fait w XOR 0x66 -> W donc si W=0x66, W vaudra alors 0x00 et donc tu met 0x00 dans octet1.

    En plus, c'est plutôt l'octet2 qu'il faut que tu teste par la suite, puisque ce n'est pas l'octet qui vaut 0x66 qui t'intéresse mais l'autre

    Code:
    ;***************************** ****************************** *****************
    ; ROUTINE TRAME reception SERIE *
    ;***************************** ****************************** *****************
    receptrame
    
    clrwdt ;effacer watchdog
    ;lire octet reçu
    ;----------------
    bsf STATUS,IRP ; pointer bank 2 et 3 en indirect
    movf bufptr,w ; charger le pointeur de destination
    movwf FSR ; charger pointeur d'adresse
    movf RCREG,w ; charger l'octet recu
    movwf INDF ; sauvegarde de l'octet reçu
    
    
    ;test sur le dernier caractère (vérif trame finie)
    ;-------------------------------------------------
    movf INDF,w ; charger l'octet reçu
    xorlw 0x66 ; comparer avec dernier attendu
    btfsc STATUS,Z ; verif résultat de l'opération (identique)
    goto findemess ; si oui aller à findemess
    
    
    ;incrémenter le pointeur
    ;-----------------------
    incf bufptr,f ; incrementer pointeur
    movf FSR,w ; charger pointeur
    return
    findemess
    movlw LOW bufin ; adresse de depart du buffer
    movwf bufptr ; prochain octet sera le premier
    bcf STATUS,RP0 ; passage en banque0
    return
    
    trait
    ; rechercher la fin du message
    ; ----------------------------
    clrwdt
    movlw LOW bufin-1 ; pointer sur début du message-1
    movwf FSR ; dans pointeur
    bsf STATUS,IRP ; pointer banques 3 et 4 en indirect
    trait2
    incf FSR,f ; pointer sur suivant
    movf INDF,w ; charger caractère
    xorlw 0x66 ; comparer
    btfss STATUS,Z ; tester si car = 0x66
    goto trait2 ; non, suivant
    decf FSR,w ; oui, prendre pointeur trouvé-1
    ;movwf octet1 ; sauver dans octet1à mon avis ceci est inutile
    decf FSR,w
    movwf octet2
    trait3
    movf octet2,w
    xorlw 0x61
    btfss STATUS,Z
    goto $+2 ; moi je mettrai return aussi ici (mais c'est une histoire de goût)
    bsf LED
    return
    movf octet2,w ; à rajouter sinon tu travailles sur le résultat de l'opération 'xorlw 0x61'
    xorlw 0x62
    btfss STATUS,Z
    goto $+2 ; moi je mettrai return aussi ici (mais c'est une histoire de goût)
    bsf LED2
    return
    Teste ce code pour voir

  12. #9
    noisyboxes

    Re : utilisation de buffer sur PIC

    ok, merci
    par contre ça ne marche pas non plus ton code!
    donc j'ai encore essayé autre chose ce matin.
    Je sais que je dois recevoir 3 octets alors j'utilise un compteur. voici le code, si vous pouvez me dire ce qui ne va pas...
    je l'ai testé, il m'a allumé les bonnes LED 2 ou 3 fois, et après il est resté bloqué!je ne comprends pas

    receptrame

    clrwdt ;effacer watchdog
    clrf PORTA
    clrf PORTB
    ;tester si erreur de frame
    ;-------------------------
    btfsc RCSTA,FERR ; tester si flag à 1
    bsf PORTA,2 ; oui allumer LED

    ;lire octet reçu
    ;----------------

    movlw 3
    movwf cmptoct
    bsf STATUS,IRP ; pointer bank 2 et 3 en indirect
    movf bufptr,w ; charger le pointeur de destination
    movwf FSR ; charger pointeur d'adresse
    loop
    movf RCREG,w ; charger l'octet recu
    movwf INDF ; sauvegarde de l'octet reçu
    incf bufptr,f ; incrémenter pointeur de caractères
    movf FSR,w ; charger pointeur
    decfsz cmpt , f ; décrémenter compteur de boucles
    goto loop ; pas dernier emplacement, suivant
    return

    trait

    clrwdt
    movlw LOW bufin-1 ; pointer sur début du message-1
    movwf FSR ; dans pointeur
    bsf STATUS,IRP ; pointer banques 3 et 4 en indirect

    incf FSR,f ; pointer sur suivant
    movf INDF,w ; charger caractère
    movwf octet1
    incf FSR,w ; oui, prendre pointeur trouvé-1
    movf INDF,w ; charger caractère
    movwf octet2
    movf INDF,w ; charger caractère
    movwf octet3



    movf octet1,w
    xorlw 0x61
    btfss STATUS,Z
    goto $+3
    bsf LED
    goto $+6
    movf octet1,w
    xorlw 0x62
    btfss STATUS,Z
    goto $+2
    bsf LED2

    movf octet2,w
    xorlw 0x61
    btfss STATUS,Z
    goto $+3
    bsf PORTB,0
    goto $+6
    movf octet1,w
    xorlw 0x62
    btfss STATUS,Z
    goto $+2
    bsf PORTB,1

    movf octet3,w
    xorlw 0x61
    btfss STATUS,Z
    goto $+3
    bsf PORTB,2
    goto $+6
    movf octet3,w
    xorlw 0x62
    btfss STATUS,Z
    goto $+2
    bsf PORTB,3

    return

  13. #10
    umfred

    Re : utilisation de buffer sur PIC

    Je pense tout d'abord qu'il faut que tu mettes ton étiquette "loop" 2 lignes au dessus (juste avant "movf bufptr,w") car le FSR n'est pas incrémenté.
    Ensuite dans ta boucle de reception tu utilise un compteur qui n'est pas défini (cmpt alors que tu initialise cmptoct).
    bufptr n'a pas l'air non plus d'être initialiser au début de ce sous-programme.

    Pour voir quel est le problème, il faudrait que tu utilises le débuggeur en pas à pas, et en regardant ce qui se passe dans les registres (la fenêtre Special Features Registers pour surveiller les registres FSR, INDF, et la fenêtre File Register).

  14. #11
    umfred

    Re : utilisation de buffer sur PIC

    Voila un code qui marche a priori (j'ai tester sous mplab).
    Code:
    receptrame
    	clrwdt ;effacer watchdog
    	clrf PORTA
    	clrf PORTB
    ;tester si erreur de frame
    ;-------------------------
    	btfsc RCSTA,FERR ; tester si flag à 1
    	bsf PORTA,2 ; oui allumer LED
    
    ;lire octet reçu
    ;----------------
    	movlw 3
    	movwf cmptoct
    	bsf STATUS,IRP ; pointer bank 2 et 3 en indirect
    	movlw LOW bufin
    	movwf bufptr
    loop
    	movf bufptr,w ; charger le pointeur de destination
    	movwf FSR ; charger pointeur d'adresse
    
    	movf RCREG,w ; charger l'octet recu
    	movwf INDF ; sauvegarde de l'octet reçu
    	incf bufptr,f ; incrémenter pointeur de caractères
    	movf FSR,w ; charger pointeur
    	decfsz cmptoct , f ; décrémenter compteur de boucles
    	goto loop ; pas dernier emplacement, suivant
    	return
    
    trait
    	clrwdt
    	movlw LOW bufin ; pointer sur début du message
    	movwf FSR ; dans pointeur
    	bsf STATUS,IRP ; pointer banques 3 et 4 en indirect
    	movf INDF,w ; charger caractère
    	movwf octet1
    	incf FSR,f ; oui, prendre pointeur trouvé-1
    	movf INDF,w ; charger caractère
    	movwf octet2
    	incf FSR,f
    	movf INDF,w ; charger caractère
    	movwf octet3
    	
    	movf octet1,w
    	xorlw 0x61
    	btfss STATUS,Z
    	goto $+3
    	bsf LED
    	goto $+6
    	movf octet1,w
    	xorlw 0x62
    	btfss STATUS,Z
    	goto $+2
    	bsf LED2
    	
    	movf octet2,w
    	xorlw 0x61
    	btfss STATUS,Z
    	goto $+3
    	bsf PORTB,0
    	goto $+6
    	movf octet2,w
    	xorlw 0x62
    	btfss STATUS,Z
    	goto $+2
    	bsf PORTB,1
    	
    	movf octet3,w ;je sais pas l'intéret de tester l'octet3vu que d'après ce que j'ai compris il vaut toujours 0x66
    	xorlw 0x61
    	btfss STATUS,Z
    	goto $+3
    	bsf PORTB,2
    	goto $+6
    	movf octet3,w
    	xorlw 0x62
    	btfss STATUS,Z
    	goto $+2
    	bsf PORTB,3
    	
    	return

  15. #12
    noisyboxes

    Re : utilisation de buffer sur PIC

    j'ai testé ton code, masi j'ai toujours ces erreur d'overflow que je n'arrive pas à éliminer.
    sinon j'ai abandonné le fait que l'octet 3 était égal à 66, c'est pour ça que je le teste quand même dans ma routine de traitement.

  16. Publicité
  17. #13
    umfred

    Re : utilisation de buffer sur PIC

    Si tu as seulement ce code, c'est normal car tu sort des fonction avec des return qui "dépilent" le stack (emplacement ou sont stockées les adresses de retour de sous programmes).
    Pour faire fonctionner juste ce code, il faut faire des appels à ces fonctions à un endroit donné. je te donne le fichier que j'ai fait pour tester.
    Untitled.asm.txt

  18. #14
    noisyboxes

    Re : utilisation de buffer sur PIC

    tinket je rajouter ton code dans mon programme, qui lui même faisait appel aux fonctions en question.
    j'ai encore testé, mais j'ai toujours ces erreurs d'overflow qui font que àprès un evoi de 3 octets le prog se bloque si je désactive pas l'erreur d'overflow...
    si t'as une solution...
    merci quand même

  19. #15
    umfred

    Re : utilisation de buffer sur PIC

    Avec ton code d'origine, la fonction receptrame était appelé à chaque fois qu'on recevait un octet. Maintenant, ce n'est plus le cas, car tu lis 3 fois le registre avant de sortir.
    Remet l'ancien code de la fonction receptrame (il me semble OK) change éventuellement la condition d'arrêt (le code 0x66), et tu ne devrais plus avoir de overflow (c'est un stack overflow au fait ?)

  20. #16
    noisyboxes

    Re : utilisation de buffer sur PIC

    je ne comprends pas bien ce que tu veux dire.
    Quel ancien code de recptrame??
    j'appel cette fonction dans mon prog principal seulement quen RCIF est à 1:
    btfss PIR1,RCIF
    autrechose
    call receptrame
    call trait
    ...

    et l'erreur vient de la mise à 1 du bit OERR du registre RCSTA;

  21. #17
    umfred

    Re : utilisation de buffer sur PIC

    Je parlait du code de receptrame mis dans le post n°5 qui d'après son écriture devait s'exécuter 3 fois pour lire la trame complète (remise à 0 du pointeur du buffer quand on recevait 0x66, c-a-d ce qui était fait à findemess).

    Il faut donc que tu rajoute le test sur RCIF dans le code que je t'ai donné:
    Code:
    ...
    loop
    	movf bufptr,w ; charger le pointeur de destination
    	movwf FSR ; charger pointeur d'adresse
    loop01
    	btfss PIR1,RCIF ; attente de passage du bit RCIF à 1
    	goto loop01
    	movf RCREG,w ; charger l'octet recu
    	movwf INDF ; sauvegarde de l'octet reçu
    	incf bufptr,f ; incrémenter pointeur de caractères
    	movf FSR,w ; charger pointeur
    	decfsz cmptoct , f ; décrémenter compteur de boucles
    	goto loop ; pas dernier emplacement, suivant
    	return
    et dans ton code principal il faut, bien sûr, retirer le test sur RCIF.

Sur le même thème :

Discussions similaires

  1. erreur 0X00 programmation PIC plus questions sur les PIC
    Par ROTT dans le forum Électronique
    Réponses: 4
    Dernier message: 22/07/2007, 14h36
  2. Utilisation de l'USART d'un pic 16f876
    Par Titou54 dans le forum Électronique
    Réponses: 2
    Dernier message: 30/05/2007, 23h11
  3. buffer
    Par savoir? dans le forum Électronique
    Réponses: 2
    Dernier message: 04/02/2007, 11h28
  4. DD cb de mo de buffer
    Par sliebart dans le forum Matériel - Hardware
    Réponses: 4
    Dernier message: 23/04/2004, 14h28