Bonjour à tous.
J'essaie de configurer une PLL du deuxième ordre sur MATLAB. Pour la faire courte, je génère un flux binaire de 1000 bits que je module en PCM/FM, et j'utilise ensuite l'algorithme Mid/End pour détecter les bits et reconstituer le signal d'origine. Chaque bit est échantillonné N_SR fois, ce qui me donne une trame de 1000*N_SR échantillons (un symbole fait donc N_SR bits).
Mon problème est le suivant : je cherche à trouver à une formule qui permette au gain proportionnel Kp et au gain intégral Ki de la PLL de s'ajuster aux paramètres du code, notamment le débit et la fréquence d'échantillonnage (fe).
La partie de la modulation PCM/FM ne pose pas de problème, mais celle juste en dessous, oui. Je voudrais un amortissement de ksi = 0.7 pour un wn fixé à debit*1e-3. J'ai les formules théoriques de Kp et Ki (voir image), mais je n'arrive pas à trouver comment les ajuster pour toutes les situations de mon code. J'ai donc essayé de rajouter le débit pour que les courbes correspondent à l'amortissement attendu, mais quand je change le débit ou la fréquence d'échantillonnage, il ne correspond plus à ce qui est attendu. Il est possible que le problème vienne du gain général K à qui il manquerait une valeur à rajouter, mais je ne vois pas laquelle ni sur quelle piste partir pour chercher. Je vous joins également un schéma de la PLL.
Merci d'avance à tous ceux qui essaieront de m'aider !
Voici le code commenté :
P.S.: sur l'image des formules, Kd = K dans mon code. J'espère que ça ne vous embrouillera pas trop.Code:% Paramètres initiaux debit = 2e6; % Débit symbole (symb/s) fe = 50e6; % Fréquence d'échantillonnage (Hz) N_SR = fe / debit; % Nombre d'échantillons par symbole nb_bits = 10000; % Nombre de bits à transmettre Tb = 1/debit; % Durée d'un symbole Ts = 1/fe; % Période d'échantillonnage % Modulation PCM/FM ======================================== % Génération du bitstream NRZ bitstream = 2 * randi([0 1], 1, nb_bits) - 1; % Suite binaire NRZ (+1/-1) nrz = kron(bitstream, ones(1, N_SR)); % Suréchantillonnage NRZ % Filtre de mise en forme (cosinus sur un symbole) h = 0.7; L = 1; v = 0:(L*N_SR - 1); g = (1 / (2 * L * N_SR)) * (1 - cos(2 * pi * v / (L * N_SR))); % Filtrage du NRZ s_filtree = conv(nrz, g); % Modulation de phase (CPM) phi = 2 * pi * h * cumsum(s_filtree) / N_SR; S_ideal = exp(1i * phi); % Signal complexe idéal modulé en phase phi_ideal = unwrap(angle(S_ideal));% Phase non-ambiguë (pour éviter les sauts de 2pi) S = exp(1i * phi_ideal); % Recalcule le signal complexe % Offset de phase (pour simuler un décalage de la porteuse) phi_offset = pi/8; S = S * exp(1i * phi_offset); % Fin de la modulation PCM/FM ==================================== % Paramètres de la boucle de synchronisation de symboles ksi = 0.7; % Facteur d'amortissement cible wn = debit*1e-3; % Pulsation propre de la boucle K = sum(g); % Gain global de la chaîne (filtre de mise en forme) Kd = Ts/K; % Gain du comparateur (phase detector) Knco = K/Kd; % Gain du NCO (oscillateur numérique) % Réglage des coefficients du correcteur PI (discret). Au secours Kp = (ksi*wn) / (K*debit); % Gain proportionnel Ki = (wn)^2*Ts / (K*debit); % Gain intégral (inclut Ts pour le discret) incr = 1/(N_SR); % Valeur initiale du NCO % Variables pour la synchronisation de symboles alpha = 0; % Phase du NCO pour détecter le timing symbole Aq_mid = 0; Aq_end = 0; % Accumulateurs pour la détection Mid/End alpha_prec = 0; % Phase précédente du NCO top_symb = 0; % Indicateur de détection de symbole S_end = 0; S_mid = 0; % Valeurs stockées pour la détection S_end_prec = 0; S_mid_prec = 0; k = 1; % Compteur de symboles err_ph = 0; % Erreur de phase estimée sum_err_ph = 0; % Somme cumulée des erreurs de phase (pour l'intégrale) nco_sync = zeros(1, length(s_filtree)-1); % Trace de la synchronisation NCO % Boucle principale sur les échantillons for n = 1:length(s_filtree)-1 alpha = alpha + incr; % Avance la phase du NCO top_symb = 0; % Détection du "milieu" du symbole (Mid) if alpha >= 0.5 && alpha_prec < 0.5 S_mid_prec = S_mid; S_mid = Aq_mid; Aq_mid = s_filtree(n); else Aq_mid = Aq_mid + s_filtree(n); end % Détection de la "fin" du symbole (End) if alpha >= 1.0 alpha = mod(alpha,1.0); % Remise à zéro de la phase du NCO S_end_prec = S_end; S_end = Aq_end; Aq_end = s_filtree(n); top_symb = 1; % Indique qu'un symbole a été détecté k = k+1; else Aq_end = Aq_end + s_filtree(n); end % Calcul de l'erreur de phase à chaque détection de symbole if top_symb == 1 nco_sync(n) = 1; % Marque la synchro pour suivi % Détection de transition de signe (zéro-crossing) if (S_end_prec >0 && S_end <=0) err_ph(k) = S_mid/N_SR; % Calcul de l'erreur de phase elseif (S_end_prec <= 0 && S_end > 0 ) err_ph(k) = -S_mid/N_SR; % Calcul de l'erreur de phase else err_ph(k) = err_ph(k-1); % Pas de transition détectée end sum_err_ph = sum_err_ph + err_ph(k); % Intégrale de l'erreur incr = incr0 - Kp*err_ph(k) - Ki*sum_err_ph; % Correction du NCO (PI) end alpha_prec = alpha; % Mise à jour de la phase précédente end % Evolution de l’erreur de phase estimée par la PLL au cours du temps (en microsecondes) figure; plot((0:length(err_ph)-1)*Tb/1e-6,err_ph); title('PLL erreur de fréquence (bitsync - nco)'); xlabel('Temps (us)'); ylabel('Erreur de phase'); grid on;
-----