Jitter del pin UART TX

Estoy desarrollando un pequeño robot usando la placa Discovery STM32L152C. Actualmente estoy tratando de configurar la placa usando el STM32CubeMX. Nunca trabajé en este nivel tan bajo (mi experiencia es mucho más sobre algoritmos), por lo tanto, comencé a hacer cosas simples, como enviar algunos caracteres al puerto UART. La placa no tiene un oscilador externo. Por lo tanto, estoy usando el oscilador RC interno.

Después de hacer esto, escribí un software muy fácil que envía continuamente un carácter al puerto UART:

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART2_UART_Init();
    unsigned char msg = '@';

    while (1)
    {
        HAL_UART_Transmit(&huart2,&msg,1,1);
    }
}

Usando un osciloscopio de 100 MHz, esto es lo que obtengo del pin:

deriva en serie

El carácter que estoy enviando es claramente visible, pero parece que la salida es algo así como inestable. He presionado el botón AUTO del visor muchas veces, pero nada cambia.

Pensé que tal vez podría ser un problema con el oscilador RC. Después de configurar la frecuencia del reloj a 4.194 MHz (la máxima) con el configurador STM32, he medido el reloj pero la salida no es la esperada.

Esto es lo que obtengo:

Medición de reloj con osciloscopio

Primero he notado que la onda no es tan "cuadrada", y además la frecuencia es ligeramente diferente: 4.202 MHz en lugar de 4.194 MHz.

Me gustaría entender mejor por qué obtengo este resultado.

En cuanto a la forma, dado que el osciloscopio es de 100 MHz y el reloj tiene una frecuencia de ~4 MHz, supongo que la herramienta de medición no es el problema. En cuanto a la frecuencia, diría que el problema está en la precisión del propio oscilador RC. ¿Estos pueden ser la causa del problema que tengo en el UART?

Su reloj se ve bien para esta aplicación. ¿Has probado un solo disparo en la salida UART? Parece que se superponen varias transmisiones.
Puede que no haya ningún problema en absoluto. Los UART son de carácter asíncrono. ¿El bucle invertido (TX conectado a RX) le da problemas con caracteres incorrectos?
Acepto que no se muestran problemas. 10% de error de reloj frente a la tasa de baudios, recuerdo que es un límite para el centro de 10 bits muestreado incluido. start/stop Jitter es solo la latencia en la duración inactiva. El problema es el ajuste del retardo del disparador. sobre el alcance
Agregue algo de tiempo de inactividad entre caracteres y algo de tiempo de espera en su alcance, o active la decodificación en serie si está disponible
esto es por diseño, solo necesita estar lo suficientemente cerca para que el otro lado trabaje a través de un carácter, por lo que su error de fluctuación y/o velocidad del reloj puede ser relativamente grande. Esta es una interfaz asíncrona, por lo que, por diseño, no se espera que los dos lados usen el mismo reloj, por lo tanto, bits de inicio y bits de parada para asegurar los bordes que se pueden usar para encontrar las celdas de bits en el siguiente carácter.
Por cierto, 8N1, el carácter 0x55 ('U') hace una onda cuadrada...

Respuestas (2)

Entonces, hay algunas respuestas aquí, comenzaré desde la más fácil de explicar de manera simple (al menos para mí) hasta las respuestas más confusas.

Primero, la forma de onda que publicó no está "cuadrada" debido a un par de factores, a saber, efectos electrónicos parásitos que afectan el pin que está probando, como capacitancia, conexión a tierra incorrecta de su alcance, resistencia en serie en el rastro, inductancia parásita y similares. Básicamente, todos estos efectos parásitos limitan la rapidez con la que el pin puede cambiar de estado. Una verdadera onda cuadrada es imposible en la práctica, ya que requeriría que un circuito cambie de estado instantáneamente (si ese fuera el caso, nuestras computadoras estarían funcionando MUCHO más rápido de lo que lo hacen). También hay un "gotchya" adicional con los microcontroladores STM32 y otros en los que se puede cambiar la fuerza de la unidad de salida. Es decir, puede, en firmware, dicte cuánta corriente está empujando por el pin hacia el resto del circuito, por lo tanto, cambia la velocidad a la que puede cambiar de estado. El código que publicó no muestra ninguna mención de esto, por lo que lo más probable es que el micro esté funcionando a los 20 MHz predeterminados, que es compatible con la captura de pantalla de su alcance (tiempo de subida de ~ 50 ns).

En segundo lugar, tiene razón al suponer que la discrepancia en la frecuencia de salida se debe al oscilador RC interno. ingrese la descripción de la imagen aquíEn la hoja de datos de STM32L152C, página 75, puede ver que el control remoto interno muestra una precisión en el peor de los casos de -4 % a +3 % en todo el rango de temperatura de funcionamiento y +/- 1 % a temperatura ambiente. Entonces (4.202 - 4.194) / 4.194 * 100 = 0.19% de diferencia, que está dentro de las especificaciones.

Por último, lo más probable es que el jitter se deba a las bibliotecas HAL de piss-porr (sé que no es una gran explicación, pero me he encontrado con tantos problemas con este b/s desde que dejaron de admitir la biblioteca SPL que hemos estado escribiendo nuestro propio HAL interno para los distintos STM32). Si observa el código HAL, la mayoría de las veces están pasando estructuras de datos gigantescas e infladas que representan el código HAL configurado automáticamente con cada llamada de función. Lo que normalmente se podría hacer enviando 4 bytes al registro apropiado (algunos, si no 1 ciclo de CPU) se compila en muchas, muchas MUCHAS líneas de ensamblaje. Combine eso con algunos ISR pateándolo aquí y allá, va a haber algo de nerviosismo. El cuello de botella principal aquí es el tiempo que tarda el procesador en captar las siguientes instrucciones de la memoria flash, en realidad, es un proceso complicado cuando el procesador está haciendo cosas con búsquedas de instrucciones canalizadas. Puede leer el Manual del procesadoraquí Sección 3. Intentaría cargar su programa en la placa de desarrollo para ejecutarlo desde la RAM y ver si el problema desaparece, si no es así, entonces estoy siendo un idiota y me estoy perdiendo algo simple. Pero mi recomendación sería deshacerse de las bibliotecas HAL si puede, desafortunadamente ST no ha publicado su SPL para las series de piezas L1 y L4, por lo que es posible que tenga que investigar un poco.

Finalmente... :) ¿Es esto siquiera un problema? ¿Puede su computadora recibir los caracteres correctamente o puede decodificarlos con su alcance?

¿Ves dónde está el punto de activación del trazo del osciloscopio? Está en medio de la pista. El jitter está antes del disparador y ocurre entre un carácter y el siguiente. Esto no afectará a la recepción del carácter, ya que la comunicación asincrónica no asume ninguna temporización de carácter a carácter.

Si cambia la configuración de su alcance para que el gatillo esté en el lado izquierdo y pueda ver dos caracteres, será más obvio lo que está sucediendo.

¿Tiene alguna rutina de servicio de interrupción de temporizador en ejecución? Por ejemplo, en la función "SystemClock_Config ()", ¿habilita un temporizador periódico?

Si es así, hay un ISR que periódicamente le roba tiempo a main() y hace que la demora entre los caracteres varíe.