Entwicklung von Mehrkanal-SDR

Ich erzähle Ihnen von meinen Erfahrungen bei der Entwicklung eines digitalen Mehrkanal-Breitbandempfängers.

Seit vielen Jahren arbeite ich auf dem Gebiet der Schaffung von Mitteln zur Erfassung und Verarbeitung von Signalen von Navigationsradargeräten in der Luft und an der Küste. Vor ungefähr zwei Jahren veröffentlichte ich die neueste Version unseres RVAQ-Boards (Radar Video AcQuisition) und fragte mich, was ich als nächstes im Leben tun sollte. Ich wollte etwas Neues und Unbekanntes. Die Wahl fiel auf den Bereich, den ich noch nicht abgedeckt habe - Digitalradio mit einfachem Zugang zum Mikrowellenbereich.

Dies ist das erste Kapitel, das der anfänglichen Formulierung des Problems gewidmet ist.

Wo soll ich anfangen, wenn Sie noch nie beruflich mit digitalem Radioempfang beschäftigt waren, mit Ausnahme des in der Kindheit montierten Mishutka-Empfängers? Natürlich mit einer Erfrischung beim Lesen von Polyakov und dem Modell in MATLAB. Die ursprüngliche Idee war, einen Mehrkanalempfänger im Bereich von 156 bis 162 MHz zu schaffen, um alle aktiven Gespräche im UKW-Seeband zu überwachen und aufzuzeichnen. Ich werde die gewünschten Eigenschaften eines solchen Empfängers
auflisten : 1. Das Empfangsband beträgt mindestens 6 MHz (162-156 = 6).
2. Die Empfindlichkeit ist nicht schlechter als -110 dBm, sonst lachen sie.
3. Ein großer Dynamikbereich, denn wenn Sie 30 Meilen lang einem Schiff am Meer auf See lauschen, wird definitiv jemand mit seinen 25 Watt in der Nähe schreien. Bei anständigen Empfängern sollte der Blockierungspegel mindestens 70 dB betragen. Ich werde sagen, dass sich herausgestellt hat, dass mehr als 90 dB blockiert wurden. Kurz gesagt, RTL-SDR hat die Erwartungen stark nicht erfüllt. So seltsam es auch scheinen mag, ich begann mit der Wahl des ADC. Da es in der Natur keine entsprechenden (zumindest theoretischen) ADCs gibt, lohnt es sich nicht, diese zu nehmen. Ein solcher ADC wurde gefunden.

Jetzt müssen Sie die Architektur des Empfängers auswählen. Eine Überprüfung der relevanten Lösungen, die Untersuchung der Elementbasis und der Intuition ermöglichten es, sich mit dem Direktumwandlungsempfänger zu befassen. Es wurde auch beschlossen, den interessierenden Bereich des Spektrums unter Verwendung des Quadraturdemodulators auf eine Frequenz von Null zu übertragen und in der ersten Nyquist-Zone zu arbeiten, um die Nutzung aller Qualitäten des ausgewählten ADC zu maximieren.

Anfangsmodell für die Parameterschätzung
clear all;
k				= 1.381e-23;	% Joule/K 	- Boltzmann's Constant
T0				= 290;			% K			- temperature
% Encoding Windows-1251

% 1.     
% 1010          -       
% 1011          -    
% 1012          -     (/.)
% 1013          -      
% 1014          -      
% 1015          -    
% 1021, 1022    -     .
% 1031, 1032    -    
% 1041, 1042    -      
% 1051, 1052    -   

% 2.            

		Rrf_inp_ohm			= 50;		% Ohm	- 	 .

% 2011  -    
        BWrf_ekv_prf_hz   	= 20.0e6;   % Hz	-	    
        Lrf_max_prf_db      =  1.0;     % dB 	- 	        (insertion loss)
        
% 2012  -    
% (    Agilent MGA-71543    )
        Grf_lna_db     	    = 16.0;     % dB 	- 	   
        NFrf_lna_db         = 1.0;      % dB		- 	   
        
