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 ---
Forum général sur le langage C !

Modérateur : Jérémy

Generateur DTMF 18F27K42
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#21 Message par satinas » dim. 20 nov. 2022 20:28

Bonsoir,
Une explication sur ce problème d'amplitude du signal PWM ?
Pourquoi le fait d'avoir une consigne sur 10 bits au lieu de 8 bits est gênante. Si les données sont sur 8 bits, il suffit de les multiplier par 4 pour utiliser toute la plage PWM, non ?
Je viens de faire un essai PWM avec CCP1, à FOSC=64MHz, Fpwm=62500Hz, le duty cycle va de 32ns à 16us, par pas de 16ns.
Merci :)

Code : Tout sélectionner

  T2CLK     = 0x01;              // timer2, clock FOSC/4
//T2CON     = 0x00;              // timer2, off, prescaler 1, postscaler 1
  T2PR      = 255;               // timer2, step 62,5ns, overflow 16us
  CCP1CON   = 0x8c;              // ccp1, on, mode pwm right aligned
  CCPR1     = 500;               // ccp1, duty cycle
//CCPTMRS0  = 0x55;              // ccp1, pwm on Timer2
  RB1PPS    = 0x09;              // pps ccp1_out -> B1
  TRISB1    = 0;                 // B1 ouput
  T2ON      = 1 ;                // timer2 on

Generateur DTMF 18F27K42
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#22 Message par paulfjujo » dim. 20 nov. 2022 21:13

bonsoir Satinas,


Oui, c'est bien ce que j'ai fait ... multiplié par 4 !
( ne plus diviser par 2 et en plus , multiplier par 2)
=> pwm valeur maxi=400

Generateur_DTMF_18F27K42_PWM5_XC8_2022-1120.zip


mais sous mikroC , je divise par 2 !
( je suis betement l'algo de roman balck!)
uniquement .. valeur maxi=100 !
moyenne des 2 amplitudes des 2 sinus
et mon amplitude analogique apres filtrage est OK


j'ai verifier le comportement du PWM5 associé à Timer2 62500Hz sortie RC4
dans le detail avec analyser logique ..
il se comporte tout à fait correctement .. avec une consigne 10 bits .. 0 à 1023

demain je vais faire le test comparatif avec MikroC ..CCP1 et Timer2 ..
cadré à droite , .... la commande Mikro C etant PWM1_Set_Duty(pwm);
..resultat équivalent à un PWM 8 bits !!

:!!: si on a CCPR1H et CCPR1L .. on devrait gerer CCP1 uttilisé en PWM , en 10 bits !
si j'envoie 100 en 10 bits ,le duty maxi serait < 10%
ce n'est pas le cas !

nota : j'ai bien essayé les combinaisons avec FMT=0 ou FMT=1 !

mikroC gere differement CCP1 PWM et les PWM 5,6,7,8

Attendons mes tests avec analyser coté MikroC pour verifier ...
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

Generateur DTMF 18F27K42
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#23 Message par satinas » lun. 21 nov. 2022 06:52

Bonjour à tous,

Si la fonction MikroC PWM_Set_Duty() marche bien avec 8 bits, c'est qu'elle multiplie par 4 avant de renseigner PWM5DC. Seulement si PR est à 255. Elle fait une règle de trois pour adapter le rapport cyclique selon la valeur de PR, en passant pas une multiplication 16 bits. Le but est de décrire toute la plage PWM du pic en entrant une valeur de 0 à 255.
Si on fait PWM_Set_Duty(130) elle fait le calcul suivant : dc = (130*4*(PR+1))/256 simplifié en (130*(PR+1))/64
Avec un PR de 255 : (130*256)/64 -> 520
Avec un PR de 100 : (130*101)/64 -> 205

Je vais regarder l'algo Roman Black. Au niveau rapidité, voilà ta fonction LoadDutyValue(pwm_1) en alignement gauche.

Code : Tout sélectionner

413: void PWM5_LoadDutyValue(uint16_t dutyValue)

11FD4  C02C     MOVFF __pcstackCOMRAMh, src
11FD6  F02E     NOP
11FD8  C02D     MOVFF 0x2D, 0x2F
11FDA  F02F     NOP
11FDC  90D8     BCF 0xFD8, 0, ACCESS
11FDE  322F     RRCF 0x2F, F, ACCESS
11FE0  322E     RRCF src, F, ACCESS
11FE2  90D8     BCF 0xFD8, 0, ACCESS
11FE4  322F     RRCF 0x2F, F, ACCESS
11FE6  322E     RRCF src, F, ACCESS
11FE8  502E     MOVF src, W, ACCESS
11FEA  6E6D     MOVWF 0xF6D, ACCESS
414:            {
415:                // Writing to 8 MSBs of PWM duty cycle in PWMDCH register
416:                PWM5DCH = (dutyValue & 0x03FC)>>2;
417:               
418:                // Writing to 2 LSBs of PWM duty cycle in PWMDCL register
419:                PWM5DCL = (dutyValue & 0x0003)<<6;
11FEC  C02C     MOVFF __pcstackCOMRAMh, src
11FEE  F02E     NOP
11FF0  0E03     MOVLW 0x3
11FF2  162E     ANDWF src, F, ACCESS
11FF4  0E06     MOVLW 0x6
11FF6  6E2F     MOVWF 0x2F, ACCESS
11FF8  90D8     BCF 0xFD8, 0, ACCESS
11FFA  362E     RLCF src, F, ACCESS
11FFC  2E2F     DECFSZ 0x2F, F, ACCESS
11FFE  EFFC     GOTO 0x11FF8
12000  F08F     NOP
12002  502E     MOVF src, W, ACCESS
12004  6E6C     MOVWF 0xF6C, ACCESS
420:            }
12006  0012     RETURN 0
421: 

En alignement droite, PWM5DC = pwm_1; devrait suffire. Problème, il le transforme en nop :)
Cela prend bien 4 cycles car pwm_1 et PWM5DC sont en mémoire access, alors où sont les instructions ?
Pourtant le programme marche :)

