Demodulación de un dato

0

Comoseveenestaimagen,tengouncircuitoquehacreadoesospulsosdeseadosenlasalida.Hayunaúltimaetapaenmicircuitoyesoes:Traducirlostiemposenquehanpasadomáspulsosa"1", y los tiempos en que se han recibido menos pulsos a "0" (para ejemplos como se ve en la imagen). en otras palabras, necesito obtener la segunda señal en la imagen como salida (la latencia no es importante, pero el ancho es importante). Intenté pasar bajo filtrando la salida. Pero no me da una onda cuadrada. Pensé en contar los pulsos. (más de 5 pulsos en 50 nanosegundos se traducirían en "1"). Pero no sé si se puede hacer usando una vista de celda Verilog-A en Cadencia.

Actualización: Este es un receptor superregenerativo (SRR) que funciona principalmente con un oscilador que se enciende y se apaga periódicamente. cuando hay una señal de entrada, el oscilador se dispara antes que cuando no hay señal de entrada. Luego hay un detector de envolvente que rastrea el sobre y lo compara con un voltaje de referencia. luego, la salida del detector de envolvente se alimenta a un comparador que crea estos pulsos en la primera imagen. ahora necesito demodular estos pulsos estrechamente espaciados como valor alto y los espaciados ampliamente como valor bajo. No sé cómo hacerlo. :(

    
pregunta Fateme

3 respuestas

0

Hay un montón de soluciones, nombraré algunas y luego mostraré cuál usaré.

  • Una solución de hardware, a saber, un detector de envolvente pero con otro capacitor en la entrada. Así que terminas con un total de dos condensadores, ve el enlace e imagina un segundo condensador en la entrada. El capacitor en la entrada dejará pasar más potencia a medida que aumenta la frecuencia, lo que a su vez aumentará el voltaje en la salida. La salida puede simplemente leerse digitalmente y listo.
  • Utilice correlación cruzada , en otras palabras, simplemente multiplique los datos entrantes por una forma de onda esperada y la suma y el valor que reciba aumentará cuando se superponga, busque aquí para obtener más información.
  • Use FFT con una ventana deslizante de menos de 100 ns y simplemente busque en la bandeja de frecuencia la forma de onda que espera .
  • Use Algoritmo de Goertzel que es esencialmente una versión reducida de la FFT. Literalmente es solo un tono de la FFT mientras que la FFT recupera todas las frecuencias hasta la frecuencia de nyquist. Solo te interesan dos frecuencias, pero esto puede reducirse a una frecuencia porque hay una forma de onda A o una forma de onda B. No estás tratando con una tercera y una cuarta. Por lo tanto, solo necesita un filtro de Goertzel para recuperar un 1 o un 0. El algoritmo de Goertzel tiene que decaer, de lo contrario sumará y sobrecargará su FPGA.
  • Registre el valor del tiempo transcurrido entre los últimos flancos. En otras palabras, es solo un contador que se restablece en el flanco ascendente o descendente, lo que sea más fácil. Y simultáneamente en el reinicio pasa su valor a otro registro. Luego toma ese valor y pasa bajo. Este valor filtrado será muy fácil de trabajar.
  • O en lo que casi estabas. Cuente el número de bordes detectados en un tiempo dado. Y luego pase el número de conteo como el punto anterior y eventualmente obtenga la información.

La forma de onda de oscilación rápida parece ser 14 / (100 ns) = 140 MHz y la forma de onda de oscilación lenta parece ser 8 / (100 ns) = 80 MHz. Los FPGA normalmente se ejecutan a 50 MHz, lo que significa que la frecuencia de nyquist es de 25 MHz, lo que significa que sus señales tendrán un alias.

La última viñeta que mencioné, que es lo que estaba cerca, quizás funcionaría si usara el conteo asíncrono, porque entonces su reloj de 50 MHz no está relacionado con los eventos. Pero el conteo asíncrono también tiene un límite superior, revise su hoja de datos para su FPGA, podría llegar a 140 MHz, quién sabe. Yo no. Realmente no recomiendo esta solución porque su FPGA podría calentarse drásticamente porque está contando muy rápido.

Con una frecuencia de reloj de 50 MHz, el 140 Mhz se doblará a 140 mod 25 = 15 MHz y su 80 MHz se doblará a 80 mod 25 = 5 MHz debido a aliasing ( undersampling ). Esto significa que se puede implementar un algoritmo simple de Goertzel que solo mire a 15 MHz o 5 MHz. Elijo 15 MHz.

Aquí hay un pseudocódigo que implementaría un algoritmo de Goertzel deslizante que decae. La fase no es realmente 100% correcta porque no me importa. Nos preocupa la amplitud, la presencia de una onda, no la fase.

void setup(){
  Complex G = 0 
  //in my pseudo-code "Complex" is a datatype that means a+ib

  Re A = 0.5
  //This is for making a decaying Goertzel filter.
  //Re means Real
  //Im means Imaginary

  //The resulting amplification of a 140 Mhz(= 15 Mhz) sine wave
  //will be 1/(1-A) = 2. So if the amplitude is 8 
  //then the amplitude of G will be around 16, and squared around 256

  Complex W = A*e^(-i*2*pi*15/50) 
  = A(cos(-2*pi*15/50) + i*sin(-2*pi*15/50))
  = a+ib 
  ≃ -0.15 -0.47i
  //I hope you know how complex numbers works.

  bool X = 140/80 Mhz waveform
  //This is the 140/80 MHz waveform, one sample. 
  //You can multiply this value so it's large, 
  //like 8 or higher if you want higher resolution
  //it's effectively fixed point arithmetic. 
  //(a multiplication by 8 is the same as padding 3 LSB zeros)

  Re amplitude = 0
  //This will be proportional to the amplitude of 140 Mhz
  //waveform. So you will want to compare this variable to something
}

void loop(){//@always posedge (50 Mhz clock) or whatever it is
  G = X + G*W

  //Here's the same information but verbose
  //A = Re(X) + Re(G)Re(W) - Im(G)Im(W)
  //B = Im(X) + Re(G)Im(W) + Im(G)Re(W)
  //Re(G) = A
  //Im(G) = B

  amplitude = Re(G)*Re(G)+Im(G)*Im(G)
  //you could square root the amplitude if you want the actual length
  //but just "square" your value you are comparing and get rid of 
  //the square root. It's more efficient this way. 
  if (amplitude > 100){
    //We've detected a 1! 
    //since we didn't square root it, 
    //the amplitude of G is above sqrt(100) = 10. 
  }else{
    //If we haven't detected 140 Mhz 
    //then it must be 80 Mhz
    //then it must be a 0
    //We've detected a 0! 
  }
}

El pseudocódigo asume que sabes números complejos y lo que estás haciendo. Nunca he tratado con Verilog y, por lo tanto, no puedo producir nada cercano a él. Pero este pseudocódigo debería ser implementado fácilmente.

Si tuviera más conocimiento sobre el FPGA, tal vez lo resolvería con la solución de hardware porque entonces no hay relojes involucrados, pero esto significa que es posible que tenga que soldar una PCB, lo que puede ser problemático. Oh bien. Si algo se ve mal o no está claro, haga un comentario y actualizaré esta respuesta. O tal vez incluso eliminarlo.

    
respondido por el Harry Svensson
0

Piense en los pulsos ampliamente espaciados como si faltara un pulso.

El borde ascendente de la señal inferior sería donde no se detecte ningún impulso faltante. (marcado en rojo)

El flanco descendente sería cuando el pulso comience a fallar nuevamente. (marcado en amarillo)

La forma de onda resultante tendría un ciclo de trabajo de ~ 66%.

La línea azul es el punto medio entre las líneas rojas y su posición debería calcularse (si desea un ciclo de trabajo del 50%).

Si desea una forma de onda con un ciclo de trabajo del 50%, también podría tener el flanco descendente en el primer pulso después de un espacio amplio, y luego contar los pulsos para obtener el flanco ascendente. (forma de onda púrpura)

    
respondido por el jsotola
-1

Filtra tus pulsos para obtener un nivel de CC variable. Luego simplemente use la detección de nivel para producir sus máximos y mínimos.

    
respondido por el Norm

Lea otras preguntas en las etiquetas