% 2013  -      
        BWrf_ekv_fms_hz   	=  6.0e6;   % Hz	-	     
        Lrf_max_fms_db      =  4.0;    % dB 	- 	         (insertion loss)
        
% 2014  -      
% (    Agilent MGA-71543    )
        Grf_amp_db      	=  16.0;    % dB 	- 	   
        NFrf_amp_db     	=  1.0;     % dB    - 	  
		
% 2015  -    
% (    Analog Devices ADL5387)
        Grf_mix_db      	=   4.5;    	% dB 	- 	    
        NFrf_mix_db     	=  15.0;    	% dB    - 	   
		IP1dBrf_mix_dbw		=  13.0 - 30.0; % dBW	- 	Input P1dB (IP1dB)

% 3.                
% 3011	-	
%    (db)
        NFrf_sys_db = pow2db( ( db2pow(  Lrf_max_prf_db )       ) + ...                   
                              ( db2pow( NFrf_lna_db     ) + 1 ) / ( db2pow( -Lrf_max_prf_db )) + ...
                              ( db2pow(  Lrf_max_fms_db ) + 1 ) / ( db2pow( -Lrf_max_prf_db ) * db2pow(  Grf_lna_db )) + ...
                              ( db2pow( NFrf_amp_db     ) + 1 ) / ( db2pow( -Lrf_max_prf_db ) * db2pow(  Grf_lna_db ) * db2pow( -Lrf_max_fms_db )) + ...
							  ( db2pow( NFrf_mix_db     ) + 1 ) / ( db2pow( -Lrf_max_prf_db ) * db2pow(  Grf_lna_db ) * db2pow( -Lrf_max_fms_db ) * db2pow(  Grf_amp_db )) ...
                            );

%    (dB)
		Grf_sys_db	= ( Grf_lna_db + Grf_amp_db + Grf_mix_db ) - ( Lrf_max_prf_db + Lrf_max_fms_db );
		
%      (Hz)
		BWrf_sys_hz = BWrf_ekv_fms_hz;

% 3012	-	Baseband LPF
		Lbb_lpf_db		= 9;		% dB			-	   Baseband LPF    (insertion loss)
		
% 3013	-	Baseband  (LTC6400-14)
		Gbb_opa_db		= 0;		% dB			-	  
		NFbb_opa_db     = 0;      % dB			-	  	

%    ,      (dB)
		Gbb_lfa_db		= Gbb_opa_db - Lbb_lpf_db;
		
%         (dB) -   . 
		NFbb_sys_db     = pow2db( ( db2pow( NFrf_sys_db         )     ) + ...                   
                                  ( db2pow( NFbb_opa_db         ) + 1 ) / ( db2pow( Grf_sys_db )) ...
					    		);
							
%         (dB)
		Gbb_sys_db	    = Grf_sys_db + Gbb_lfa_db; 

%       (Hz) -  
		BWbb_sys_hz		= BWrf_sys_hz;
		
%         (dBW)		
		PNbb_out_dbw	= pow2db( k * T0 * BWrf_sys_hz ) + NFbb_sys_db + Gbb_sys_db;	

% 3014	-	 
% (    1  Linear Technology LTC2271)
		FSadc_hz		= 20.0e6;	% Hz	-	Sampling rate		
		SNadc_fs_db		= 84;		% dB	-	SNR 
		NBadc_fs_bits	= 16;		% bits 	-	Full scale bits
		Vadc_fs_v		= 2;		% V		-	Full scale voltage
		Radc_inp_ohm	= 1000;		% Ohm	-	Input ADC resistance	

%            (dBW)			
		PFSadc_inp_dbw	= pow2db( 2.0 * (( Vadc_fs_v * 0.5 * sqrt( 0.5 )) ^ 2 ) / Radc_inp_ohm );  
		
%      (dBW)			
		PNadc_snr_dbw	= PFSadc_inp_dbw - SNadc_fs_db;
		
%      (dBW)
		PNadc_qan_dbw	= PFSadc_inp_dbw - ( NBadc_fs_bits * mag2db( 2 ) + mag2db( sqrt( 6 ) / 2 )); % adding correction factor for sinusoidal signal			
					