Code : Tout sélectionner

507:                 PWM5DC = pwm_1;
1025E  F2F7     NOP
10260  FF6C     NOP
10264  F2FB     NOP
10266  FF6D     NOP

Generateur DTMF 18F27K42
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#24 Message par paulfjujo » lun. 21 nov. 2022 10:37

bonjour satinas,


merçi d'avoir décortiqué la fonction mikroc

mais dans mon cas ,(MikroC) c'est CCP1 qui est utilisé comme PWM générateur et non PWM5
donc usage aussi de CCP1RL et CCPR1H, au détail pres de la possibité d'utiliser le cadrage à gauche ou droite suivant l'etat du bit FMT 'CCP1CON)
qui est d'ailleur la principale difference avec PWM5 (sans ce bit FMT)
ou on retrouve aussi les 2 registres PWM5 DCH et DCL , MAIS sans choix du cadrage à gauche ou droite

doc mikroc
void PWMx_Set_Duty(unsigned short duty_ratio);
Sets PWM duty ratio. Parameter duty takes values from 0 to 255, where 0 is 0%, 127 is 50%, and 255 is 100% duty ratio.
Other specific values for duty ratio can be calculated as (Percent*255)/100


test mikroC avec SQA analyser :

et PWM1_Set_Duty(pwm1);
on couvre bien 0 à100% avec pwm1= 0 à 255
on est bien sur PWM1 ( donc sur un CCP1 utilisé en PWM)
j'ai verifié que :
CCP1EN_bit=1; active la sortie PWM1
CCP1EN_bit=0; inhibe la sortie PWM1

code du test

Code : Tout sélectionner


    CCP1EN_bit
=1; // enable/active PWM output
    T2CON.T2ON=1;
   do
   
{
    CPrint(" Test CCP1 en mode PWM associé à TMR2, pwm 16 à 240 \r\n");
    for (pwm1=16;pwm1<240;pwm1=pwm1+16)
    {
     ByteToStr(pwm1,CRam1);
     CPrint(" pwm1 = ");
     Print(CRam1);CRLF1();
     SQA=1;
     PWM1_Set_Duty(pwm1);
     SQA=0;
     Delay_ms(1);
    }
    CPrint(" saisir Q pour quitter le test\r\n");
     Raz_Buffer1();
     Delay_ms(2000);
     if (*(Buffer1)=='0')
     {
         CPrint(" Disable CCP1 \r\n");
         CCP1EN_bit=0;
      }
       if (*(Buffer1)=='1')
     {
         CPrint(" Enable CCP1 \r\n");
         CCP1EN_bit=1;
      }
   }
   while(*(Buffer1)!='Q');
   CPrint(" ..fin de test\r\n");
   CRLF1(); 


