Comment piloter une PLL ?

Bonjour a tous,

Je dispose de quelques pll que j’aimerais aujourd’hui utiliser, j’aimerai notamment faire fonctionner le fameux MC145170P http://www.vastint.com/upload/file/MC145170_PLL_Frequency_Synthesizer_with_Serial_Interface.pdf avec un VCO en VHF , ce chip utilise un bus SPI, pour définir la fréquence du VCO on a besoin de charger 3 registres R, N et C , j’ai trouver un petit prog pour pouvoir les calculer facilement, http://doxical.free.fr/resources/exstatic/mc145170/MC145170_Ctl.exe
mes paramètres comme exemple sont: fref: 4 mhz, fout: 145mhz, utilisation de PDout, j’obtient donc:

R, 00A0
N, 1770
C, 63

c’est là que sa se corse car je ne sais pas trop comment envoyer ces 3 registres dans le chip, notament le dernier, C, j’ai griffoné un bout de code, quelqu’un d’entre vous aurait il deja utilise ce genre de chip ?

#include <SPI.h>

int latchPin = 8; //Enb
int clockPin = 12; //Clk
int dataPin = 11; //Data

void setup() 
{
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() 
{  
  digitalWrite(latchPin, LOW);  
  digitalWrite(clockPin, LOW);
  
  shiftOut(dataPin, clockPin, MSBFIRST, (00000000 >> 8));  //00000000 exemple 8bits
  shiftOut(dataPin, clockPin, MSBFIRST, 00000000);
  shiftOut(dataPin, clockPin, LSBFIRST, (00000000 >> 8)); //00000000 exemple 8bits
  shiftOut(dataPin, clockPin, LSBFIRST, 00000000);  
  
  digitalWrite(latchPin, HIGH);
}

merci de votre aide et bonne journée

D'après la doc constructeur, le circuit reconnait automatiquement le registre adressé en fonction du nombre de bits transférés.

8 bits la donnée est pour le registre C 16 bits la donnée est pour le registre N 15 ou 24 bits la donnée est pour le registre R (dans le cas de l'arduino les transferts se font modulo 8 donc tu enverras 24 bits) Le cycle est marqué par l'état de la ligne ENB à zéro. La durée du cycle est sans importance c'est uniquement la transition d'ENB qui est importante. Donc pour les transferts 16 ou 24 bits: - tu fais descendre ENB, - tu envoies 1 octet, - tu envoies 1 second octet, - puis éventuellement un troisième, - tu fais remonter ENB

Pour C qui est un registre 8 bits: - tu fais descendre ENB, - tu envoies l'octet, - tu fais remonter ENB

Un bout de code (pas testé). Peut être utilisé indifféremment pour programmer l'un des 3 registres. On met le contenu du registre à programmer dans "valeur" et le nombre d'octets à envoyer dans nb.

//  sendReg
    Emission de la configuration d'un registre
    valeur : contient la valeur à placer dans le registre
    nb     : contient le nombre d'octets à envoyer
   //
void sendReg(unsigned long valeur, unsigned char nb){
    unsigned char tampon;
    unsigned char i=nb
    do{
        tampon = (unsigned char)(valeur >> ((i-1)*8));
        shiftOut(dataPin, clockPin, MSBFIRST, tampon);
        i--;
    }while(i>0);
}

Tu pourrais même créer 3 constantes REGISTRE_C, REGISTRE_N et REGISTRE_R qui définiraient la longueur du registre.

const char REGISTRE_C=1;
const char REGISTRE_N=2;
const char REGISTRE_R=3;

ensuite tu utilises comme ça

   val = ma_fonction_qui_calcule_la valeur_de_N()
   sendReg(val, REGISTRE_N)

   val = ma_fonction_qui_calcule_la valeur_de_C()
   sendReg(val, REGISTRE_C)

merci pour ces éclaircissement fdufnews,

si j'ai bien compris, on envoie pas directement le binaire mais on converti les hex avec la formule, du coup je peut les stocker de tel manière?

const char RegC = 0x63; //8 BITS
const char RegN = 0x05DC; //16 BITS
const char RegR = 0x0028; //24 BITS

en revanche, comme je ne fait que vraiment de la bidouille, je n'arrive pas utiliser le "do" que tu as mis dans le code

    //valeur : contient la valeur à placer dans le registre
    //nb     : contient le nombre d'octets à envoyer
void loop()
{
void sendReg(unsigned long RegC, unsigned char nb);
}
    unsigned char tampon;
    unsigned char i=1;
    do
{
        tampon = (unsigned char)(RegC >> ((i-1)*8));
        shiftOut(dataPin, clockPin, MSBFIRST, tampon);
        i--;
    }
while(i>0);
}

bonjour
tiens ça me donne envie un de ses jours de reinterfacer la gestion de MC145159 avec un arduino.
la derniere fois que j’ai joué avec c’etait en gerant le SPI par un port // en basic sur un I486 :grin:
autant dire que ce n’etait hier 8)
pour les curieux

