Bienvenue aux nouveaux arrivants sur FantasPic !
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
Modérateur : Jérémy
Regler le timer d'une PWM
Bonjour,
voici un code pour PIC16F628, à l'époque écrit avec HitechC.
Il gère 3 PWM avec 2 BP pour un PIC ne possédant qu'un PWM
Et le fichier header ecl_pwm.h
voici un code pour PIC16F628, à l'époque écrit avec HitechC.
Il gère 3 PWM avec 2 BP pour un PIC ne possédant qu'un PWM
Code : Tout sélectionner
/*===============================================================================
Composant : PIC16F628A
Essais PWM.
Auteur: HULK28
===============================================================================*/
#include <pic.h>
#include "ecl_pwm.h" // Définitions spécifiques
/*================================================================================
|Historique | Date | Modification
---------------------------------------------------------------------------------
| V1.0 | 12/07/2006 | - Date de création
| V1.1 | 29/07/2006 | - correction
---------------------------------------------------------------------------------
Fichier c : ecl_pwm.c
Fichier définition : ecl_pwm.h
Fichier définition PIC : pic.h -> pic16f6x.h
Fichier Hex : ecl_pwm.hex
==================================================================================
PRÉSENTATION DU PROGRAMME
Ce programme tourne sur un PIC16F628.
Les entrées / Sorties sont définies comme suit :
* Sorties : - Sortie PWM (0-255) S1 ---> RA6
- Sortie PWM (0-255) S2 ---> RA7
- Sortie PWM (0-255) S3 ---> RB3
* Entrées : - Bouton poussoir UP ---> RB6
- Bouton poussoir DOWN ---> RB7
* Entrée ANA : aucune
* E/S :
=====================================================================================
Tous les "timing" sont basés sur un résonateur de fréquence 4 Mhz.
Le temps de cycle par instruction est de 1 µs.
Toutes les données utilisées sont exprimées en décimal, sauf celles
spécifiées.
================================================================================*/
//***************************************************************
ushort Compteur62us ;
uchar Flag62us ;
ushort ValeurPwmS1 ;
ushort ValeurPwmS2 ;
ushort ValeurPwmS3 ;
uchar Valeur3Pas ;
uchar CompteurPression ;
uchar CombinaisonBPs ;
//***************************************************************
void init_pic(void);
void interrupt traite_int(void);
void clock_pic(void);
void DelayMs(uchar cpt) ;
void init_var(void) ;
void init_pwm(void) ;
void stop_pwm(void) ;
void setDC_pwm(ushort dc) ;
uchar TestBPs(void) ;
void GestionBPs(void) ;
//***************************************************************
/****************************************************************
Temporisation en millisecondes
****************************************************************/
void DelayMs(uchar cpt)
{
ushort t ;
while (cpt != 0)
{
CLRWDT() ;
-- cpt ;
t = 112 ;
while (t !=0) -- t ;
}
}
/****************************************************************
Traitement des interruptions
****************************************************************/
void interrupt traite_int(void)
{
if(TMR1IF)
{
TMR1IF = 0 ;
Flag62us = 1 ;
TMR1H = 0xFF ;
TMR1L = 0xC1 ; // 0xFFFF - 0xFFC1 = 62 => 62 x 1 µs = 62 µs
}
}
/****************************************************************
Initialisation du PIC
****************************************************************/
void init_pic(void)
{
// Configuration du module CCP
CCP1CON = 0x00 ; // module CCP1 désactivé
// Configuration du port B
RBPU = 0 ; // active pull up
RBIE = 0 ;
// Configuration des I/O
PwmS1 = 0 ; // à l'init. S1 = 0
PwmS2 = 0 ; // à l'init. S2 = 0
PwmS3 = 0 ; // à l'init. S3 = 0
TRISA = ConfigIOPortA ;
TRISB = ConfigIOPortB ;
// Timer 0 (8 bits) est utilisé pour le wachtdog à 2,3 s.
T0CS = 0 ; // Clock interne
PSA = 1 ; // timer0 = Wachtdog
PS2 = 1 ; // \
PS1 = 1 ; // => 111 + WDT => 18 ms x 128 = 2,304 s
PS0 = 1 ; // /
// Timer 1 (16 bits) est utilisé pour l'horloge: base de 62 µs. Quartz 4 Mhz => 1 instruction = 1 µs
T1CON = 0x00 ; // Prédivision de l'horloge par 1
TMR1H = 0xFF ;
TMR1L = 0xC1 ; // 0xFFFF - 0xFFC1 = 62 => 62 x 1 µs = 62 µs
TMR1ON = 1 ; // On lance le timer 1
TMR1IE = 1 ; // On autorise les interruptions du timer 1
// Autorisation des interruptions
PEIE = 1 ; // Autorisation des IT peripherique
GIE = 1 ; // Autorisation général des IT
}
/****************************************************************
Initialisation des variables globales
****************************************************************/
void init_var(void)
{
Flag62us = 0 ;
Compteur62us = 0 ; // Raz compteur clock
ValeurPwmS1 = 0 ;
ValeurPwmS2 = 0 ;
ValeurPwmS3 = 0 ;
Valeur3Pas = 0 ;
}
/****************************************************************
Initialisation du périphérique PWM
****************************************************************/
void init_pwm(void)
{
CCP1CON = 0x00 ; // module off
TMR2 = 0 ; // raz timer2 value
PR2 = 0x7C ; // PR2 = 124 --> f = 500 Hz
CCPR1L = 0 ; // Duty cycle = 0 à l'init
TRISB3 = 0 ; // RB3 = output
T2CKPS1 = 1 ; // Prescaler = 1:16
T2CKPS0 = 1 ;
CCP1CON = 0x0C ; // Mode PWM 10 bits + init two LSBs of PWM duty cycle at 0
TMR2ON = 1 ; // Timer2 ON
}
/****************************************************************
Arrête le périphérique PWM
****************************************************************/
void stop_PWM(void)
{
RB3 = 0 ;
TMR2ON = 0 ;
CCP1CON = 0x00 ;
}
/****************************************************************
Charge le rapport cyclique PWM [0-1023] -> [0-100%]
****************************************************************/
void setDC_PWM(ushort dc)
{
CCP1CON = CCP1CON & 0b11001111 ; // clear CCP1CON<5:4>
CCP1CON = CCP1CON | ((dc << 4) & 0b00110000) ; // set the two LSBs duty cycle
CCPR1L = dc >> 2 ; // set the eight MSBs duty cycle
}
/****************************************************************
Gestion horloge du PIC
****************************************************************/
void clock_pic(void)
{
Flag62us = 0 ;
// ValeurPwmSx [0-256]
// Compteur62us [0-256]
if (ValeurPwmS1 == 0) PwmS1 = 0 ;
else
{
if (Compteur62us == 0) PwmS1 = 1 ;
else if (Compteur62us == ValeurPwmS1) PwmS1 = 0 ;
}
if (ValeurPwmS2 == 0) PwmS2 = 0 ;
else
{
if (Compteur62us == 0) PwmS2 = 1 ;
else if (Compteur62us == ValeurPwmS2) PwmS2 = 0 ;
}
Compteur62us = Compteur62us + 8 ;
if (Compteur62us == 256) Compteur62us = 0 ; // période = 2 ms
}
/****************************************************************
Test périodiquement l'action sur les boutons poussoirs
****************************************************************/
uchar TestBPs(void)
{
CompteurPression = 0 ;
CombinaisonBPs = AUCUNE ;
while (!BoutonUp)
{
DelayMs(10) ;
++CompteurPression ;
if (!BoutonDown)
CombinaisonBPs = UP_ET_DOWN ;
else
CombinaisonBPs = UP ;
if (CompteurPression > 200) break ; // expiration
}
while (!BoutonDown)
{
DelayMs(10) ;
++CompteurPression ;
if (!BoutonUp)
CombinaisonBPs = UP_ET_DOWN ;
else
CombinaisonBPs = DOWN ;
if (CompteurPression > 200) break ; // expiration
}
return(CombinaisonBPs) ;
}
/****************************************************************
Gestion des boutons poussoirs
****************************************************************/
void GestionBPs(void)
{
switch (CombinaisonBPs)
{
case UP :
if (CompteurPression > 1)
{
if (ValeurPwmS1 < 248) ValeurPwmS1 = ValeurPwmS1 + 8 ;
if (ValeurPwmS2 < 248) ValeurPwmS2 = ValeurPwmS2 + 8 ;
if (ValeurPwmS3 < 248) ValeurPwmS3 = ValeurPwmS3 + 8 ;
}
else
{
if (ValeurPwmS1 < 224) ValeurPwmS1 = ValeurPwmS1 + 32 ;
if (ValeurPwmS1 < 224) ValeurPwmS2 = ValeurPwmS2 + 32 ;
if (ValeurPwmS1 < 224) ValeurPwmS3 = ValeurPwmS3 + 32 ;
}
break ;
case DOWN :
if (CompteurPression > 1)
{
if (ValeurPwmS1 > 7) ValeurPwmS1 = ValeurPwmS1 - 8 ;
if (ValeurPwmS2 > 7) ValeurPwmS2 = ValeurPwmS2 - 8 ;
if (ValeurPwmS3 > 7) ValeurPwmS3 = ValeurPwmS3 - 8 ;
}
else
{
if (ValeurPwmS1 > 31) ValeurPwmS1 = ValeurPwmS1 - 32 ;
if (ValeurPwmS1 > 31) ValeurPwmS2 = ValeurPwmS2 - 32 ;
if (ValeurPwmS1 > 31) ValeurPwmS3 = ValeurPwmS3 - 32 ;
}
break ;
case UP_ET_DOWN :
if (CompteurPression > 1)
{
switch (Valeur3Pas)
{
case 0 :
Valeur3Pas = 50 ; // 50%
ValeurPwmS1 = 128 ;
ValeurPwmS2 = 128 ;
ValeurPwmS3 = 128 ;
break ;
case 50 :
Valeur3Pas = 100 ; // 100%
ValeurPwmS1 = 256 ;
ValeurPwmS2 = 256 ;
ValeurPwmS3 = 256 ;
break ;
case 100 :
Valeur3Pas = 0 ; // 0%
ValeurPwmS1 = 0 ;
ValeurPwmS2 = 0 ;
ValeurPwmS3 = 0 ;
break ;
}
}
break ;
}
// S1 est mis à jour par ValeurPwmS1 --> Timer1
// S2 est mis à jour par ValeurPwmS2 --> Timer1
// S3 est mis à jour par ValeurPwmS3 --> PWM
setDC_PWM((ValeurPwmS3 * 4)-1) ; // on se ramène à l'échelle [0-1023]
while (TestBPs() != AUCUNE) // on attend le relâchement du bouton.
CLRWDT() ;
Compteur62us = 0 ;
}
/****************************************************************
Programme principale
****************************************************************/
main()
{
CLRWDT() ;
// init registres
init_pic();
// init variables globales
init_var() ;
// init PWM hard
init_pwm() ;
//setDC_PWM(128) ;
while(1)
{
// raffraichi le watchdog
CLRWDT() ;
// gestion 62 µs
if (Flag62us)
clock_pic();
// gestion des boutons poussoirs
if (TestBPs() != AUCUNE)
GestionBPs() ;
}
}
Et le fichier header ecl_pwm.h
Code : Tout sélectionner
// Définitions spécifiques
/********************************************************************
* Librairie de définitions Centrale tableau *
* Ecrit en C pour être compilé avec HI-TECH, testé avec MPLAB *
*********************************************************************
*********************************************************************
* Fichier : ecl_pwm.h HULK28 *
* Date: 16/09/2006 *
* Version: 1.00 *
*********************************************************************
* Fonctions: *
* *
*********************************************************************
* Revision History: *
* V1.00 - Version beta *
********************************************************************/
/*====================================================================
-----= Predefined instructions =-----
====================================================================*/
// Predefined instructions
#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit))
#define NOP() asm(" nop")
#define FALSE 0
#define TRUE !FALSE
#define BYTE unsigned char /* sizeof(BYTE) must == 1 */
#define uchar unsigned char
#define ushort unsigned short
#define ulong unsigned long
// Descriptions des différentes entrées et sorties
static bit PwmS1 @ PORTBIT(PORTA, 6) ; // sortie S1 PWM
static bit PwmS2 @ PORTBIT(PORTA, 7) ; // sortie S2 PWM
static bit PwmS3 @ PORTBIT(PORTB, 3) ; // sortie S3 PWM
static bit BoutonUp @ PORTBIT(PORTB, 6) ; // entrée poussoir UP
static bit BoutonDown @ PORTBIT(PORTB, 7) ; // entrée poussoir DOWN
// Définition des différentes constantes spécifiques à la centrale
// Remarque: 1 = entrée, 0 = sortie
#define ConfigIOPortA 0x3F // RA6 et RA7 = output--> PWM, le reste en input
#define ConfigIOPortB 0xFF // port B en input
#define AUCUNE 0x00 // none
#define UP 0x01 // +
#define DOWN 0x02 // -
#define UP_ET_DOWN 0x03 // + AND -
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 55 invités