RA3 trigger pour SQA
RC4 sortie PWM1

terminal YAT
Test CCP1 en mode PWM associé à TMR2, pwm 16 à 224
pwm1 = 16
pwm1 = 32
pwm1 = 48
pwm1 = 64
pwm1 = 80
pwm1 = 96
pwm1 = 112
pwm1 = 128
pwm1 = 144
pwm1 = 160
pwm1 = 176
pwm1 = 192
pwm1 = 208
pwm1 = 224
saisir Q pour quitter le test
0
Disable CCP1
Test CCP1 en mode PWM associé à TMR2, pwm 16 à 240
pwm1 = 16 <-- PAS de sortie signal
pwm1 = 32
pwm1 = 48
pwm1 = 64
pwm1 = 80
pwm1 = 96
pwm1 = 112
pwm1 = 128
pwm1 = 144
pwm1 = 160
pwm1 = 176
pwm1 = 192
pwm1 = 208
pwm1 = 224
saisir Q pour quitter le test
1
Enable CCP1
Test CCP1 en mode PWM associé à TMR2, pwm 16 à 240
pwm1 = 16 <-- OK presence signal
pwm1 = 32
pwm1 = 48
pwm1 = 64
pwm1 = 80
pwm1 = 96
pwm1 = 112
pwm1 = 128
pwm1 = 144
pwm1 = 160
pwm1 = 176
pwm1 = 192
pwm1 = 208
pwm1 = 224
Aide toi, le ciel ou FantasPic t'aidera

Generateur DTMF 18F27K42 [Solved]
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#25 Message par satinas » lun. 21 nov. 2022 11:11

Ok, j'avais juste recompilé ton programme sans le lancer, mes essais ont aussi été faits avec CCP1 sur un programme test.
Tu peux aussi faire CCPR1 = pwm_1 directement. Ces fonctions MikroC sont trop lentes. Après, l'adaptation aux données sinus, j'ai pas encore tout compris, mais c'est pas grave :)

Explication pour le programme fantôme. Le listing ne désassemble pas l'instruction MOVFFL du 18F27K42. Il manque le premier des 3 octets de cette instruction. En regardant le fichier HEX, on retrouve bien les instructions complètes, 12 octets et 6 cycles. c'est faisable en 8 octets et 4 cycles avec MOVF/MOVWF si pwm_1 était en mémoire access, ce qui n'est pas le cas, elle est en 0xBD/0xBE.

Code : Tout sélectionner

507:                 PWM5DC = pwm_1;
1025C  0060          ; MOVFFL pwm_1L,PWM5DCL
1025E  F2F7     NOP  ;
10260  FF6C     NOP  ;
10262  0060          ; MOVFFL pwm_1H,PWM5DCH
10264  F2FB     NOP  ;
10266  FF6D     NOP  ;
Modifié en dernier par satinas le lun. 21 nov. 2022 18:43, modifié 1 fois.

Generateur DTMF 18F27K42
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#26 Message par paulfjujo » lun. 21 nov. 2022 11:48

je confirme, tests avec SQA analyser comme temoin.
The alignment of the 10 bits from the CCPR register is determined by the CCPxFMT bit.
FIGURE 23-5: PWM 10-BIT ALIGNMENT

FMT=0
CCPRxH bits 9 et 8 = MSB
CCPRxL bit 7..0 = LSB

si FMT=1
CCPRxH = bit 9...2
CCPRxL = bits 1..0



avec FMT=0 cadrage à droite
si on travaille avec CCPR1L= pwm (8 bits value) et donc CCPR1H=0
maxima = 22% pour Pwm=224
... normal CCP1 travaille en 10 bits ! c'est le probleme que je constatais avec CCP1 sur XC8 !

avec FMT=1 cadrage à gauche
CCPR1L=0
CCPR1H= pwm1
comportement SEMBLABLE qu'avec la fonction MikroC PWM1_Set_Duty(pwm1);


