└── Costas_Loop.m /Costas_Loop.m: -------------------------------------------------------------------------------- 1 | %===================================================% 2 | % ---Matlab Simulation--- % 3 | % -----Costas Loop----- % 4 | %===================================================% 5 | function Costas_Loop 6 | %% Parameters 7 | % LO = 10.0005MHz 8 | % RF = 10.0000MHz 9 | % K_VCO = 4000 10 | % Sample Rate = 1.00GHz 11 | % Sample Length = 10000 12 | Sp_Rate = 1e9; %Sample Rate 13 | Sp_Len = 1e4; %Sample Length 14 | Time = 0:1/Sp_Rate:(Sp_Len/Sp_Rate)-1/Sp_Rate; %Time Scale 15 | LO = 10.0005e6; %Local Oscillate Frequency 16 | RF = 10e6; %Radio Frequency 17 | K_VCO = 4e3; %Parameter for voltage-controlled oscillator 18 | Theta_Error = 0; %Voltage-controlled oscillator Theta Error 19 | %% Input Signal 20 | Message = 1.5+cos(2*pi*3e5.*Time) +... %Message Signal 21 | 0.5*cos(2*pi*2e5.*Time); 22 | Carrier = cos(2*pi*RF.*Time); %Carrier Signal 23 | DSB_SC = awgn(Message.*Carrier,35,'measured'); %35dB Gaussian White Noise 24 | %% Filter 25 | lowpass_Filt = designfilt('lowpassfir',... %Lowpass Filter 26 | 'PassbandFrequency',1e5, 'StopbandFrequency',5e6,... 27 | 'PassbandRipple',0.5,'StopbandAttenuation',45,... 28 | 'DesignMethod','kaiserwin','SampleRate',1e9); 29 | loop_Filt = [1 (1/200)*ones(1,200)]; %Loop Filter 30 | %% Initialize 31 | VLO_I = zeros(1,length(Time)); %VLO(Initial) 32 | VLO_Q = zeros(1,length(Time)); %VLO(Quadrature) 33 | VI = zeros(1,length(Time)); %Vout(Initial) 34 | VQ = zeros(1,length(Time)); %Vout(Quadrature) 35 | V_PD = zeros(1,length(Time)); %V Baseband Detector 36 | V_OP = zeros(1,length(Time)); %V Operation 37 | ThetaE_Rec = zeros(1,length(Time)); %Theta Error Record 38 | %% Loop 39 | disp('Costas Loop Processing...'); 40 | for Cnt = 1:length(Time) 41 | VLO_I(Cnt) = 2*cos(2*pi*(LO+Theta_Error)*Time(Cnt)); 42 | VLO_Q(Cnt) = 2*sin(2*pi*(LO+Theta_Error)*Time(Cnt)); 43 | VI(Cnt) = filter(lowpass_Filt,VLO_I(1:Cnt).*DSB_SC(1:Cnt))*[zeros(Cnt-1,1);1]; 44 | VQ(Cnt) = filter(lowpass_Filt,VLO_Q(1:Cnt).*DSB_SC(1:Cnt))*[zeros(Cnt-1,1);1]; 45 | V_PD(Cnt) = VI(Cnt)*VQ(Cnt); 46 | V_OP(Cnt) = filter(loop_Filt(2),loop_Filt(1),V_PD(1:Cnt))*[zeros(Cnt-1,1);1]; 47 | Theta_Error = Theta_Error - K_VCO*V_OP(Cnt); 48 | ThetaE_Rec(Cnt) = Theta_Error; 49 | end 50 | %% Graph 51 | Freq = (0:Sp_Len-1) .* (Sp_Rate/Sp_Len); %Frequency Domain 52 | figure('Color','white','Name','Costas Loop - InputSignal','NumberTitle','off'); 53 | plot(subplot(3,3,[1 2]),Message); Graph_Set(gca,[0 Sp_Len],[0 4],'Time/ns','Volt/V','Message Signal'); 54 | plot(subplot(3,3,[4 5]),DSB_SC); Graph_Set(gca,[0 Sp_Len],[-6 6],'Time/ns','Volt/V','DSB-SC Signal'); 55 | plot(subplot(3,3,[7 8]),Carrier); Graph_Set(gca,[0 Sp_Len],[-2 2],'Time/ns','Volt/V','Carrier Signal'); 56 | stem(subplot(3,3,3),Freq,abs(fft(Message)),'Marker','.'); Graph_Set(gca,[0 10e5],[0 2e4],'Freq/Hz','Magnitude','Message Signal'); 57 | stem(subplot(3,3,6),Freq,abs(fft(DSB_SC)),'Marker','.'); Graph_Set(gca,[9e6 11e6],[0 2e4],'Freq/Hz','Magnitude','DSB-SC Signal'); 58 | stem(subplot(3,3,9),Freq,abs(fft(Carrier)),'Marker','.'); Graph_Set(gca,[9e6 11e6],[0 2e4],'Freq/Hz','Magnitude','Carrier Signal'); 59 | figure('Color','white','Name','Costas Loop - Process','NumberTitle','off'); 60 | plot(subplot(2,2,1),VLO_I); Graph_Set(gca,[0 Sp_Len],[-3 3],'Time/ns','Volt/V','Local Oscillate Initial'); 61 | plot(subplot(2,2,3),VLO_Q); Graph_Set(gca,[0 Sp_Len],[-3 3],'Time/ns','Volt/V','Local Oscillate Quadrature'); 62 | plot(subplot(2,2,2),1:Sp_Len,VI,1:Sp_Len,Message); Graph_Set(gca,[0 Sp_Len],[0 4],'Time/ns','Volt/V','Output Initial Compared with Message'); 63 | plot(subplot(2,2,4),VQ); Graph_Set(gca,[0 Sp_Len],[-0.15 0.15],'Time/ns','Volt/V','Output Quadrature'); 64 | figure('Color','white','Name','Costas Loop - Process & Result','NumberTitle','off'); 65 | plot(subplot(2,6,[1 4]),V_PD); Graph_Set(gca,[0 Sp_Len],[-3e-2 3e-2],'Time/ns','Volt/V','Baseand Detector'); 66 | stem(subplot(2,6,[5 6]),Freq,abs(fft(V_OP)),'Marker','.'); Graph_Set(gca,[0 3e7],[0 0.3],'Freq/Hz','Magnitude','Baseand Detector'); 67 | plot(subplot(2,6,[7 10]),V_OP); Graph_Set(gca,[0 Sp_Len],[-2e-4 2e-4],'Time/ns','Volt/V','Operation Volt'); 68 | plot(subplot(2,6,[11 12]),1:Sp_Len,ThetaE_Rec,1:Sp_Len,ones(1,Sp_Len)*(RF-LO)); Graph_Set(gca,[0 Sp_Len],[-1e3 0],'Time/ns','Volt/V','Theta Error'); 69 | disp('Final Theta Error: '+string(ThetaE_Rec(end))); 70 | 71 | function Graph_Set(ax,XLim,YLim,Xlabel,Ylabel,Title) 72 | %% Graph Setting Helper 73 | ax.FontSize = 11; 74 | ax.Title.String = Title; 75 | ax.XLabel.String = Xlabel; 76 | ax.YLabel.String = Ylabel; 77 | ax.XLim = XLim; 78 | ax.YLim = YLim; 79 | ax.XGrid = 'on'; 80 | ax.YGrid = 'on'; 81 | ax.XMinorTick = 'on'; 82 | ax.YMinorTick = 'on'; 83 | --------------------------------------------------------------------------------