et la base du code en basic

10 CLS
15 REM *********************************************************************
16 REM *                                                                   *
20 REM * Logiciel de programmation pour synth‚tiseur de fr‚quence MC145159 *
25 REM * par  F5HII & F6CSX (C) Juin 1999                                  *
26 REM *                                                                   *
29 REM *********************************************************************
30 REM
40 DIM R(14), N(18)
50 R(0) = 1:  ENVOI = 0
60 DX = &H378
70 REM DX: adresse h‚xa du port parallŠle
80 REM INV =1 si l'interface inverse les donn‚es, sinon INV=0
90 INV = 0
100 K = 255 * INV
110 N(0) = 1 - INV
115 REM N(0) est le bit de controle
120 REM mise … 0 de toutes les sorties de l'interface
130 OUT DX, K
140 CLS
150 PRINT "LOGICIEL UNIVERSEL DE PROGRAMMATION DU MC 145159 "
160 PRINT
170 IF INV = 1 THEN 210
180 IF INV = 0 THEN 220
190 PRINT "erreur inv = 0 ou 1"
200 END
210 PRINT "Logiciel configur‚ pour interface inversant les donn‚es": GOTO 230
220 PRINT "Logiciel configur‚ pour interface n'inversant pas les donn‚es"
230 PRINT
240 Fxtal = 12.8
250 IF (Fxtal < 1) OR (Fxtal > 20) THEN 240
260 PRINT
270 PRINT "Le pas du synth‚tiseur est fix‚ … 12,5 kHz par d‚faut"
280 FCOMP = 12.5
290 REM R est le diviseur de reference R=FXTAL/FCOMP"
300 R = 1000 * Fxtal / FCOMP
310 PRINT "La valeur du diviseur de la r‚f‚rence est R="; R
320 MEMR = R
330 IF R < 3 THEN 340 ELSE 360
340 PRINT "frequence de comparaison trop grande"
350 GOTO 280
360 IF R > 16383 THEN 370 ELSE 390
370 PRINT "frequence de comparaison trop petite"
380 GOTO 280
390 P = 64
400 IF P = 40 THEN 440
410 IF P = 32 THEN 440
420 IF P = 64 THEN 440
425 IF P = 128 THEN 440
430 GOTO 390
440 INPUT "fr‚quence … synth‚tiser FVCO EN kHz"; FVCO
450 REM M est le diviseur global entre FVCO ET FCOMP
455 PRINT FVCO
456 REM
460 M = FVCO / FCOMP
 