% 3015	-	     
        SNfm_min_db		= 12.0;		% dB  		-   -       
		BWfm_max_hz		= 25.0e3;	% Hz 		-    ,    		
		BWfm_min_hz		= 6.25e3;	% Hz 		-      ,    

%   (dBW)         (     )	
		Pfm_min_dbw		= pow2db( k * T0 * BWfm_max_hz ) + NFbb_sys_db + SNfm_min_db;		
		
%         ,      (dBW)
		Pfm_min_bb_sys_dbw 	= Pfm_min_dbw + Gbb_sys_db;		

%     .        
%        (dBW)
		PFSmix_inp_dbw = PFSadc_inp_dbw - Gbb_lfa_db - Grf_mix_db;		

%       ( )
		deltaPmix_inp_lin = IP1dBrf_mix_dbw - PFSmix_inp_dbw; 
		



Jetzt will ich Bilder
%       
Nfft = 2 * (( FSadc_hz / 2 ) / BWfm_min_hz ); 
Nsmp = Nfft;

tmp_fft_buf = zeros( 1, Nfft );
tmp_acc_buf = zeros( 1, Nfft );
tmp_smp_buf = zeros( 1, Nsmp );

max_acc = 30;

for acc = 1:max_acc
%   1 
%     -      
%    -       

  PS1 = db2pow( Pfm_min_bb_sys_dbw );
  WS1 = 25.0e3;
  FS1 =  1.0e6;
  
  Fstart = FS1;
  Fstop  = Fstart + WS1 - BWfm_min_hz;
  Pstep  = PS1 / ( WS1 / BWfm_min_hz ); 
  PS1_smp_buf = zeros( 1, Nsmp );
  
  for f = Fstart:BWfm_min_hz:Fstop
      phi_acc = 2.0 * pi * rand( 1 ); % random phase
      phi_stp =       pi * ( f / ( FSadc_hz / 2 ));
      
      for k = 1:Nsmp
          PS1_smp_buf( k ) = PS1_smp_buf( k ) + sqrt( Pstep ) * exp( j * phi_acc );
          phi_acc = phi_acc + phi_stp;
          
          if( phi_acc > (  2.0 * pi ))
              phi_acc = phi_acc - 2.0 * pi;
          else
              if( phi_acc < ( -2.0 * pi ))
                  phi_acc = phi_acc + 2.0 * pi;
              end
          end
      end
  end

%   2 
%     -       
%    -       

  PS2 = db2pow( PFSadc_inp_dbw - 1.0 ); % -1 dB back off 
  WS2 = 25.0e3;
  FS2 = -2.0e6;
  
  Fstart = FS2;
  Fstop  = Fstart + WS2 - BWfm_min_hz;
  Pstep  = PS2; 
  PS2_smp_buf = zeros( 1, Nsmp );
  
  for f = Fstart:BWfm_min_hz:Fstop
      phi_acc = 2.0 * pi * rand( 1 ); % random phase
      phi_stp =       pi * ( f / ( FSadc_hz / 2 ));
      
      for k = 1:Nsmp
          PS2_smp_buf( k ) = PS2_smp_buf( k ) + sqrt( Pstep ) * exp( j * phi_acc );
          phi_acc = phi_acc + phi_stp;
          
          if( phi_acc > (  2.0 * pi ))
              phi_acc = phi_acc - 2.0 * pi;
          else
              if( phi_acc < ( -2.0 * pi ))
                  phi_acc = phi_acc + 2.0 * pi;
              end
          end
      end
  end

