Red de conocimiento informático - Aprendizaje de programación - Código fuente de demodulación Ofdm

Código fuente de demodulación Ofdm

Tenga en cuenta que estos dos son caracteres entre comillas, que indican los parámetros SNR de la propia función de matlab, 'fsk', M, 1, 'coherent', esto significa que la estimación de la prueba de correlación debe resolver su d.

Manteniendo el canal estimado. Hay una curva de tasa de error de bits

Borrar todo;

Cerrar todo;

Fprintf( '\n simulación OFDM\ n \ n ');

-

Definición de parámetros

-

IFFT_bin_length = 1024

Recuento de portadores = 200;

Número de bits por símbolo = 2;

Símbolos por portadora = 50

Número de subportadoras 200

Números/símbolos 2

p>

Símbolos/portadora 50

Número de símbolos de entrenamiento 10

Longitud del prefijo cíclico T/4 (nota del autor) CP todo cero

Modo de modulación QDPSK

Porcentaje de canales multitrayecto 2, 3 y 4 (predeterminado)

Retraso máximo del canal 7 (símbolos de datos unitarios)

Condicional simulado transmitir y recibir Sincronización estricta entre

SNR = entrada ('SNR =' parámetros de relación señal-ruido de entrada

Relación señal-ruido = 3:14; rango de relación señal-ruido

BER = cero (1, longitud (SNR));

Longitud de salida de la banda base = recuento de portadoras * símbolo por portadora * bits por símbolo calcular el longitud de la secuencia binaria transmitida

carriers =(1: carrier _ count) (floor(IFFT _ bin _length/4)-floor(carrier _ count/2)); 156, 157-356

Conjugate_carrier = IFFT_bin_length-carrier2; coordenadas: 1024-(157:356) 2 = 1026-(157:356)=(869:670)

Construcción * * *matriz portadora de tiempo yugo, aplicando así el llamado RCC, reduciendo la complejidad computacional del algoritmo, es decir, el resultado después de ifft es un número real.

Defina la matriz portadora de tiempo conjugada

También puede utilizar la función flipdim para construir una matriz de yugo * * * simétrica.

-

Emisión de señal

-

out = rand(1, baseband_out_length);

baseband _ salida 1 = ronda(salida);

banda base _ salida 2 = piso(salida * 2

banda base _ salida 3 = techo(salida * 2)- 1;

baseband_out4 = randint(1, baseband _ out _ length);

Cuatro formas de generar la secuencia binaria a enviar, elija cualquiera para generar la secuencia binaria a enviar.

if(salida de banda base 1 == amplificador de salida de banda base baseband_out1 == baseband_out3)

fprintf('Se ha generado la secuencia de transmisión \ n \ n '); > baseband _ out = baseband _ out 1;

En caso contrario

fprintf('¡¡¡Compruebe el código!!!!!!!!!!!!!!!!!!!! ! ! ! \n\n');

Fin

Cuatro formas de generar una secuencia binaria enviada.

Baseband_out=round( rand(1, baseband_out_length));

convert_matrix = forma(baseband_out, bits_per_symbol, length(baseband_out) /bits_per_symbol);

Para k = 1 longitud (salida de banda base)/bits por símbolo),

modulo_baseband(k) = 0;

Para i = 1: bits por símbolo

módulo_baseband(k) = módulo_baseband(k) transform_matrix(I,k)*2^(bits_per_symbol-I

Fin

Fin

Convertir cada 2); bits en un número entero de 0 a 3.

Usa el modo "msb izquierdo".

-

Porcentaje de pruebas realizadas por lavabin

Una función incorporada que convierte directamente bits binarios a números decimales

-

p>

convert_matrix 1 = 0(longitud(baseband_out)/bits_per_symbol,bits_per_symbol);

convert_matrix 1 = convert_matrix ';

Prueba _ convert_ matriz 1 = bi2de(convertir _ matriz 1, bits_per_symbol, ' left-msb ');

Prueba _ convert _ matriz 2 = bi2de(convertir _ matriz 1, bits_per_symbol, 'right-msb');

Descripción de la función:

BI2DE convierte un vector binario en un número decimal.

D = BI2DE(B) convierte el vector binario B en un valor decimal D. Cuando B es una matriz, la transformación se realiza por filas y la salida D es un vector de columna de valores decimales. La orientación predeterminada para la entrada de archivos binarios

es derecha-MSB; el primer elemento en B representa el bit menos significativo.

if(modulo_baseband==Prueba_convert_matriz 1')

fprintf('modulo_baseband=Prueba_convert_matriz 1\n\n'); /p>

else if(módulo _ baseband = = Prueba _ convertir _ matriz 2')

fprintf(' módulo _ baseband = Prueba _ convertir _ matriz 2 \ n \ n '); /p>

De lo contrario

fprintf(' módulo _ baseband ~ = cualquier Prueba _ convert _ matriz \ n \ n ');

Fin

Fin

Obtenemos el resultado "modulo_baseband = Test_convert_matrix 1".

-

carrier_matrix = shape(modulo_baseband, carrier_count, simbolos_per_carrier)';

Generar matriz de portadoras de tiempo

-

Modulación QDPSK

-

carrier_matrix = [zeros(1, Carrier_count); Carrier_matrix]; agrega inicialización para la fase de modulación diferencial, que es 0.

Para i = símbolos por portadora 1)

carrier_matrix(i, = rem(carrier_matrix(i, carrier_matrix (i-1,, 2^bits_per_symbol)); Modulación diferencial

Fin

Carrier_matrix = carrier_matrix*((2*pi)/(2^bits_per_symbol)); generar fase diferencial

[X, Y]=pol2cart. carrier_matrix, ones(size(carrier_matrix, 1), size(carrier_matrix, 2)); desde coordenadas polares hasta coordenadas complejas, el primer parámetro es la fase y el segundo parámetro es la amplitud.

Carrier_matrix contiene todo información de fase y todas las amplitudes son iguales "1".

Complex_carrier_matrix=complex(X,Y);

Añadir secuencia de entrenamiento` 2

training _ símbolos =[1j j 1-1j j j 1j j 1j j 1j j 1j j 1j j 1j j 1j...

-j-j-1 1j j-1-j-1j-j-1j-1j-j-1j-1j-1j- 1j-1j- 1j-1j-j-1...

1j j 1-1-j-j-1j j 1j j 1j j 1j j 1j j 1-1j-j 1-j 1-j 1j 1j 1j 1j 1...

-1-j-j-1j j 1j j 1j-j-1j j 1-j-j-1j-j-1j-j-1j 1j j 1j 1j 1-j -1j-j -65438...

-1 1j j 1-j-j-1j j 1j j 1j-j-1j j j 1j j 1j j 1j 1j 25 veces " 1 j j 1 ", 25 veces "-1 - j -j -1 ", un total de 200 símbolos en una línea

training_symbols = cat(1, Training_symbols, Training_symbols);

training_symbols = cat(1, Training_symbols, Training_symbols) ; generar 4 filas de símbolos de entrenamiento

Complex_carrier_matrix = cat(1, Training_symbols, complex_carrier_matrix); fusionar secuencia de entrenamiento con datos

Símbolos piloto de tipo bloque

IFFT_modulation= cero (4 símbolos por portador, IFFT_bin_length);

Aquí, el vector de fila de ceros se encuentra entre los símbolos de entrenamiento y ¡Entre los símbolos de datos! ! !

4 símbolos de entrenamiento y 1 símbolo cero

Cada símbolo OFDM ocupa una fila de "modulación IFFT"

IFFT_modulation(:, portadora) = número complejo _carrier_matrix;

IFFT _modulation(:, conjugate_carrier) = conj(complex_carrier_matrix);

-

Probado por lavabin - índice de ceros encontrado

index_of_zeros = zeros(símbolos por operador, IFFT_bin_length-2 * recuento de operadores);

IFFT_modulation1 = zeros(4 símbolos_ 1 por operador, IFFT_bin_length);

IFFT_modulation2=zero (4 símbolos por portadora, IFFT_bin_length);

IFFT_modulation1( 6: símbolos_5 por portadora, = IFFT_modulation(6: símbolos_5 por portadora, = = 0;

Porcentaje de i = 1: símbolos por portadora

index_of_zeros (i, = buscar(IFFT_modulation1(i 5, = = 1);

Fin

-

Time_Wave_Matrix = IFFT( IFFT_modulation'); utilizado para operaciones IFFT

Matriz de onda de tiempo = matriz de onda de tiempo'; Si X es una matriz, ift devuelve la transformada de Fourier inversa de cada columna de la matriz.

Para i = 1: 4 símbolos por portadora 1

windowed_time_wave_matrix( i,) = real(time_wave_matrix( i,));

End

p>

Obtener la parte real del resultado IFFT

Este paso se puede omitir porque los resultados IFFT son todos números reales.

Se puede ver que solo se toman los puntos del operador después de IFFT, sin copiar CP ni agregar final.

OFDM_modulation = reshape(windowed_time_wave_matrix',1,IFFT_bin_length*(4 símbolos_1 por portadora));

Operación P2S

-

Porcentaje de pruebas realizadas por lavabin

Otra forma de conversión matricial

ofdm_modulation_tmp = windowed_time_waveform_matrix. ;

OFDM _ modulación _ prueba = OFDM _ modulación _ tmp(';

if (prueba de modulación ofdm == modulación ofdm)

fprintf(' OFDM _ modulación _ prueba = = OFDM _ modulación \ n \ n ');

En caso contrario

fprintf(' OFDM _ modulación _ prueba ~ = OFDM _ modulación \ n \ n ') ;

Fin

Obtenemos el resultado "OFDM_modulation_test == OFDM_modulation".

-

Tx_datos = ofdm_modulación

-

Simulación de canal

-

d 1 = 4; a 1 = 0,2; D2 = 5; a2 = 0,3D3 = 6; a3 = 0,4D4 = 7; a4 = 0,5 simulación de canal

copiar1 = cero ( Tx_data));

Para i = 1 d1: longitud(Tx_data)

copia 1(I)= a 1 * Tx_data(I-d 1);

Fin

copia2 = cero(tamaño(Tx_data));

Para i = 1 d2: longitud(Tx_data)

copia 2 (I)= a2 * Tx_data(I-D2);

Fin

copiar3 = cero(tamaño(Tx_data));

Para i = 1 d3: longitud (Tx_data )

copia 3(I)= a3 * Tx _ data(I-D3);

Fin

copia4 = cero(tamaño(Tx_data));

Para i = 1 d4: longitud(Tx_data)

copiar 4(I)= a4 * Tx_data(I-D4);

Fin

Tx_datos = Tx_datos copia 1 copia 2 copia 3 copia 4 multirutas

Tx_señal_potencia = var (Tx_data);

Para IDX = 1: Longitud (Relación señal-ruido) Simulación Monte Carlo

linear_SNR = 10^(Relación señal-ruido (idx)/10

ruido _σ= Tx _ señal _ potencia); /linear _ SNR;

Noise_scale_factor = sqrt(noise_sigma);

ruido = randn (1, longitud (Tx _ data)) * ruido _ escala _ factor

Rx_Data = Ruido Tx_data

-

Recepción de señal

-

Rx _ Data _ matriz = forma(Rx _ Datos, IFFT_bin_length, 4 símbolos _ por _ portadora 1);

Rx _ espectro = FFT(Rx _ Data _ matriz);

Asume una sincronización precisa entre Tx y Rx

Rx _ portadoras = Rx _ espectro(portadoras,)';

Rx _ entrenamiento _ símbolos = Rx_portadoras((1:4),:);

Rx_carrier = Rx_carriers((5:55),:);

-

Estimación de canal

-

Rx_training_symbols = Rx_training_symbols.

/símbolos_entrenamiento;

Rx_training_symbols_deno = Rx_training_symbols. ^2;

Rx_training_symbols_deno = Rx_training_symbols_deno(1, Rx_training_symbols_deno(2, Rx_training_symbols_deno(3, Rx_training_symbols_deno(4,);

Rx_training_symbols_nume = Rx_training_symbols(1,) ing_symbols(2,) Rx_training_symbols(3,) Rx_training_symbols(4,);

Rx_training_symbols_nume = conj(Rx_training_symbols_nume);

Tome los símbolos piloto de 4 vectores para una optimización promedio

Operación en el "vector de línea", es decir, un único símbolo OFDM

< El principio de p>: encontrar 1/H para realizar una compensación en el dominio de la frecuencia en los datos después de FFT

1/H = conj(H)/H^2 porque H^2 = H * conj(H)

Rx_training_symbols = Rx_training_symbols_nume /Rx_training_symbols_deno; Rx_training_symbols_nume.

/Rx_training_symbols_deno;

Rx_training_symbols_2 = cat(1, Rx_training_symbols, Rx_training_symbols);

Rx_training_symbols_ 4 = cat(1,Rx_training_symbols_2,Rx_training_symbols_2);

Rx_training_symbols _8 = gato (1,Rx_training_symbols_4,Rx_training_symbols_4);

Rx_training_symbols_16 = cat(1,Rx_training_symbols_8,Rx_training_symbols_8);

Rx_training_symbols_32 = cat(1,Rx_training_symbols_16,Rx_ bols_16);

Rx_training_symbols_48 = cat(1,Rx_training_symbols_32,Rx_training_symbols_16);

Rx_training_symbols_ 50 = cat(1,Rx_training_symbols_48,Rx_training_symbols_2);

Rx_training_symbols = cat(1,Rx_train ing_symbols_50,Rx_training_symbols);

Rx_carriers = Rx_training_symbols. * Los Rx_carriers se utilizan para la ecualización de un solo toque en el dominio de la frecuencia.

Rx_phase = ángulo(Rx_carriers)*(180/pi);

phase_negative = find(Rx_phase lt;0);

-Prueba usando "rem" -

Fase_Rx 1 = Fase_Rx;

Fase_Rx2 = Fase_Rx

Fase_Rx 1(fase_negativa)= rem(Fase_Rx 1(fase_negativa) 360, 360);

Rx_fase 2(fase_negativa)= Rx_fase 2(fase_negativa) 360;

si Rx_fase 2(fase_negativa)= = Rx_fase 1(fase_negativa)

fprintf('\nNo es necesario usar rem en la transición de fase negativa.\n n ')

De lo contrario

fprintf('\nNecesitamos usar rem en la transición de fase negativa .

\n ')

Fin

-

Rx _ fase(fase _ negativa)= rem(Rx _ fase(fase _ negativa) 360, 360) ;Convertir fase negativa en fase positiva

Rx _ decodificado _ fase = diff(Rx _ fase

Es por eso que la fase inicial se agrega delante.

"¡¡¡El vector fila de ceros aquí está entre los símbolos de entrenamiento y los símbolos de datos!!!"

phase _ negativo = find(Rx _ decode _ fase lt; 0);

Rx_decoded_phase(phase_negative)= rem(Rx_decoded_phase(phase_negative) 360, 360); Convierte la fase negativa en fase positiva nuevamente.

-

Demodulación QDPSK

-

base _ fase = 360 /2^bits_per_symbol

δ_phase; = base_phase/2;

Rx_decoded_symbols = zero(size(Rx_decoded_phase, 1), size(Rx_decoded_phase, 2));

Para I = 1: (2^ bits_per_symbol-1)

fase_centro = fase_base * I;

plus_delta = fase_centro fase_delta; umbral de decisión 1

menos_delta = fase central - fase_delta 2

decodificado = find((Rx _ decodificado _ fase lt; = plus _ delta) amp; (Rx _ decodificado _ fase gtMINUS _ delta));

Rx_decoded_symbols = I;

Fin

Solo se evaluaron tres áreas.

El área restante es espacio de fase cero.

Al definir la matriz de demodulación, esta área se ha definido como cero.

Rx_serial_symbols = reshape(Rx_decoded_symbols',1,size(Rx_decoded_symbols,1)* size(Rx_decoded_symbols,2));

para i = bits por símbolo: -1: 1

si i ~= 1

Rx_binary_matrix(i,) = rem(Rx_serial_symbols, 2);

Rx_serial_symbols = piso(Rx_serial_symbols/2);

Otro

Rx_binary_matrix(i,)= Rx_serial_symbols

Fin

Fin

Entero versus binario

baseband _ in = shape(Rx_binary_matrix, 1, size(Rx_binary_matrix, 1)* size(Rx_binary_matrix, 2));

-

Cálculo de la tasa de errores

-

bit _ errores(idx)= buscar( baseband _ in ~ = baseband _ out);

Cada elemento del resultado de la búsqueda es la etiqueta del vector de entrada que satisface la condición lógica, y su longitud vectorial también es un número diferente de bits enviados y recibidos.

bit_error_count(idx)= tamaño(bit_error,2);

total_bits = tamaño(baseband_output,2);

Tasa de error de bits = recuento de errores de bits/ número total de bits;

fprintf ( 'f \n ', bit _ error _ rate

[number_err(idx), BER(idx )] = biterr(baseband_out, baseband_in);

Fin

Semilog(SNR, BER, ' r * ');

Legend(' OFDM BER-SNR ');

xlabel(' SNR(dB)'); y label(' BER ');

Título("OFDM");

Se abre la cuadrícula;

-

Fin

-

1. Este programa realiza una estimación simple del canal LMS sin aumentar la comparación con otros algoritmos de estimación de canales, como MMSE;

2. La condición de simulación es que el sistema esté en un estado de sincronización ideal.