470 IF (M < 543) OR (M > 131071!) THEN 480 ELSE 500
480 PRINT "erreur de programmation"
490 GOTO 240
500 IF M < 65535! THEN 520 ELSE 440
510 GOTO 410
520 REM calcul des diviseurs A et N
530 N = INT(M / P)
540 a = M - N * P
550 R = MEMR
560 REM m‚morisation de R
570 PRINT "FVCO = (FXTAL/R).(NP+A)"
580 PRINT "R="; R
590 PRINT "N="; N
600 PRINT "A="; a
610 PRINT "P="; P
620 IF INV = 0 THEN 670
630 REM compl‚mentation de R, N et A
640 R = 16383 - R
650 N = 1023 - N
660 a = 127 - a
670 REM convertion en binaire des diviseurs A,N et R
680 REM convertion de R
690 REM R(0) et R(15) sont prealablement definis
700 FOR X = 14 TO 1 STEP -1
710 R(X) = INT(R / 2 ^ (X - 1))
720 R = R - R(X) * (2 ^ (X - 1))
730 NEXT X
740 REM convertion de N
750 REM N(0),bit de controle, est prealablement defini
760 REM N,A et le bit de controle forment un mot de 18 bits
770 FOR X = 10 TO 1 STEP -1
780 N(X + 7) = INT(N / 2 ^ (X - 1))
790 N = N - N(X + 7) * (2 ^ (X - 1))
800 NEXT X
810 REM convertion de A
820 FOR X = 7 TO 1 STEP -1
830 N(X) = INT(a / 2 ^ (X - 1))
840 a = a - N(X) * (2 ^ (X - 1))
850 NEXT X
860 PRINT "Affichage des donn‚es en binaire MSB <-----LSB": PRINT
870 PRINT "Diviseur de r‚f‚rence R (14 bits)"
880 PRINT "R(X)";
890 FOR X = 14 TO 1 STEP -1
900 PRINT R(X);
910 NEXT X
920 PRINT "Diviseur programmable N (10 bits), A (7 bits), bit de controle:"
930 PRINT "N(X)";
940 FOR X = 17 TO 0 STEP -1
950 PRINT N(X);
960 NEXT X
970 REM donn‚s sur BIT 0
980 REM clok   sur BIT 1
990 REM enable sur BIT 2
1000 REM envoi des donn‚es vers le synth‚tiseur
1010 REM envoi de R et P
1020 FOR X = 14 TO 1 STEP -1
1030 OUT DX, R(X) + 254 * INV
1040 OUT DX, R(X) + 2 + 250 * INV
1050 OUT DX, R(X) + 254 * INV
1060 NEXT X
1070 OUT DX, K
1080 REM envoi de l'impulsion de transfert
1090 GOTO 1140
1100 FOR X = 1 TO 10
1110 OUT DX, 4
1120 NEXT X
1130 OUT DX, K
1140 REM envoi de A et de N  A:7bits N:10bits
1150 FOR X = 17 TO 0 STEP -1
1160 OUT DX, N(X) + 254 * INV
1170 OUT DX, N(X) + 2 + 250 * INV
1180 OUT DX, N(X) + 254 * INV
1190 NEXT X
1200 OUT DX, K
1210 REM envoi de l'impulsion de transfert
1220 FOR X = 1 TO 10
1230 OUT DX, 4 + 247 * INV
1240 NEXT X
1250 OUT DX, K
1260 PRINT
1270 PRINT " Taper F pour une nouvelle frequence, T pour terminer, R pour recommencer"
1275 IF a$ = "s" OR a$ = "S" THEN 1316
1280 a$ = INKEY$
1290 IF a$ = "f" OR a$ = "F" THEN 1330
1300 IF a$ = "t" OR a$ = "T" THEN 1350
1310 IF a$ = "r" OR a$ = "R" THEN 50
1315 IF a$ = "s" OR a$ = "S" THEN
1316 FVCO = FVCO + 12.5
1317 IF FVCO MOD 10000 <> 0 THEN 450
1318 FOR i = 1 TO 100: NEXT i
1319 END IF
1320 GOTO 1280
1330 CLS
1340 GOTO 440
1350 END

Quelque chose comme ça

const char RegC = 0x63; //8 BITS
const char RegN = 0x05DC; //16 BITS
const char RegR = 0x0028; //24 BITS
int latchPin = 8; //Enb
int clockPin = 12; //Clk
int dataPin = 11; //Data

/*  sendReg
    Emission de la configuration d'un registre
    valeur : contient la valeur à placer dans le registre
    nb     : contient le nombre d'octets à envoyer
*/
void sendReg(unsigned long valeur, unsigned char nb){
    unsigned char tampon;
    unsigned char i=nb;
    do{
        tampon = (unsigned char)(valeur >> ((i-1)*8));
        shiftOut(dataPin, clockPin, MSBFIRST, tampon);
        i--;
    }while(i>0);
}

void setup(void){
  // faire ici les init des entrées-sorties
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  
  sendReg(RegC,1);
  sendReg(RegN,2);
  sendReg(RegR,3);
}

void loop(void){
  // là tu mets ce que tu veux
}

Bonjour,

pour les curieux

justement, :D c'est quoi comme TRX ?, j'observe un VFO pour la partie TX et un VFO pour le RX, riche !!! ]:D 73's de Jacques - F1APY

f1apy: Bonjour,

pour les curieux

justement, :D c'est quoi comme TRX ?, j'observe un VFO pour la partie TX et un VFO pour le RX, riche !!! ]:D 73's de Jacques - F1APY

Bonjour F1APY de memoire et sous toutes réserves : j'ai recupéré ça il y a déjà (tres/trop :grin: ) longtemps et mis à la cave suite à reforme d'un réseau de com urgences locales il me semble que c'etait des E/R LISA gérés à l'epoque par EGT (ça doit taper ~ dans le 450 Mhz) Il faudrait déjà d'abord que je retrouve le carton et que je l'ouvre dans ma province :grin: )