// avec FMT=1
SQA=1; // debut de la 1ere capture
CCPR1L=0;
CCPR1H=pwm1;
while(TMR2IF_bit==0);
TMR2IF_bit=0;

Delay_ms(1); // encadrement de la mesure signal pwm sur l'analyser
SQA=0;

:eek:
Par contre, surprise !
si FMT1=1
:!!: PWM1_Set_Duty(pwm1); NE MARCHE PLUS!
il faut FMT=0 !
:furieux: sacré salade , pourquoi faire simple quand on peut faire compliqué!

rappel: FMT est à 0 au reset !

remarque :

The CCPRxH:CCPRxL register pair can be written to at any
time; however the duty cycle value is not latched into
the 10-bit buffer until after a match between T2PR and T2TMR.


avec l'analyser logique , je ne vois pas de difference
au changement de valeur ! avec ou sans synchro Timer2
:!!: synchro utile ??
Aide toi, le ciel ou FantasPic t'aidera

Generateur DTMF 18F27K42 [Solved]
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#27 Message par satinas » lun. 21 nov. 2022 12:12

C'est un mécanisme interne, il n'y a rien à faire après le réglage des 2 consignes PR et CCPR.
La période PWM démarre après overflow TMR=PR du timer FOSC/4.
- TMR = 0, CCPR est latché, signal haut, TMR s'incrémente (+2 bits avec FOSC)
- lorsque (4*TMR)+(0 à 3) = CCPR signal bas.
- lorsque TMR = PR signal haut
Ensuite en réglant le postscaler, on a un évènement TMRIF et une interruption possible toutes les 1 à 16 périodes PWM. CCPR peut être modifié à tout moment, la valeur sera prise en compte au prochain overflow timer.

Generateur DTMF 18F27K42 [Solved]
gwion
Amateur
Amateur
Messages : 192
Enregistré en : février 2022

#28 Message par gwion » mar. 27 déc. 2022 10:03

Bonjour tout le monde,

Je viens me greffer sur ce sujet, car je tente de porter le code de Roman Black vers le 16F876A.
Environnement est MPLAB X et le compilateur XC8.
Je rencontre quelques problèmes de fonctionnement... J'ai bien tenté de décortiquer votre discussion pour trouver le loup, mais je suis quelque peu largué :sifflotte:
Donc avec ce code, j'ai bien du PWM sur CCP1 (et même sur CCP2 soit dit en passant). Par contre j'ai la très nette impression qu'il n'y a qu'une seule fréquence présente. De plus, je suis censé faire défiler les 16 tonalités par les 2 boucles FOR imbriquées, mais à l'oreille c'est toujours la même...
Si quelqu'un pouvait me donner une piste ce serait merveilleux :-)
Bonne journée.

Bruno

Code : Tout sélectionner

// Portage du code source de génération DTMF Roman Black pour le 16F876A
//

#define _XTAL_FREQ 24000000
 
// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = ON         // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#include <xc.h>

// Global Variables
unsigned long waveA   __at0x15 );   // 32bit accumulators for the 2 sinewaves
unsigned char waveA_2 __at0x17 );   // overload for fast access to byte 2
unsigned long waveB   __at0x19 );  
unsigned char waveB_2 __at0x1B );   // overload for fast access to byte 2

unsigned long BDA_periodA;  // 32bit periods for the 2 sinewaves
unsigned long BDA_periodB;
 
uint8_t  drow=0;     // DTMF selected row and column
uint8_t  dcol=0;

uint8_t u8_NbCycleTimer0;

__bit bitFinTempoDTMF;

// defines for the DTMF sine frequencies
// Sinewave is a lookup table of 64 steps, to generate 1633 Hz each step is 1633 * 64
// 24bit Binary divider uses byte2 (/65536)
// PWM freq is 128 PIC instructions (8Mhz xtal *PLL) = 62500 Hz
// So the math is;  Fout * 64 * 65536 / Fpwm
// we can use a constant Fout * (64 * 65536 / 62500) = Fout * 67.108864
#define Frow0 46775   // 697 Hz  DTMF rows
#define Frow1 51674   // 770 Hz
#define Frow2 57177   // 852 Hz
#define Frow3 63149   // 941 Hz

