/******************************************************** /* Génération de deux signaux pwm indépendants * /* avec les deux modules CCP1 et CCP2 * /* * /* Auteur : Arlotto Date : 08/01/03 * /* * /* CCP1 commande RC2 broche 17 du 877 * /* CCP2 commande RC1 borche 16 du 877 * /* Ce programme tourne sur la carte demo icd * /* donc avec un circuit RC de fréquence 3.5 seront * /* laissés à 00. PWMdt=(CCPR1L:00)*0.25µs (cf8.3.2) * /* PWMdt = CCPR1L * 4 * 0.25µs (décalage de 2) * /* donc CCPR1L=0 <-> 0% et CCPR1L>=99 <-> 100% * /* on fera de même avec le module CCP2 * /* attention a reprendre les calculs lorsque pre!=1 * /********************************************************/ #include void InitPwm(void); void SetDutyCycle(unsigned char ch,unsigned char DutyCycle); unsigned char GetDutyCycle(unsigned char ch); void main(void) { unsigned char r ; TRISB1 = 0 ; RB1 = 0 ; TRISD=0 ; RD3 = 1 ; InitPwm(); SetDutyCycle(0,50); SetDutyCycle(1,25); while(1) { if (RB0==0) { r = GetDutyCycle(0); if (r<100) { r=r+2; /* ! +1 peut conduire à aucune variation du fait */ /*de l'approximation entière dans GetDutyCycle() */ SetDutyCycle(0,r); } else { SetDutyCycle(0,0); } r = GetDutyCycle(1); if (r>=1) { r= r - 2 ; SetDutyCycle(1,r); } else { SetDutyCycle(1,100); } while(!RB0) ; } } } /**************************************************************** /* Fonction : InitPwm() * /* Cette fonction initialise les deux modules CCP1 et CCP2 en * /* mode pwm pour une fréquence de 10kHz avec un quartz de 4Mhz * /* les deux rapports cycliques sont mis à 0 * /****************************************************************/ void InitPwm(void) { PR2 = 99 ; CCPR1L = 0 ; CCP1CON = 0x0C ; /* PWM mode , bit 5 et 4 à 0 */ TRISC2 = 0 ; CCPR2L = 0 ; TRISC1 = 0 ; CCP2CON = 0x0C; T2CON = 0x04 ; /* TMR2ON prescaler = 1 */ } /**************************************************************** /* Fonction : SetDutyCycle() * /* Cette fonction programme le rapport cyclique DutyCycle sur * /* le canal ch (0 ou 1) * /* Le rapport est fourni sous la forme 0 100) { DutyCycle = 100 ; } DutyCycle = ( (unsigned int) PR2 * (unsigned int)DutyCycle )/100 ; if ( ch == 0 ) { CCPR1L = DutyCycle ; return ; } if ( ch == 1 ) { CCPR2L = DutyCycle ; return ; } CCPR1L = 0 ; CCPR2L = 0 ; return ; } /**************************************************************** /* Fonction : GetDutyCycle() * /* Cette fonction permet de relire le rapport cyclique * /* Pour l'avoir sous la forme 0<->100 * /* Attention du fait qu'on travaille avec des nombres entiers * /* on n'obtient qu'une valeur approchée (par défaut) dans le cas* /* où la division ne tombe pas juste * /****************************************************************/ unsigned char GetDutyCycle(unsigned char ch) { if ( ch == 0 ) { return ((unsigned int)CCPR1L * 100) / PR2; } if ( ch == 1 ) { return ((unsigned int) CCPR2L * 100) / PR2; } /*erreur */ return 255 ; }