pourquoi ? ça t’intéresse si j'en exhume un ? (je dois en avoir une bonne dizaine, surement pas tous en forme 8) )

edit il semblerait que sa référence soit ATR2680 en tous ca c'est ça que j'ai recupéré http://f5fyu.free.fr/pageposte/modificationatr2680.htm

est il nécessaire d’inclure <SPI.h> ?
sa compile sans erreur, mais pas mieux niveau fonctionnement…

const char RegC = 0x63; //8 BITS
const char RegN = 0x05DC; //16 BITS
const char RegR = 0x0028; //24 BITS

int latchPin = 8; //Enb
int clockPin = 13; //Clk
int dataPin = 11; //Data

/*  sendReg
	Emission de la configuration d'un registre
	valeur : contient la valeur à placer dans le registre
	nb     : contient le nombre d'octets à envoyer
*/

void sendRegC(unsigned long RegC, unsigned char nb)
{
digitalWrite(latchPin, LOW);

	unsigned char tampon;
	unsigned char i=1;
	do
{
		tampon = (unsigned char)(RegC >> ((1-1)*8));
		shiftOut(dataPin, clockPin, MSBFIRST, tampon);
		i--;
	}
while(i>0);
}

void sendRegN(unsigned long RegN, unsigned char nb){
	unsigned char tampon;
	unsigned char i=2;
	do
{
		tampon = (unsigned char)(RegN >> ((2-1)*8));
		shiftOut(dataPin, clockPin, MSBFIRST, tampon);
		i--;
	}
while(i>0);
}

void sendRegR(unsigned long RegR, unsigned char nb){
	unsigned char tampon;
	unsigned char i=3;
	do
{
		tampon = (unsigned char)(RegR >> ((3-1)*8));
		shiftOut(dataPin, clockPin, MSBFIRST, tampon);
		i--;
	}
while(i>0);
digitalWrite(latchPin, HIGH);
}

void setup(void){
  // faire ici les init des entrées-sorties
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  
  sendRegC(RegC,1);
  sendRegN(RegN,2);
  sendRegR(RegR,3);
}

void loop(void)
{
  // là tu mets ce que tu veux
}

est il nécessaire d’inclure <SPI.h> ?

SPI.h est nécessaire pour le SPI matériel.
shiftOut() implémente un SPI logiciel.

La broche ENB doit faire un cycle pour chaque transfert

const char RegC = 0x63; //8 BITS
const char RegN = 0x05DC; //16 BITS
const char RegR = 0x0028; //24 BITS
int latchPin = 8; //Enb
int clockPin = 12; //Clk
int dataPin = 11; //Data

/*  sendReg
	Emission de la configuration d'un registre
	valeur : contient la valeur à placer dans le registre
	nb     : contient le nombre d'octets à envoyer
*/
void sendReg(unsigned long valeur, unsigned char nb){
	unsigned char tampon;
	unsigned char i=nb;

        digitalWrite(latchPin, LOW);
	do{
		tampon = (unsigned char)(valeur >> ((i-1)*8));
		shiftOut(dataPin, clockPin, MSBFIRST, tampon);
		i--;
	}while(i>0);
        digitalWrite(latchPin, HIGH);
}

void setup(void){
  // faire ici les init des entrées-sorties
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  
  sendReg(RegC,1);
  sendReg(RegN,2);
  sendReg(RegR,3);
}

void loop(void){
  // là tu mets ce que tu veux
}

Bonjour Artouste,

pourquoi ? ça t’intéresse si j'en exhume un ? (je dois en avoir une bonne dizaine, surement pas tous en forme smiley-cool )

Ce genre de TRX est intéressant pour faire des relais urbains (faible puissance sur 430 Mhz), je pensais aussi que ce genre de bête me disait quelque chose, je dois avoir le manuel technique qui traine quelque part au fond d'une armoire...(cadeau du frangin qui était directeur chez Alcatel Nord). Si tu les retrouves et que tu veux bien m'en céder 2, je suis intéressé, sous réserve d'un prix OM (à traiter par MP pour ne pas encombrer le forum). Cordialement, F1APY

mon filtre de boucle a l'air ok et sa verrouille que dal, j'ai un bout de code en C, qui tourne sur un PIC, je ferai un test avec, voir si cela ne vient pas d'autre chose.

merci de votre aide et bonne journée.

f1apy: Bonjour Artouste,

pourquoi ? ça t’intéresse si j'en exhume un ? (je dois en avoir une bonne dizaine, surement pas tous en forme smiley-cool )