#define Fcol0 81135   // 1209 Hz  DTMF columns
#define Fcol1 89657   // 1336 Hz
#define Fcol2 99120   // 1477 Hz
#define Fcol3 109589  // 1633 Hz

// sinewave table, range 0-99, 64 entries
const unsigned char sine64[64] = {
50,54,59,64,68,73,77,81,85,88,91,93,95,97,98,99,99,99,98,97,95,93,91,88,85,81,77,73,68,64,59,54,
50,45,40,35,31,26,22,18,14,11,8,6,4,2,1,0,0,0,1,2,4,6,8,11,14,18,22,26,31,35,40,45 };
 
//=============================================================================
//  MAKE DTMF TONE
//=============================================================================
void make_DTMF_tone(void)
{
  
//-------------------------------------------------------
  // this generates the 2 accurate sinewaves together.
  // a DDS algorithm calculation is done once every PWM cycle,
  // then the 2 sinewaves are generated by the PIC PWM module.
  // For a full description of algorithm; www.RomanBlack.com/one_sec.htm#BDA
  // NOTE! for good speed PWM TMR2 is manually polled, not an interrupt.
  //-------------------------------------------------------
  
unsigned char pwm;
  
bitFinTempoDTMF=0;
  
u8_NbCycleTimer0 0;
  
INTCONbits.GIE 1;  
  
TMR0 0;
  
RB1 1;  //  led on    
  
INTCONbits.T0IE 1// start timer
    
  // loop and generate dual sinewave DTMF tone
  
while(bitFinTempoDTMF==0)
  {
    while(
PIR1bits.TMR2IF==0);
        
    
PIR1bits.TMR2IF 0;
  
    
// calc the A sinewave, 
    
waveA += BDA_periodA;            // zero-error Accumulation 
    
pwm sine64[waveA_2 0x3F];    // Binary Divide output (/65536) and keep 6 bits
    
if(drow == 4pwm 0;        // disable if row is OFF

    // calc the B sinewave, and ADD the 2 waves together
    
waveB += BDA_periodB;                  
    if(
dcol != 4pwm += sine64[waveB_2 0x3F];  // only enable if col is ON    

    // scale the summed sinewaves and place in PWM module
    
pwm = (pwm >> 1);   // scale 0-200 back to 0-100 for PWM
    
pwm += 14;          // offset to centre waveform (100 into centre of 128)
    
CCPR2L pwm;       // load added sinewaves into PWM module
  
}

}
//-----------------------------------------------------------------------------

void main()
{

    
CMCON 0x07;        // turn off comparators (make all pins digital)
    
OPTION_REGbits.T0CS 0;    //  0: Timer0 incrémenté par horloge interne  1: horloge externe sur RA4
    
    
OPTION_REGbits.PSA=0;    // 0-préscaler assigné au Timer0 1-affecté au watchdog (pour ne pas diviser par 2))
    
    // on fixe le prescaler 
    
OPTION_REGbits.PS2=1
    
OPTION_REGbits.PS1=1;
    
OPTION_REGbits.PS0=1;

    
//TRISE = 0b01111111;   // RE7 is ouput for PWM

    //-------------------------------------------------------
    // startup delay, let the PSU voltage stabilise etc.
    
__delay_ms(10);

    
// setup PWM module
    // Marche à suivre pour faire du PWM :
    //  - Ecrire dans PR2 la valeur permettant d'obtenir la Période désirée.
    // - Ecrire dans CCPR1L la valeur donnant la durée du Duty cycle.
    // - Configurer la broche d'utilisation en sortie ( bit = 0 dans TRISC).
    // - Initialiser le Timer 2 par T2CON ( prédiv, TMR2 on).
    // - Initialiser le CCP par CCP1CON (mode PWM, 2 bits LSB Duty cycle)
  
    
TRISC 0x00;
    
T2CON 0b00000100;     // TMR2 on, prescale 1:1
    
PR2 = (128-1);            // PWM at period = 128
    
CCPR2L 0;               // start PWM = 0% by default
    
CCP2CON 0b00001100;     // PWM module ON, output A on PORTE.F7
    //NOTE!! make sure CCP2MX is set to RE7 in the PIC config (edit project)

    
PORTB 0
    
// TRISB0 = 0; //RB0 as Output PIN
    // TRISB1 = 0; //RB1 as Output PIN
    // TRISB2 = 0; //RB2 as Output PIN
    
TRISB 0x00//Initialize PortB as output

  //-------------------------------------------------------
  // main running loop
    
while(1)
    {
    for (
drow=0;drow<3;drow++) {
        for (
dcol=0;dcol<3;dcol++) {
            
            switch (
drow) {
                case 
BDA_periodA Frow0;
                case 
BDA_periodA Frow1;
                case 
BDA_periodA Frow2;
                case 
BDA_periodA Frow3;
            }
            
            switch (
dcol) {
                case 
BDA_periodB Fcol0;
                case 
BDA_periodB Fcol1;
                case 
BDA_periodB Fcol2;
                case 
BDA_periodB Fcol3;
            }

            
make_DTMF_tone();
            
            
__delay_ms(1000);  
        }
    }
    
    
__delay_ms(6000);  
  }
}
//-----------------------------------------------------------------------------


void __interrupt() isr(void) {
    
// INTCONbits.T0IF : flag débordement timer 
    
if (INTCONbits.T0IF) {
    
        if ( 
u8_NbCycleTimer0 >= 99 ) {
            
INTCONbits.T0IE 0// stop timer
            
TMR0 0;
            
RB1 0;
            
bitFinTempoDTMF=1;
            
u8_NbCycleTimer0=0;
        }
        else {
            
u8_NbCycleTimer0 ++;
        }
        
        
INTCONbits.T0IF 0;  // acquittement du flag pour autoriser int suivante
    
}
}
 
 

Generateur DTMF 18F27K42 [Solved]
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#29 Message par paulfjujo » mar. 27 déc. 2022 10:27

bonjour,


je vois que tu n'as qu'une seule table sinus ?
il en faut 2
ce qui pourrais expliquer que tu n'obtiens qu'une seule frequence
la meme pour Wave_A ou Wave_B

regarde le code 18F27K42
extrait ici

Code : Tout sélectionner

// This uses dual sinewaves of 28% different amplitudes, to match the spec for "twist" in
 // telephone DTMF to ensure the higher freq has a higher amplitude, to cope with line losses.
  
uint8_t Sin64L[64]={
 
// const uint8_t Sin64L[64]={   <-- en mikroC!
  
39,42,46,50,53,57,60,63,66,68,71,72,74,75,76,77,77,77,76,75,74,72,71,68,66,63,60,57,53,50,46,42,
  
39,35,31,27,24,20,17,14,11,9,6,5,3,2,1,1,1,1,1,2,3,5,6,9,11,14,17,20,24,27,31,35};
 
// const uint8_t Sin64H[64] = {  <-- en mikroC !
  
uint8_t Sin64H[64] = {
  
50,54,59,64,68,73,77,81,85,88,91,93,95,97,98,99,99,99,98,9795,93,91,88,85,81,77,73,68,64,59,54,
  
50,45,40,35,31,26,22,18,14,11,8,6,4,2,1,1,1,1,1,2,4,6,8,11,14,18,22,26,31,35,40,45};

 


:-D Bonne fete de fin d'année !
Aide toi, le ciel ou FantasPic t'aidera

Generateur DTMF 18F27K42 [Solved]
gwion
Amateur
Amateur
Messages : 192
Enregistré en : février 2022

#30 Message par gwion » mar. 27 déc. 2022 11:54

Bonjour Paul :-)

Effectivement, le loup était là, merci beaucoup Paul.
Du coup je vois bien qu'il y a bien un mixage de fréquences sur la simulation.
Pour info, J'avais récupéré le source MikroC sur le site de Roman (archive Download SG13_DTMF.zip sur https://www.romanblack.com/SG/SG_tutorial.htm) et il semble que, bien que parlant de DTMF, le programme ne génère qu'un sinus pur.
Et bonnes fêtes de fin d'année à toi également.

Voilà le résultat en simulation (trace bleue = sortie PWM, trace jaune = sortie du filtre 4,7k et 47nF)

Capture d’écran 2022-12-27 114905.png
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 35 invités