¿Cómo generar un reloj de alta frecuencia con alta estabilidad desde un microcontrolador?

Estoy usando el microcontrolador TivaC launchpad TM4C123G, para generar un reloj de 40 MHz, pero lo probé en el osciloscopio y no parece una onda cuadrada, es más como una sinusoidal aquí hay una captura de pantalla:

ingrese la descripción de la imagen aquí

y aquí está mi código:

#include <lm4f120h5qr.h>
#include <stdbool.h>
#include <stdint.h>
#include "driverlib/sysctl.c"
#include "driverlib/pin_map.h"

void SYS_CLOCK(){  SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ); }   
// Microcontroller Frequency 80MHZ

 void CLK1_SETUP(unsigned long Period){
 SYSCTL->RCGCWTIMER |= (0x1<<0);
 WTIMER0->CTL &= ~(1<<8);
 WTIMER0->CFG = 0x00000004;
 WTIMER0->TBMR |= (0xA<<0);
 WTIMER0->TBILR = Period;
 WTIMER0->TBMATCHR =Period/2;
 WTIMER0->CTL |= (1<<8);

 SYSCTL->RCGCGPIO |= (1<<2);
 GPIOC->DIR |= (0x1<<5); 
 GPIOC->DEN |= (0x1<<5);
 GPIOC->PUR |= (0x1<<5); 
 GPIOC->AFSEL |= (0x1<<5);
 GPIOC->AMSEL &= ~(0x1<<5);
 GPIOC->PCTL |= 0X00700000;
 }

 void CLK2_SETUP(unsigned long Period){
 SYSCTL->RCGCWTIMER |= (0x1<<1);
 WTIMER1->CTL &= ~(1<<8);
 WTIMER1->CFG = 0x00000004;
 WTIMER1->TBMR |= (0xA<<0);
 WTIMER1->TBILR = Period;
 WTIMER1->TBMATCHR =Period/2;
 WTIMER1->CTL |= (1<<8);

 GPIOC->DIR |= (0x1<<7); 
 GPIOC->DEN |= (0x1<<7);
 GPIOC->PUR |= (0x1<<7); 
 GPIOC->AFSEL |= (0x1<<7);
 GPIOC->AMSEL &= ~(0x1<<7);
 GPIOC->PCTL |= 0X70000000;
 }

 void main()
 {
 SYS_CLOCK();
 CLK1_SETUP(2); //40MHZ~25nsec~2
 CLK2_SETUP(190);//421KHZ~2.375usec~190
 ADC_SETUP(); 
 }

por otro lado genere otro reloj con el mismo código pero con una frecuencia de 421 KHZ y se ve correcto:

ingrese la descripción de la imagen aquí

¿Alguna sugerencia sobre cómo hacer que los 40 MHz sean más estables y precisos?

Compensa tu sonda y usa un cable de tierra más corto para empezar.
Una terminación adecuada también ayudará.

Respuestas (2)

Sus pines GPIO no pueden cambiar entre señal baja y alta lo suficientemente rápido.

A 40 Mhz, el período de un solo ciclo es de 25 ns. Aquí está la definición de la velocidad de giro de los pines GPIO del documento http://www.ti.com/lit/ds/spms376e/spms376e.pdf :

ingrese la descripción de la imagen aquí

Para un solo ciclo, necesita un borde de subida y uno de bajada.

Como se ve en el gráfico anterior, en el mejor de los casos, sumará hasta 16,7 ns (unidad de 8 mA con el control de velocidad de respuesta deshabilitado). Entonces, en este caso, sus pines pasarán la mayor parte del tiempo cambiando la señal hacia arriba o hacia abajo. Y eso es más o menos lo que estamos viendo en la imagen de su osciloscopio también.

Entonces, según tengo entendido, ¿esto es lo mejor que puede hacer mi microcontrolador y no hay solución para este problema?
si realmente necesita que la salida sea una onda cuadrada, puede colocar un comparador realmente rápido en la salida para dar forma al pulso de nuevo a una onda cuadrada. Por otro lado, ¿por qué necesita que la señal sea una onda cuadrada en primer lugar? Si desea registrar algo, es posible que funcione bien con la señal distorsionada.
@AbdelrahmanTarief Oh, una forma alternativa de obtener su señal sería generar el reloj usando un PLL como el Si5351 controlado a través de I²C. Por ejemplo, el Si5351 sube a 200 MHz y tiene una velocidad de respuesta de 1,5 ns en el peor de los casos. Ni siquiera es caro.
Genere una frecuencia más lenta y multiplíquela con un PLL externo, o use algún tipo de oscilador de cristal que no tenga nada que ver con el microcontrolador, y actívelo si es necesario.

Primero baje la frecuencia a 10 MHz para ayudar a ver qué está pasando. Verá una parte plana entre el pico del borde ascendente y el borde descendente.

Luego mejore la sonda del osciloscopio, por compensación (efecto muy pequeño en estas frecuencias; la segunda imagen muestra una sonda bien compensada) y puesta a tierra mejorada (puede marcar una gran diferencia...)

Luego intente la terminación en serie (S-term). Una resistencia de 27 a 100 ohmios (comience con 56) puede cuadrar bien el borde de ataque; si es demasiado alta, se redondeará. El término S debe estar lo más cerca posible del pin de E/S, pero espero que conectarlo al pin del Launchpad sea lo suficientemente bueno. También puede experimentar con las diferentes potencias de la unidad y el control de la velocidad de giro; la mejor solución dependerá del cableado externo, pero una terminación S es una adición útil para algunas señales rápidas.

Finalmente, restaure el reloj a 40 MHz y vea la mejora. (Puede valer la pena agregar más imágenes a la pregunta).