Ce genre de TRX est intéressant pour faire des relais urbains (faible puissance sur 430 Mhz), je pensais aussi que ce genre de bête me disait quelque chose, je dois avoir le manuel technique qui traine quelque part au fond d'une armoire...(cadeau du frangin qui était directeur chez Alcatel Nord). Si tu les retrouves et que tu veux bien m'en céder 2, je suis intéressé, sous réserve d'un prix OM (à traiter par MP pour ne pas encombrer le forum). Cordialement, F1APY

bonjour F1APY ça te coutera juste les frais de port, les prix d'artouste sont imbattables :grin: par contre il te faudra attendre le moi de mai, je ne retourne pas dans ma province avant. je te recontacte sur ça après mon passage là bas

Re bonjour,

ça te coutera juste les frais de port, les prix d'artouste sont imbattables smiley-mr-green par contre il te faudra attendre le moi de mai, je ne retourne pas dans ma province avant.

Super et merci beaucoup, y a pas le feu et je peux attendre sans problèmes. Cordialement, Jacques - F1APY

Sinon, Artouste, f1apy ... vous avez quelques chose a ajouter concernant mon probleme?

merci a bientot

subsix:
Sinon, Artouste, f1apy … vous avez quelques chose a ajouter concernant mon probleme?

merci
a bientot

bonjour
Ton MC à déjà fonctionné avec une autre interface ?
ton circuit de test est cablé comment ?

voir avec le SPI si ce n’est pas un probleme d’inversion MSB <—> LSB (je me suis déjà fais qq prise de tete avec ça 8) )

pour test simple , je coderais en dur qq injections de data (excursion basse/haute) avec envoi sequencé toutes les 2/3 secondes (pour déjà voir si ça verouille un peu quelquefois ou jamais)

Artouste:

subsix:
Sinon, Artouste, f1apy … vous avez quelques chose a ajouter concernant mon probleme?

merci
a bientot

bonjour
Ton MC à déjà fonctionné avec une autre interface ?
ton circuit de test est cablé comment ?

voir avec le SPI si ce n’est pas un probleme d’inversion MSB <—> LSB (je me suis déjà fais qq prise de tete avec ça 8) )

pour test simple , je coderais en dur qq injections de data (excursion basse/haute) avec envoi sequencé toutes les 2/3 secondes (pour déjà voir si ça verouille un peu quelquefois ou jamais)

Mon CI est neuf, jamais tester ailleurs
mon câblage reprend celui du datasheet

quartz 4mhz + 2x 33pf + 1mohm
le VCO est un Zcomm , ref: V180MC01
le filtre de boucle est calculé pour 145mhz
le tout est alimenter via l’arduino, en 5v
sur le ld jai une led
je n’utilise que Enb, Clk, et Din
je n’utilise pas Dout

le tout est alimenté via l'arduino, en 5v

Tu as là une belle source de pollution. Tu pourrais commencer par séparer les alimentations et filtrer (HF) tous les signaux entre l'arduino et ton synthétiseur de fréquence.

quartz 4mhz + 2x 33pf + 1mohm

L'arduino a un quartz à 16MHz. Les fréquences sont des multiples entiers. Attention aux accrochages.

subsix: Mon CI est neuf, jamais tester ailleurs mon câblage reprend celui du datasheet

re ça ce n'est pas une config de test , mais une appli dans ton cas isole les excedents et part là dessus 5V arduino , d'instinct je n'aime pas du tout :grin:

le 4Mhz QZ déjà tu le detecte à l'oscillo ?

Sinon, Artouste, f1apy ... vous avez quelques chose a ajouter concernant mon probleme?

Tu as un oscillo à disposition ? si oui commence à regarder ce qui sort en boucle ouverte, tu devrais voir des crénaux en sortie sur PDout, ce qui veux déjà dire que le pb est extérieur à la commande surtout si tu fais varier la fréquence, si c'est pas le cas c'est que ton PLL ne comprends pas ce que tu lui envoies, à supposer que l'oscillateur de référence fonctionne correctement ce qui est encore à vérifier, bienvenue dans le monde de la RF XD Cordialement, Jacques - F1APY

merci de vos réponses, j'ai deja filtré a donf mes alim, 100nf/100uf/Vk200 ..

alors ce soir je testereai

des alims separé un quartz 16mhz (donc recalcul dufiltre de boucle) signaux de sortie sur PDOut

j'ai deja également vérifier mon quartz qui oscille bien a 4mhz