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

18F27K42 et MikroC mystere et boule de gomme
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#1 Message par paulfjujo » dim. 22 août 2021 12:04

Bonjour,


"à chaque jour suffit sa peine" !

La taille de mon code augmente bien sur , au fur et à mesure des rajouts de fonctionnalités
:eek: mais aujoud'hui je vois qu'une partie ne répond plus correctement !
ce n'est pourtant que l'Init du NCO ( Numerical Controlled Oscillateur) en début de programme
le probleme est bénin , mais EXISTANT !

la version precedente me donnait bien la valeur de fréquence (calculée) , associé au parametre Incrément du NCO
c'est en fait le simple resiultat de calcul avec entier long et flottants
aujourd'hui , j'ai 0.00 comme résultat au lieu de 599.9 ?????
aucune modif faite au niveau de cette Init NCO !

Code : Tout sélectionner



//declarations
const code float NCO1_Clock[5]={64000000,64000000,32000,500000,31000};
const char NCO1_CL4[] =" MFINTOSC/4 (31 kHz)";
const char NCO1_CL3[] ="  MFINTOSC (500 kHz)";
const char NCO1_CL2[] =" LFINTOSC" ;
const char NCO1_CL1[] =" HFINTOSC ";
const char NCO1_CL0[] =" FOSC";
// Increment = Freq * 2097512/ NCO1 clock
const float NCO1_Coeff= 4.194; // 2097152/500.000=  4.194
const char * NCO1_Clock_Name[] ={ NCO1_CL0,NCO1_CL1,NCO1_CL2,NCO1_CL3, NCO1_CL4};
char NCO1_Clock_Choix=3;  // 0 à 4
char PWS_Valeur=;  // = 2 ^ PWS_Choix =>{1,2,4,8,16,32,64,128]};
char PWS_Choix;  // 0 à 7
unsigned long Increment;
-----------------------------------------------------

partie de la fonction  void Init_NCO(void); 
appelée depuis le main program


    F0
= (NCO1_Clock[NCO1_Clock_Choix] * (float)Increment )/ 2097152.0;
    if (Bavard==1)
     {
      CPrint (" Freq Output=  ");
      Float2Ascii (F0,CRam1,1);
      Print (CRam1);  CRLF1();
      Delay_ms(500);
      }
      


sur terminal :
(0.000) Increment = 2516
(0.000) NCO1CLK choix = 3 soit MFINTOSC (500 kHz) 500000.0 Hz
(0.000) Freq Output= 0.0


l'increment est OK, la frequence de base 500KHz est OK
mais le resultat de l'equation globale est faux .
La valeur Freq est bien à zero, car rien ne sort si je valide le NCO1EN_bit

DIVISER POUR MIEUX REGNER .. c'est ma device dans ces cas là

je modifie donc le code pour separer le calcul en 2 operations ,
pour voir ce qui se passe ..
via rajout d'une variable intermediaire float F1;

Code : Tout sélectionner



     CPrint 
(" F0=  ");
     F0= (NCO1_Clock[NCO1_Clock_Choix] * (float)Increment ) ;
     Float2Ascii (F0,CRam1,1);
     Print (CRam1);  CRLF1();
     F1=F0 / 2097152.0 ;
     if (Bavard==1)
     {
      CPrint (" Freq Output=  ");
      Float2Ascii (F1,CRam1,1);
      Print (CRam1);  CRLF1();
      Delay_ms(500);
      }


et je retouve mon resultat OK
et j'obtiens bien la note à 600Hz si je valide NCO1EN_Bit

