mode capture ccp1
Répondre à la discussion
Affichage des résultats 1 à 11 sur 11

mode capture ccp1



  1. #1
    invitee8a0b493

    mode capture ccp1


    ------

    salut,
    je programme un pic 16F877, (je suis débutante)
    j'ai un capteur qui détécte les tours d'un moteur, à chaque fois le moteur fait un tour ce capteur passe de 0 à 12v.
    je veux lire les impulsions provenant du capteur et les compter (càd compter le nombre de tours de moteur).
    je sais que je dois utuliser le mode capture du module ccp, j'ai commencé avec ce code,
    svp aidez moi à le modifier pour répondre à mes besoins, et si avez d'autre idées, aidez moi please.

    Code:
    #include <16F877.h>
    #include <stdlib.h>
    #fuses HS,NOWDT,NOPROTECT,NOLVP
    #use delay(clock=20000000)
    #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
    
    INPUT(PIN_C_2);
    int nombre =0;
    int8  gc_capture_flag = FALSE;
    
    void main()
    {
     setup_ccp1(CCP_CAPTURE_RE);    // Configure CCP1 to capture rise
     setup_timer_1(T1_INTERNAL);    // Start timer 1
    while(1)
    {
    if(gc_capture_flag == TRUE)
    {
    nombre=nombre+1;
     gc_capture_flag = FALSE;
    }
    }
    printf("nombre=%d\n\r",nombre);
    delay_ms(5000);
    nombre=0;
    }

    -----
    Dernière modification par gienas ; 11/04/2012 à 14h22. Motif: Ajouté la balise code, obligatoire pour les programmes

  2. #2
    Laboum

    Re : mode capture ccp1

    Bonsoir nesrine22,
    Hélas je ne peux pas te répondre, (je ne travaille pas avec ce langage) as-tu consulté le datasheet?
    N'oublie pas d'utiliser la balise "code", ce sera plus agréable pour les futurs intervenants.
    Code:
    #include <16F877.h>
    #include <stdlib.h>
    #fuses HS,NOWDT,NOPROTECT,NOLVP
    #use delay(clock=20000000)
    #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
    
    INPUT(PIN_C_2);
    int nombre =0;
    int8 gc_capture_flag = FALSE;
    
    void main()
    {
    setup_ccp1(CCP_CAPTURE_RE); // Configure CCP1 to capture rise
    setup_timer_1(T1_INTERNAL); // Start timer 1
    while(1)
    {
    if(gc_capture_flag == TRUE)
    {
    nombre=nombre+1;
    gc_capture_flag = FALSE;
    }
    }
    printf("nombre=%d\n\r",nombre) ;
    delay_ms(5000);
    nombre=0;
    }
    Bon courage

  3. #3
    propic

    Re : mode capture ccp1

    slt

    tu peut aussi utilisé la pin RB0/INT en mode interruption, à chaque tour du moteur le capteur va donné une impulsion qui provoque l'interruption, et dans la routine d'interruption t incremente une variable.
    le contenue de la variable est le reflus de nbrs de tour.

    b8

  4. #4
    invitee8a0b493

    Re : mode capture ccp1

    merci beaucoup,
    peux tu me donner un exemple pour s'inspirer?

  5. A voir en vidéo sur Futura
  6. #5
    RISC

    Re : mode capture ccp1

    Salut,

    Je n'utilise pas non plus CCS.
    Si tu veux un exemple d'utilisation de l'unité CCP en mode Capture tu pourras en trouver je pense ici : http://www.microchip.com/codeexamples
    écrit en ANSI-C...

    Si tu cherches sur ce forum "capture" tu devrais trouver des dizaines de sujets...

    a+

  7. #6
    propic

    Re : mode capture ccp1

    Bonjour,

    vous avez aussi la méthode du timer0 en mode compteur,chaque impulsion reçue sur la pin RA4 va incrémenté le registre TMR0
    ou si vous voulez que chaque multiple de 2,4 ou 16 impulsions qui provoque l’incrémentation du REG TMR0.
    le contenue de TMR0 est le reflus de nbrs de tour.

    moi non plus, (je ne travaille pas avec ce langage).
    si vous voulez en assembleur.

  8. #7
    propic

    Re : mode capture ccp1

    si votre programme ne fait rien que cela, pourquoi ne v utilisé pas le 16f84.
    le 16f877 et plus grand pour cette application.

    slt

  9. #8
    invitee8a0b493

    Re : mode capture ccp1

    Merci pour vos réponses,
    j'ai besoin de 16F877, j'ai d'autre tâches à faire,
    je vous remerci, mais je doit utiliser le ccs.
    SVP, un petit programme avec ccs utilisant l'interruption.

  10. #9
    petardfrancois

    Re : mode capture ccp1

    Bonjour.

    J'ai réalisé sous Mikrobasic un code employant le mode capture pour mesurer une fréquence, période et rapport cyclique.


    Code :

    program ProjetD



    '***************************** ****************************** ********************
    'Pour microcontrolleur 18F4550, Osc 20Mhz
    'Demo mesure, fréquence, Rapport cyclique, periode.
    'Par Christophe Acquier.

    DIM
    LCD_RS as sbit at RB4_bit
    LCD_EN as sbit at RB5_bit
    LCD_D7 as sbit at RB3_bit
    LCD_D6 as sbit at RB2_bit
    LCD_D5 as sbit at RB1_bit
    LCD_D4 as sbit at RB0_bit

    DIM

    LCD_RS_Direction as sbit at TRISB4_bit
    LCD_EN_Direction as sbit at TRISB5_bit
    LCD_D7_Direction as sbit at TRISB3_bit
    LCD_D6_Direction as sbit at TRISB2_bit
    LCD_D5_Direction as sbit at TRISB1_bit
    LCD_D4_Direction as sbit at TRISB0_bit

    DIM CCP1L,CCP1H as BYTE 'Variable poids faible et fort pour CCPR1
    DIM Tstart,Tend,TdiffDOWN as INTEGER
    DIM Frequence as WORD 'Variable pour la conversion en fréquence
    DIM periode,Rapport,Ttotal,TdiffUP as FLOAT 'Variable pour la periode et du Rapport cyclique


    DIM Txt as CHAR[20] ' Variable d'affichage des valeurs.
    DIM Txt1 as CHAR[20] '
    DIM Txt2 as CHAR[20]
    DIM Txt3 as CHAR[20]
    DIM Txt4 as CHAR[20]

    '------------------------------------- Procédure d'interruption globale------------------------------------------------------
    '----------------Attention !! la détection et l'anticipation du débordement du timer (TRM1) n'est pas incluse Attention !!--------------------
    Sub procedure interrupt()
    '-------------------------------- Procédure d'interruption dés qu'un front montant/descendant détecté sur (RC.2)CCP1 provenant d'un signal carré------
    '-------------------------Prise de mesure de la durée de l'état Haut du signal et de l'état Bas pour le calcul du rapport cyclique---------
    CCP1L = CCPR1L 'Transfert des 8 bit de poids faible de CCPR1 vers CCP1L.
    CCP1H = CCPR1H 'Transfert des 8 bit de poids fort de CCPR1 vers CCP1H.
    Tend = CCP1L + word(CCP1H<<8) 'Décalage de 8 position vers la gauche de CCP1H vers Tend afin de pouvoir lire les 16 bit de CCP1.

    IF CCP1CON.CCP1M0 = 0 THEN 'SI front descendant détecté ALORS :
    TdiffUP = Tend - Tstart 'Calcul du temps écoulé entre 2 interruptions correspond au nombre d'impulsion du timer 1 durant cette pèriode
    'pour le niveau haut du signal dans TdiffUP
    ELSE 'SINON
    TdiffDown = Tend - Tstart 'Calcul du temps écoulé entre 2 interruptions correspond au nombre d'impulsion du timer 1 durant cette pèriode
    'pour le niveau bas du signal dans TdiffDown
    END IF
    Ttotal = TdiffUP + TdiffDOWN 'Addition du temps au niveau haut et bas pour obtenir la periode du signal
    Tstart = Tend 'le temps écoulé d'arrivé devient le temps de départ pour effectuer la prochaine mesure...(de suite,ainsi de suite)
    CCP1CON.CCP1M0 = not CCP1CON.CCP1M0 'INVERSEMENT DU FRONT DE DETECTION DU SIGNAL.
    PIR1.CCP1IF = 0 'Remise à zéro du flag de CCP1 pour relancer la prochaine interruption.

    end sub

    Sub procedure LCDOUT() 'Procédure d'affichage

    Txt [7] = 0
    Txt1[5] = 0
    Txt2[5] = 0
    Txt3[7] = 0
    Delay_ms (1000)
    Lcd_Cmd(_LCD_CLEAR) '
    Lcd_Out (1,1,Txt) 'Affichage de TdiffUP (optionnel)
    Lcd_out (1,8,Txt4)
    Lcd_Out (2,7,Txt1) 'Affichage de TdiffDOWN (optionnel)
    Lcd_Out (2,1,"Rt:") 'Affichage du Rapport cyclique
    Lcd_out (2,15,"%")
    Delay_ms (1000)
    Lcd_Cmd(_LCD_CLEAR)
    Lcd_Out (1,5,Txt2) 'Affichage de la fréquence
    Lcd_Out (1,1,"FQ:")
    Lcd_out (1,14,"HZ")
    Lcd_Out (2,5,Txt3) 'Affichage de la periode
    Lcd_Out (2,1,"T:")
    Lcd_out (2,14,"Sec")
    end sub



    Main:
    CMCON = 7 '
    T1CON = 1 'Activation du timer 1 sans prédiviseur (20ns à 20 MHZ).
    CCP1CON = %00000100 'les interruptions commenceront sur un front montant du signal sur CCP1.
    PIE1 = %00000100 'Autorisation des interruptions sur le module de capture sur CCP1.
    INTCON = %11000000 'Autorisation des interruptions émanant d'autres modules.
    TRISB = 0
    LCD_INIT() 'Initialisation de l'afficheur LCD.
    Lcd_Cmd(_LCD_CLEAR) 'Effacement de l'afficheur LCD.
    Lcd_Cmd(_LCD_CURSOR_OFF) 'Pas de curseur.

    WHILE TRUE

    RAPPORT = (TdiffUP/Ttotal)*100.
    PERIODE = (Ttotal*2./10000000.) 'Calcul de la periode : T = Ttotal x 20 ns
    FREQUENCE = (1./PERIODE) 'Calcul de la fréquence : FQ = 1/PERIODE
    FloatToStr(RAPPORT,Txt1) 'Conversion de la variable RAPPORT vers Txt1 pour l'afficheur
    FloatToStr(FREQUENCE,Txt2) 'Conversion de la variable FREQUENCE vers Txt2 pour l'afficheur
    FloatToStr(PERIODE,Txt3) 'Conversion de la variable PERIODE vers Txt1 pour l'afficheur
    WordToStr(TdiffUP,txt) ' aide visuel (optionnel)
    WordToStr(TdiffDOWN,txt4) ' aide visuel (optionnel)
    LCDOUT()

    WEND
    end.

  11. #10
    petardfrancois

    Re : mode capture ccp1

    Erf ! Pas très lisible

    Je vous envois simplement la procédure d'interruption sans les commentaires.

    CCP1H, CCP1L as BYTE
    Ndiff, Nstart, Nend as INTEGER


    Sub procedure interrupt()

    IF PIR1.CCP1IF = 1 THEN
    CCP1L = CCPR1L
    CCP1H = CCPR1H
    Nend = CCP1L + word(CCP1H<<8)
    Ndiff = Nend - Nstart
    Nstart = Nend
    PIR1.CCP1IF = 0
    END IF
    end sub

  12. #11
    petardfrancois

    Re : mode capture ccp1

    Bon dernier post avant de me faire épingler pour flood

    Pour résumer le principe d'utilisation du module CCP1 en mode capture, c'est que celui-ci, associé au timer 1 (qu'il faut lancer tout de même) génère à la fois une capture de l'état du timer 1 et une interruption.
    Il suffit donc de récupérer l'état de la capture grâce à CCPR1L et CCPR1H (attention on le lis sur 16bit) en la retranscrivant dans la variable (Nend = CCP1L + word(CCP1H<<8)) qui correspond à par exemple dans votre cas à une fin de tour de votre moteur, ensuite pour préparer la prochaine mesure, ce que vous avez "capturez" à la fin de rotation devient le départ de la prochaine rotation (Nstart = Nend) et enfin il vous reste plus que de faire la différence entre les deux (Ndiff = Nend - Nstart) pour connaitre le nombre "d'impulsion" du timer 1 et bien sur de remettre le flag à zéro (PIR1.CCP1IF = 0 ) pour réinitialiser la prochaine interruption provoqué par la capture.
    Vous n'avez pas besoin dans l'interruption de mettre sous condition (IF PIR1.CCP1...) c'est seulement utile pour le différencier des autres flag..
    Pour calculer le temps : T = 1/(osc/4) x "contenu de CCP1"

    Bon voilà, j'espère avoir été utile dans la compréhension de ce module.

Discussions similaires

  1. Mode capture PIC
    Par invitead364e96 dans le forum Électronique
    Réponses: 18
    Dernier message: 20/11/2013, 23h33
  2. interruption basse priorité pour le module CCP1 capture
    Par invited08e1382 dans le forum Électronique
    Réponses: 3
    Dernier message: 19/05/2011, 12h17
  3. mode capture CCPx
    Par invite69641788 dans le forum Électronique
    Réponses: 2
    Dernier message: 20/05/2010, 22h31
  4. Conflit CCP1 & CCP2 en mode Compare
    Par invite5637435c dans le forum Électronique
    Réponses: 3
    Dernier message: 03/12/2006, 22h55
  5. mode capture du PIC16F627 ?
    Par invite164b8116 dans le forum Électronique
    Réponses: 3
    Dernier message: 03/10/2006, 18h39
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...