Principe de fonctionnement
Dans ce petit projet je vais vous expliquez comment générer un signal sinusoïdal, sinus cardinal, signal triangulaire, carre et aléatoire à base du PIC16F877. J’ai utilisé un convertisseur numérique analogique DAC de 8 bits à base du réseau R/2R, amplificateur à gain variable et un filtre basse bas pour lisser le signal et restitué la bande de base.
Ce mini-projet permet de générer 5 signaux analogiques et un signal TOR avec une fréquence fixe (vous pouvez modifier la fréquence en agissant sur les paramètres du TimerO).
- Signal sinusoïdal (SIN)
- Signal sinus cardinal (sin(x)/x) (SINC)
- Signal triangulaire symétrique (double rompes) (TRIANG1)
- Signal triangulaire simple rampe (TRIANG2)
- Signal carré (SQRT)
- Signal de bruit aléatoire (RAND)
Les boutons poussoirs STOP et START sert à lancer les signaux, chaque foie que vous voulez modifier la forme d’onde, vous appuyer d’abord sur STOP puis vous sélectionnez votre signal 🙂 ensuite START.
Résaau R/2R – Convertisseur Numérique Analogique 8 bits (DAC)
La tension de sortie correspond à chaque bit (D0-D7) (VCC=5V) :
Ce qui constitue un système binaire pondéré à base 2, chaque bit valant 2 puissances n. Le théorème de superposition indique que nous pouvons obtenir toutes les tensions comprises entre 0V et VCC par pas de VCC/256.
Ce réseau constitué de 2 sortes de résistances seulement constitue donc un convertisseur Numérique/Analogique (DAC) dont les éléments ne requièrent pas une très grande précision. (Contrairement à des réseaux par additions de courants dont certaines résistances ont une valeur 128 fois plus élevée que d’autres).
Amplificateur de tension et filtre lisseur de tension
La bande passante & le gain du filtre en fonction des potentiomètres RV1 & RV2
Résultats des simulations pour les signaux : Signal sinusoïdal et triangulaires :
Code MikroC
#define Sin_Val 16
#define Pas_Sin 1 // Prescaller 1/16
// Les vecteurs de 16 valeurs des signaux
unsigned char SineWave[Sin_Val] = {128, 179 , 222 , 249, 254, 238, 202, 154 , 101 , 53 , 17 , 1 , 6, 33,76, 127};
unsigned char SinCWave[Sin_Val] = {38, 68, 73, 35, 0, 38, 152, 255, 255, 152 ,38 ,0,35, 73,68,38};
unsigned char TrigWave1[Sin_Val] = {5 , 36, 73, 109, 146, 182, 219, 255, 255 , 219, 182, 146, 109, 73, 36, 0};
unsigned char TrigWave2[Sin_Val] ={0 , 17 , 34, 51, 68, 85, 102, 119, 136, 153, 170 , 187, 204, 221, 238, 255};
unsigned char SqrtWare[Sin_Val] ={0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255};
unsigned char Wave[Sin_Val]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned short int count = 0;
unsigned short int CountFreq=0, ValTimer0=255; // La prochaine version intègre l'option de varier la fréquence
unsigned char DataPortB=0;
unsigned char i=0;
// Fonction pour stopper le Timer0 (Stop)
void Timer_Disable(void)
{
INTCON.GIE = 0;
INTCON.PEIE = 0;
INTCON = 0;
INTCON.TMR0IE = 0;
INTCON.TMR0IF = 0;
PORTC=0;
}
// Fonction pour lancer le signal (Start)
void Timer_Enable(void)
{
INTCON.GIE = 1;
INTCON.PEIE = 1;
INTCON.TMR0IE = 1;
INTCON.TMR0IF = 1;
}
// Routine d'interruption (Timer0 ou PORTB)
void interrupt()
{
if(INTCON.INTF==1)
{
INTCON.INTF=0;
Timer_Disable();
}
if (INTCON.TMR0IF ==1)
{
INTCON.TMR0IE=0;
INTCON.TMR0IF = 0;
PORTC=Wave[count];
count+=Pas_Sin;
count = count % Sin_Val;
INTCON.TMR0IE = 1;
TMR0 = ValTimer0;
}
}
void main()
{
TRISC = 0x00; // PORTC en sortie
PORTC = 0x00; // Initialisation du portc à 0
TRISB = 0xFF; // bits 0-6 en entrés , le bit7 en sortie
PORTB.F7=0;
// Configuration du TIMER0 pour une fréquence de 2MHZ max (8MHz Fosc)
OPTION_REG.T0CS = 0; // bit 5 Source d'horloge (0 interne)
OPTION_REG.T0SE = 0; // bit 4 Type de front 0 our front montenat
OPTION_REG.PSA = 0; // bit 3 Activer le prediviseur
OPTION_REG.PS2 = 0; // bits 2-0 PS2:PS0: (0 à 255) pré-diviseur
OPTION_REG.PS1 = 0;
OPTION_REG.PS0 = 0;
TMR0 = 0; // Initialisation du TIMER0 à 0 (fréquence max)
// Interrupt Registers
INTCON.RBIE=1;
INTCON.TMR0IE = 1;
INTCON.GIE = 1;
INTCON.INTE=1;
OPTION_REG.INTEDG=1;
INTCON.TMR0IF = 0;
INTCON.RBIF=0;
while(1)
{
DataPortB = PORTB;
switch(DataPortB)
{
// Start
case 0x02 :
Timer_Enable();
break;
// Signal Sine
case 0x04 :
for(i=0;i<Sin_Val; i++) Wave[i] = SineWave[i];
Timer_Enable();
break;
// Signal Sinus cardinal (sin(x)/x)
case 0x08 :
for(i=0;i<Sin_Val; i++) Wave[i] = SinCWave[i];
Timer_Enable();
break;
// Signal triangulaire symétrique
case 0x10 :
for(i=0;i<Sin_Val; i++) Wave[i] = TrigWave1[i];
Timer_Enable();
break;
// Signal triangulaire non smétrique
case 0x20 :
for(i=0;i<Sin_Val; i++) Wave[i] = TrigWave2[i];
Timer_Enable();
break;
// Signal carré
case 0x40 :
for(i=0;i<Sin_Val; i++) Wave[i] = SqrtWare[i];
Timer_Enable();
break;
// Signal aléatoire
case 0x80 :
for(i=0;i<Sin_Val; i++) Wave[i] = floor(255.0*(double)rand()/32767.0);
Timer_Enable();
break;
}
}
}
Télécharger gratuitement le fichier du projet générateur des signaux à base du PIC16877 à fréquence fixe & DAC 8 bits R/2R :
- Codes MikroC du projet générateur des signaux à base du PIC16F877
- Montage ISIS du projet générateur des signaux à base du PIC16F877
Une réponse sur « Projet électronique : Générateur des signaux à base du PIC16877 à fréquence fixe & DAC 8 bits R/2R »
[…] Un Projet : Générateur des signaux à base du PIC16877 à fréquence fixe & DAC 8 bits R/2R tr…. […]