%      
  PN1 = db2pow( PNbb_out_dbw );
  WN1 = BWbb_sys_hz;
  
  Pfull_bw = PN1 * ( FSadc_hz / WN1 );
  
  PN1_smp_buf = sqrt( 0.5 * Pfull_bw ) * complex( randn( 1, Nsmp ), randn( 1, Nsmp ));
  tmp_fft_buf = fftshift( fft( PN1_smp_buf ));
  tmp_msk_buf = zeros( 1, Nfft );
  tmp_msk_buf((( Nfft / 2 ) - (( WN1 / FSadc_hz ) * ( Nfft / 2 )) + 1 ) : (( Nfft / 2 ) + (( WN1 / FSadc_hz ) * ( Nfft / 2 )))) = ... 
              ones( 1, (( WN1 / FSadc_hz ) * Nfft ));
  
  tmp_fft_buf = tmp_fft_buf .* tmp_msk_buf;
  PN1_smp_buf = ifft( fftshift( tmp_fft_buf ));

%    
  PN2 = db2pow( PNadc_snr_dbw ) - db2pow( PNadc_qan_dbw );
  %PN2 = db2pow( PNadc_snr_dbw );
  
  Pfull_bw = PN2;
  
  PN2_smp_buf = sqrt( 0.5 * Pfull_bw ) * complex( randn( 1, Nsmp ), randn( 1, Nsmp ));

%    
  QAN_smp_buf = PS1_smp_buf + PS2_smp_buf + PN1_smp_buf + PN2_smp_buf;
  
  QAN_delta = Vadc_fs_v / ( 2 ^ NBadc_fs_bits );
  
  QAN_smp_buf = round( QAN_smp_buf ./ QAN_delta ) .* QAN_delta;
  
  QAN_smp_buf_re = real( QAN_smp_buf );
  QAN_smp_buf_re( find( QAN_smp_buf_re > (  Vadc_fs_v / 2.0 ))) =  Vadc_fs_v / 2.0;
  QAN_smp_buf_re( find( QAN_smp_buf_re < ( -Vadc_fs_v / 2.0 ))) = -Vadc_fs_v / 2.0;
  
  QAN_smp_buf_im = imag( QAN_smp_buf );
  QAN_smp_buf_im( find( QAN_smp_buf_im > (  Vadc_fs_v / 2.0 ))) =  Vadc_fs_v / 2.0;
  QAN_smp_buf_im( find( QAN_smp_buf_im < ( -Vadc_fs_v / 2.0 ))) = -Vadc_fs_v / 2.0;
  
  QAN_smp_buf = complex( QAN_smp_buf_re, QAN_smp_buf_im );

%   ADC

  tmp_smp_buf = QAN_smp_buf;
  %tmp_smp_buf = PS1_smp_buf + PS2_smp_buf + PN1_smp_buf + PN2_smp_buf;
  
  tmp_fft_buf = fft( tmp_smp_buf ) / Nfft;
  tmp_acc_buf = tmp_acc_buf + ( tmp_fft_buf .* conj( tmp_fft_buf ));
end  

tmp_acc_buf = tmp_acc_buf ./ max_acc;

f = linspace(( -FSadc_hz / 2 ) + BWfm_min_hz, FSadc_hz / 2, Nfft );

plot( f, pow2db( fftshift( tmp_acc_buf ))); 
xlim( [( -FSadc_hz / 2 ), ( FSadc_hz / 2 )] ); 
ylim( [-150.0, -20.0] ); 
title('Power Spectrum')
xlabel('Frequency (Hz)')
ylabel('P(f) dBW')
drawnow;



Nun, das Modell zeigte die Realisierbarkeit der Idee - Empfindlichkeit -115 dBm, Blockierung unter 90 dB.

Ferner entfernen wir im FPGA unter Verwendung des Normalisierungsblocks von Quadratursignalen die konstante Komponente, bewältigen den Spiegelkanal und legen ein Signal an den DDC- Eingang an . Nach Driftinteressierenden Frequenz auf Null, wird das Signal an eine Kette von digitalen CIC - und FIR -filter Kanalzug bildet. Wenn wir gleichzeitig mehr als einen Kanal empfangen möchten, müssen wir natürlich eine Reihe von DDC und Filtern haben.

Wenn die Öffentlichkeit interessiert sein wird, werde ich im nächsten Artikel über die nächsten Schritte bei der Modellierung und die Bewertung der FPGA-Hardwareressourcen sprechen.

Source: https://habr.com/ru/post/de395853/


All Articles