((0.000) Increment = 2516
(0.000) NCO1CLK choix = 3 soit MFINTOSC (500 kHz) 500000.0 Hz
(0.000) F0= 1257999897.0
(0.000) Freq Output= 599.9


Cela demontre que le compilateur MikroC est quand meme un peu (beaucoup) inconsistant ..
si le rajout de code modifie le comportement d'un morceau déja testé OK auparavant

* probleme de Pile ( Stack) ? :sifflotte: .. pas la pile plate de 4,5V !
* pas de probleme d'appel externe via interrupt dans cette phase du programme ...
* Meme si je deplace le contenu de ma subroutine / fonction dans le main programme
pour eviter un appel de fonction ( usage de stack) en moins, c'est le meme probleme.
* probleme de Bank ?? ... on ne s'en preoccupe pas ..en C ( sauf si usage asm)
* probleme d'acces entre data en Flash ?
* le compilo se prend la tete ! -> aspirine pour compilo ?


:mur: donc je ne vois pas pourquoi.
quoique il me semble avoir déja vu des cas ou MikroC demande à ne pas trop mettre de
calculs sur la meme ligne, ou avec trop de parentheses , de les eclater sur plusieurs lignes ..

une idée ?

demander à MikroE ? ... le forum MikroC est quasi mort !

Le fait d'utiliser l'UART à outrance , charge effectivement un peu plus le MCU
mais cette bete n'est actuellement utilisée qu'à 6.2% de RAM et 17.6% de code ,
et me permet quand meme de debugger .. ou bugger ?

Charge_18F27K42_2021-0822.JPG


est-ce le fait d'avoir rajouté / testé ceci , pour Temps_X
exit

Code : Tout sélectionner



#define DO4 523
#define RE4 587
#define MI4 659
#define FA4 698
#define SOL4 784
#define LA4 880
#define SI4 988

volatile  typedef  struct
{
 unsigned int Note;
 unsigned int Tempo;
}
 Partition;

Partition Melodie1[] = {
 {DO4, 1},
 {DO4, 1},
 {DO4, 1},
 {RE4, 1},
 {MI4, 2},
 {RE4, 2},
 {DO4, 1},
 {MI4, 1},
 {RE4, 1},
 {RE4, 1},
 {DO4, 4}

};

void Au_clair_de_la_lune()
 {  int i,j;
    CPrint("Melodie 1 \r\n");
    for (i=0;i<11;i++)
    {
    Led_B=1;
    WordToStr( Melodie1[i].Note,CRam1);
    Print(CRam1);UART1_Write(TAB);
    WordToStr( Melodie1[i].Tempo,CRam1);
    Print(CRam1);CRLF1();
    Set_Note_NCO(Melodie1[i].Note);
    NCO1EN_bit=1;
    //VDelay_Advanced_ms(pause, fosc);
    for (j=0;j< Melodie1[i].Tempo ;j++) Delay_ms(300);
    NCO1EN_bit=0;
    Led_B=0;
    Delay_ms(100);
    }
    CRLF1();
  }
 


(0.499) Melodie 1
(0.000) 523 1
(0.398) 523 1
(0.399) 523 1
(0.401) 587 1
(0.398) 659 2
(0.699) 587 2
(0.696) 523 1
(0.401) 659 1
(0.401) 587 1
(0.397) 587 1
(0.398) 523 4
(1.298)


:!!: NE PAS UTILISER MIKROC pour UN MCU AUTOMOBILE !
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Modifié en dernier par paulfjujo le jeu. 2 sept. 2021 18:56, modifié 2 fois.
Aide toi, le ciel ou FantasPic t'aidera

18F27K42 et MikroC mystere et boule de gomme
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#2 Message par satinas » dim. 22 août 2021 12:26

Tu fais les questions et les réponses, c'est pratique :)
As-tu essayé de passer NCO1_Clock[] hors de la flash ?

18F27K42 et MikroC mystere et boule de gomme
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

#3 Message par Temps-x » dim. 22 août 2021 14:09

Bonjour paulfjujo, satinas, et tout le forum,

:sifflotte: Peux tu inclure de l'asm dans ton code, comme ça MIKROC fonctionnera bien .... et de plus l'asm rendra service au C :lol:

==> A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

18F27K42 et MikroC mystere et boule de gomme
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#4 Message par paulfjujo » dim. 22 août 2021 17:49

satinas a écrit :Tu fais les questions et les réponses, c'est pratique :)
As-tu essayé de passer NCO1_Clock[] hors de la flash ?


oui, aucun changement ..

j'ai fais une version tres allégée du programme ..
test_wo_bug_18F27K42.zip

et là,
:eek: impossible de reproduire le probleme !

(0.000)
(0.000) Init Generateur de Frequence NCO ,sortie RC0 => Buzzer piezo
(0.000) Avec Bug
(0.000) Init de base NCO (voir page 454 datasheet)
(0.000) Polarity =0 (Not inverted)
(0.000) NCO1 operates in Fixed Duty Cycle mode 50% , divide by 2 (PFM=0)
(0.000) Increment = 2516
(0.000) NCO1CLK choix = 3 soit MFINTOSC (500 kHz) 500000.0 Hz
(0.000) Freq Output= 599.9
(0.500) Melodie 1
(0.000) 523 1
(0.391) 523 1
(0.403) 523 1
(0.397) 587 1
(0.397) 659 2
(0.703) 587 2
(0.695) 523 1
(0.398) 659 1
(0.399) 587 1
(0.399) 587 1
(0.401) 523 4
(1.295)



à Temps_X :
mettre de l'ASM, un chouia ..oui

Code : Tout sélectionner


 
// test clignotement Led_Temoin => verifie que le programme est lancé
    
for (i=0;i<4;i++)
    {
        
_asm btg LATA,;
       
Delay_ms(250);
    } 



mais manipuler des flottants,multiplication division ..
melange avec le C , compilo pas content
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

18F27K42 et MikroC mystere et boule de gomme
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#5 Message par paulfjujo » lun. 23 août 2021 15:15

bonjour,


idea ! le proverbe précédement cité se confirme...

Aujourd'hui je reteste mon programme .. voulant absolument dénicher où est ce bug !
NEGATIF,
:furieux: plus de bug !!!

est-ce le fait de recharger MikroC ?

Code : Tout sélectionner

(0.000)  Init Generateur de Frequence NCO ,sortie RC0 => Buzzer piezo
(0.000)  Init de base NCO (voir page 454 datasheet
(
0.000)  Polarity =(Not inverted
(
0.000)  NCO1 operates in Fixed Duty Cycle mode 50% , divide by 2  (PFM=0)
(
0.000)  Increment=2516   ->(float) Increment ) =>       2516   2516.0
(0.075)  Increment =       2516
(0.000)  NCO1CLK choix 3 soit   MFINTOSC (500 kHz)    500000.0 Hz
(0.000)  Calcul direct F0= ( (float) Increment NCO1_Clock[NCO1_Clock_Choix] )/2097152.0;
(
0.000)  Resultat Freq Output=  599.9
(0.446Melodie 1 
(0.005)   523        1
(0.395)   523        1
(0.400)   523        1
(0.399)   587        1
(0.402)   659        2
(0.696)   587        2
(0.699)   523        1
(0.398)   659        1
(0.400)   587        1
(0.399)   587        1
(0.400)   523        4
(1.294)  


nota :
resultat =
599.9 avec calcul direct sur 1 seule ligne de programme
ou 601.0 avec calculs séparés

:sifflotte: conclusion : Le flottant porte bien son nom

:!!: Dans certains cas, il faudra rajouter un FPU ?
ou passer au PIC32 , voir DSP


Code : Tout sélectionner

(0.000)  Increment=2516   ->(float) Increment ) =>       2516   2516.0
(0.000)  Increment =       2516
(0.000)  NCO1CLK choix 3 soit   MFINTOSC (500 kHz)    500000.0 Hz
(0.000)  Calcul direct F0= ( (float) Increment NCO1_Clock[NCO1_Clock_Choix] )/2097152.0;
(
0.000)  Resultat Freq Output=  599.9




en calculs séparés

Code : Tout sélectionner

(0.000)  Increment =       2516
(0.000)  NCO1CLK choix 3 soit   MFINTOSC (500 kHz)    500000.0 Hz
(0.000)  Sans Bug
(0.000)  F1  choix ref frequence 500000.0
(0.000)  F2 Increment 2516.0
(0.000)  F0 F1 F2 =calcul intermediare 1260319828.9
(0.000)  Resultat Freq Output=  601.0;
 


exit allez, on passe à autre chose ...
Aide toi, le ciel ou FantasPic t'aidera

[clos] 18F27K42 et MikroC mystere et boule de gomme
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#6 Message par paulfjujo » jeu. 2 sept. 2021 18:55

Bonjour,

je ne peux decidement pas fermer ce post ...

Aujourd'hui , avec mon code grandissant en taille
ma subroutine au_clair_de_la_lune ne change plus de note ,mais s'execute avec la meme note !
de meme le delai n'est pas respecté. ?

en mettant le code de la subroutine void Set_Note_NCO( float Fr)
directement dans la subroutine au_clair_de_la_lune
c'est OK !

ou sinon, en gardant l'appel de Set_Note_NCO( float Fr)
MAIS en initialisant le pointeur pI dans la partie declaration de variables ( globales)
char *pI=&Increment ;
C'est aussi OK ...

alors que j'ai deja au debut du main programme
pI=&Increment;

si je reduit la taille de mon code ...
c'est OK sans cette init forcée
char *pi;

l'init dans le debut du main devrait etre suffisante ?...
idea ! une idée du probleme ...
:sifflotte: ça se passe entre le clavier et les didis via les neuronnes ? oops ou encore un mystere MikroC ..
le compilo qui arrange ,optimise à sa guise ...

Code : Tout sélectionner




 
//------- NCO --------------------------
const code float NCO1_Clock[5]={64000000.0,64000000.0,32000.0,500000.0,31000.0};
//float NCO1_Clock[5]={64000000,64000000,32000,500000,31000};
const char NCO1_CL4[] =" MFINTOSC/4 (31 kHz)";
const 
char NCO1_CL3[] ="  MFINTOSC (500 kHz)";
const 
char NCO1_CL2[] =" LFINTOSC" ;
const 
char NCO1_CL1[] =" HFINTOSC ";
const 
char NCO1_CL0[] =" FOSC";
// Increment = Freq * 2097512/ NCO1 clock
const float NCO1_Coeff4.194// 2097152/500.000=  4.194
const char NCO1_Clock_Name[] ={ NCO1_CL0,NCO1_CL1,NCO1_CL2,NCO1_CL3NCO1_CL4};
char NCO1_Clock_Choix=3;  // 0 à 4
char PWS_Valeur=;  // = 2 ^ PWS_Choix =>{1,2,4,8,16,32,64,128]};
char PWS_Choix=3;  // 0 à 7
unsigned long Increment=0L;
char *pI//=&Increment;

#define DO_4 523
#define RE_4 587
#define MI_4 659
#define FA_4 698
#define SOL_4 784
#define LA_4 880
#define SI_4 988

volatile  typedef  struct
{
  
unsigned int Note;
  
unsigned int Tempo;
Partition;

// Melodie à jouer
Partition Melodie1[] = 
{
 {
DO_41},
 {
DO_41},
 {
DO_41},
 {
RE_41},
 {
MI_42},
 {
RE_42},
 {
DO_41},
 {
MI_41},
 {
RE_41},
 {
RE_41},
 {
DO_44},
};

void Init_NCO(void)       // at 600Hz
 
{

    if (
Bavard==1)
    {
     
CPrint(" Init de base NCO (voir page 454 datasheet) \r\n");
     
CPrint(" Polarity =0 (Not inverted) \r\n");
     
CPrint(" NCO1 operates in Fixed Duty Cycle mode 50% , divide by 2  (PFM=0)\r\n");
    }
     
NCO1CON.NCO1EN=0;  // disable
     
NCO1CON.NCO1POL=0//0 = NCO1 output signal is not inverted   1=inverted
     // NCO1CON.PFM=1; // duty cycle=> by PWM
     // 1 = NCO1 operates in Pulse Frequency mode
     // 0 = NCO1 operates in Fixed Duty Cycle mode, divide by 2

     
NCO1CON.PFM=0//else Fixed duty cycle is 50%
     
Increment=2516L;      //600Hz
       
F2= (float)Increment ;
       
CPrint (" Increment=2516   ->(float) Increment ) => ");
        
LongWordToStr(Increment,CRam1);
        Print (
CRam1); Espaces;
        
Float2Ascii (F2,CRam1,1);
        Print (
CRam1);
        
CRLF1();
     
pI=&Increment;   // pointeur sur les parametres NCO
     
if (Bavard==1)  
     { 
CPrint (" Increment = ");  LongWordToStr(Increment,CRam1);
      Print(
CRam1);  CRLF1();
      }
      
NCO1INCU=  *(pI+2);
      
NCO1INCH=  *(pI+1);
      
NCO1INCL=  *(pI+0);
      
PWS_Valeur=0;
     
//  0=FOSC  1=HFINTOSC  3=500Khz   4=31000
     // NCO1_Clock_Choix=4;  //  4=31000
      
NCO1_Clock_Choix=3;  //  3=500Khz
     
if (Bavard==1
     {
      
CPrint (" NCO1CLK choix = ");
      
cx=  NCO1_Clock_Choix+48;
      
UART1_Write(cx);
      
CPrint (" soit ");  CPrint(  NCO1_Clock_Name[NCO1_Clock_Choix] );
      
F1=NCO1_Clock[NCO1_Clock_Choix];
      
UART1_Write(TAB);Float2Ascii(F1,CRam1,1);
      Print (
CRam1);  CPrint(" Hz\r\n");
      }
      
NCO1CLK=  PWS_Valeur<<|  NCO1_Clock_Choix ;
        
//Foverflow=  NCO clock * Increment / 2^20   ;   /1 048 576
     // 2097152.0 = 2 x  Foverflow,car division NCO clock par 2 pour duty 50%
       
CPrint (" Calcul direct F0= ( (float) Increment * NCO1_Clock[NCO1_Clock_Choix] )/2097152.0;\r\n");
      
F0= ( (float) Increment NCO1_Clock[NCO1_Clock_Choix] ) / 2097152.0;
       
     if (
Bavard==1)
     {
      
CPrint (" Resultat Freq Output=  ");
      
Float2Ascii (F0,CRam1,1);
      Print (
CRam1);  CRLF1();
      
Delay_ms(500);
      }
      
Drapeaux.NCO_initialise=1;
  }
  
void Set_Note_NCOfloat Fr)
{
   
NCO1CON.NCO1EN=0;
   if (
Fr>30.0)
   {
     
Increment= (unsigned long) ( Fr*  NCO1_Coeff);
     
pI=&Increment;
     
NCO1INCU=  *(pI+2);
     
NCO1INCH=  *(pI+1);
     
NCO1INCL=  *(pI+0);
   }
}
  


 
void Au_clair_de_la_lune()
 {  
int i=0;
    
int j=0;
    
float Fx=0.0;
    
NCO1EN_bit=0;  // stop
    
CPrint(" Melodie 1\r\n");
    for (
i=0;i<11;i++)
    {
       if (
Bavard==1)
     {

       
WordToStrMelodie1[i].Note,CRam1);
       Print(
CRam1);UART1_Write(TAB);
       
WordToStrMelodie1[i].Tempo,CRam1);
       Print(
CRam1);CRLF1();
      }
     
Fx=(float) Melodie1[i].Note;
     
Set_Note_NCO(Fx);      //  <- BAD
    //---Ok en remplaçant  Set_Note_NCO(Fx);  par le code ci-dessous ----
    //  Increment= (unsigned long) ( Fx*  NCO1_Coeff);
    //  pI=&Increment;
    //  NCO1INCU=  *(pI+2);
    //  NCO1INCH=  *(pI+1);
    //  NCO1INCL=  *(pI+0);
    //----------------------------
     
NCO1EN_bit=1;  // start
      
for (j=0;jMelodie1[i].Tempo ;j++) Delay_ms(300);
      
NCO1EN_bit=0;  // stop
      
Delay_ms(100);
    }
  }
  
  
----------  
main ---------

   
Bavard=1;
    
Drapeaux.NCO_initialise=0;
    
Increment=0L;
    
pI=&Increment;
  
    
CPrint(" Init Generateur de Frequence NCO ,sortie RC0 => Buzzer piezo\r\n");
    
Init_NCO();  
     
Au_clair_de_la_lune();
    
CRLF1();
  
  
  
 



à l'execution donne , dans les 2 cas

Init Generateur de Frequence NCO ,sortie RC0 => Buzzer piezo
Init de base NCO (voir page 454 datasheet)
Polarity =0 (Not inverted)
NCO1 operates in Fixed Duty Cycle mode 50% , divide by 2 (PFM=0)
Increment=2516 ->(float) Increment ) => 2516 2516.0
Increment = 2516
NCO1CLK choix = 3 soit MFINTOSC (500 kHz) 500000.0 Hz
Calcul direct F0= ( (float) Increment * NCO1_Clock[NCO1_Clock_Choix] )/2097152.0;
Resultat Freq Output= 599.9
Melodie 1
523 1
523 1
523 1
587 1
659 2
587 2
523 1
659 1
587 1
587 1
523 4

Aide toi, le ciel ou FantasPic t'aidera

18F27K42 et MikroC mystere et boule de gomme
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#7 Message par satinas » jeu. 2 sept. 2021 20:27

Bonjour,

Je ne vois pas de problème, à part les éventuels warnings concernant les types de variables.

Comme le pointeur Pi sert à remplir des registres, autant le créer en unsigned. Ensuite qu'on l'assigne lors de sa définition ou dans le programme, cela ne devrait rien changer. Je sais qu'avec MikroC les char sont unsigned par défaut, mais c'est pas standard et je trouve qu'il vaut mieux le spécifier.

unsigned long Increment;
unsigned char *pI = (unsigned char *)&Increment;
pI = (unsigned char *)&Increment;
NCO1INCU = *(pI+2);


Retourner vers « Langage C »

Qui est en ligne

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