El modo externo de temporización STM32cubemx mide la frecuencia por encima de 10M

El modo externo de temporización STM32cubemx mide la frecuencia por encima de 10M

Este artículo explica cómo usar la función de reloj externo del temporizador para medir hábilmente la frecuencia de las señales externas de alta frecuencia. El rango puede ser tan alto como 30M o más.

Herramientas necesarias:

  • Placa de desarrollo: STM32F103RCT6
  • STM32CubeMX
  • IDE: Keil-MDK

Explicación del principio

reloj temporizador

Cuando usamos el temporizador TIM normalmente, en el árbol del reloj en cubemx, simplemente haga clic en la configuración para seleccionar el reloj del temporizador. Por ejemplo, la siguiente situación:

imagen

A través del árbol de relojes, se proporciona un reloj de 72M al temporizador colgado en el reloj APB2. Cómo se genera el reloj internamente, no es necesario que nos preocupemos aquí, está fuera del alcance de este artículo, siempre que sepamos que hay una entrada de reloj de 72M para el temporizador TIM como fuente de reloj.

Para decirlo de manera más vívida, se le da al temporizador una entrada PWM de 72M, ciclo de trabajo del 50%, nivel alto de 3.3V y nivel bajo de 0V. Siempre que el temporizador detecte el flanco ascendente de PWM, agregará uno en el registro de valor de conteo CNT.

A continuación ilustramos que hay un reloj interno de 1k de entrada al temporizador. Como se muestra abajo

imagen-20230603165825032

Cuando el TIM detecta el flanco ascendente del reloj, el registro CNT se incrementará en uno. Sabemos que cuando CNT calcula el valor de recarga automática almacenado en el registro ARR, volverá a cero. Si ARR es 1000. Entonces el valor de conteo de CNT tiene la siguiente relación:

imagen-20230603170109275

Debido a que el reloj interno es de 1 khz, el registro CNT aumenta en 1 cada 1 ms. Cuando el conteo llega a 1000, el valor de ARR se satisface y la carga comenzará nuevamente.

Muy bien, ahora usa nuestros pequeños cerebros. Supongamos que no sabemos cuál es el reloj interno. ¿Cómo podemos saber su frecuencia a través de CNT?

Los lectores pueden detenerse aquí y pensar en cómo se debe resolver este problema. La respuesta se revelará más adelante.

Primero podemos configurar el valor ARR para que sea lo suficientemente grande, como 65536, para evitar recargar y contar desde 0 después de que el valor de conteo alcance ARR. Podemos leer el valor de CNT cada 1 segundo y, después de leer el valor actual, borrar el registro de CNT y comenzar a contar nuevamente. Se puede imaginar que el CNT leído cada segundo es el flanco ascendente del reloj interno recibido por el temporizador dentro de 1 segundo ¿No es el número de flancos ascendentes la frecuencia del reloj? (vómito~~éxtasis) Bajo el ejemplo actual, es concebible que cada lectura sea 1000.

Con esta idea, ¿no podemos medir la frecuencia de la fuente del reloj del temporizador? Sería genial si esta fuente de reloj pudiera elegir una señal externa y enviarla al temporizador como una fuente de reloj a través del pin del puerto IO. ¡Eh! ¡Casualmente, el temporizador realmente tiene un pin de reloj externo!

Temporizador reloj externo

La siguiente figura es un diagrama de bloques del temporizador interceptado del manual de referencia:

Imagen QQ 20230603171436

TIMX_EXR es el pin del reloj externo. Si ve este diagrama de bloques y murmura, es muy problemático. ¿Cuáles son las otras cajas desordenadas? ¿Para qué sirven el ITR0 y el TRC al lado? No te preocupes, simplifiquemos un poco el gráfico:

914C47CEEC0B42B77177D684639B7C75

El temporizador conduce a un pin, que corresponde a un puerto IO.Ingresamos la señal PWM externa a este pin: TIMx_EXR. Después de que la señal pwm ingresa a la detección de flanco ascendente, se conecta al registro CNT para contar y agregar uno a cada flanco ascendente.

Ahora configuramos el ARR en 65536, y el pin ETR está conectado a una señal PWM de 60k. Lea el valor de conteo del registro CNT cada 1 segundo y límpielo después de la lectura. Es concebible que cada vez que se lea el CNT, sea 60000, correspondiente a este segundo, el CNT detecta 60k flancos ascendentes y la frecuencia PWM es 60k.

¡Pero! Si la frecuencia supera los 65536 Hz, el valor de conteo de CNT se borrará automáticamente después de presionar ARR, ¿entonces no podemos leer los datos? Si quieres saber qué pasó después, escuchemos la siguiente sección.

frecuencia de ruptura

Después de que CNT llega a ARR, se actualiza, contando desde cero. Sin embargo, se generará una interrupción del temporizador. Podemos definir una variable CONTAR, cuando ocurre una interrupción, la variable se incrementará en uno, y esta variable indicará cuántos ciclos se han registrado y cuántas ARR hay.

Suposición: ARR es 50k, la frecuencia PWM de entrada externa es 10.001M. Cuando leemos cada 1 segundo, leeremos que COUNT es 2000 y que el valor del registro CNT es 1000. Entonces la frecuencia PWM se puede calcular como:
ARR ∗ COUNT + CNT = 50000 ∗ 2000 + 1000 = 10.001 M ARR*COUNT+CNT=50000*2000+1000=10.001Mun RRCUENTA _ _+CNT=500002000+1000=10.001 M
Cabe señalar que después de cada lectura, no solo se debe borrar el registro CNT, sino que también se debe borrar la variable COUNT.

Establecimiento de ingeniería

árbol del reloj

imagen-20230603190613506

imagen-20230603190625608

Configuración del temporizador

Esta rutina utiliza dos temporizadores. El primero es el temporizador 2 y la fuente del reloj es un reloj externo.

imagen-20230603190513559

Se puede ver que PA0 es el pin del reloj externo correspondiente al temporizador 2. Solo necesitamos conectar la señal PWM externa a PA0 para medir la frecuencia.

imagen-20230603190914960

Encienda la interrupción del temporizador 2, que se usa para generar una interrupción de actualización cuando el valor de conteo excede 65536, y agregue uno a la variable en la interrupción, lo que indica que se ha contado un ciclo en este momento.

imagen-20230603191028836

El temporizador 3 se usa para generar una interrupción de 1 s y lee la frecuencia actual en la interrupción cada segundo.

imagen-20230603190653410

imagen-20230603191955032

Configuración del puerto serie

imagen-20230603192104481

codigo de GENERACION

Imagen QQ 20230603192419

Imagen QQ 20230603192436

escritura de código

Redirección de puerto serie

Al final de usart.c, escribe la siguiente función

#include <stdio.h>

int fputc(int ch, FILE *f)
{
    
    
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}

int fgetc(FILE *f)
{
    
    
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}

Imagen QQ 20230603192340

En main.c, incluya el archivo de encabezado:

#include "stdio.h"

Imagen QQ 20230603192910

Imagen QQ 20230603194008

conteo de pulsos

Primero defina las variables utilizadas para contar, y el significado de las variables se explica en los comentarios.

uint32_t FQ; // 用来存放频率

uint16_t CNT_2 = 0; // 超出65536位后 用这个记录超过的次数
uint16_t CNT_1 = 0; // 0-65536内用这个记录

Imagen QQ 20230603192836

Luego inicie los temporizadores 2 y 3.

HAL_TIM_Base_Start_IT(&htim3); // 启动定时器3进行1S定时

HAL_TIM_Base_Start_IT(&htim2); // 启动定时器2进行外部脉冲计数

Imagen QQ 20230603192839

Debido a que los temporizadores 2 y 3 se encienden secuencialmente, no se puede usar la frecuencia medida por primera vez.

La siguiente es la parte importante de este artículo, leer el valor de conteo:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    
    
    if (htim == (&htim3)) // 定时器中断1S触发一次
    {
    
    
        CNT_1 = __HAL_TIM_GET_COUNTER(&htim2); // 读取CNT计数值
        //		CNT_1 = TIM2->CNT;// 读取CNT寄存器这样也可以
        FQ = CNT_1 + CNT_2 * (__HAL_TIM_GET_AUTORELOAD(&htim2) + 1); // 获取频率值
        __HAL_TIM_SET_COUNTER(&htim2, 0);// 设置CNT为0
        printf("cnt:%u\n", FQ); // 打印频率值   1S打印一次
        CNT_1 = 0;  
        CNT_2 = 0; 
    }
    if (htim == (&htim2)) // 计数值计满,产生更新中断
    {
    
    
        CNT_2++; // 记满后,+1,标志多了一个满量程数
    }
}

imagen-20230603193436367

La fórmula de cálculo de frecuencia aquí es la siguiente:
FQ = CNT 1 + CNT 2 ∗ ( 65535 + 1 ) FQ=CNT_1+CNT_2*(65535+1)FQ=CN T1+CN T2( 65535+1 )

__HAL_TIM_GET_AUTORELOAD(&htim2) lee el valor del registro ARR de TIM2, porque el conteo comienza desde 0, entonces se suma uno. Por ejemplo, ARR es 999, calculado de 0 a 999, en realidad calculado 999+1 veces.

conexión de hardware

alfiler objeto de conexión paráfrasis
PA0 Terminal positivo del generador de señal Pin de reloj externo de TIM2
TIERRA Terminal negativo del generador de señal por tierra

Debido a que mi placa de desarrollo tiene ch340 integrado, no es necesario conectar un asistente de puerto serie ch340 externo aquí.

IMG_20230603_195910

resultado de la operación

El generador de señal genera una señal de onda cuadrada de 12M, 0-3.3V. La información del puerto serie es la siguiente:

imagen-20230603200553300

Se puede ver que cnt midió exitosamente la frecuencia de la señal externa con un error de 0.004%.

De hecho, debido a que existe la parte de detección de borde dentro del temporizador, el tiempo no solo puede medir la frecuencia de la señal PWM, sino también medir directamente la frecuencia de la onda sinusoidal y la onda triangular , y la amplitud no tiene que ser 0- ¡3,3 V!

Imagen QQ 20230605160228

Por ejemplo, mido una onda triangular de 1M, 1V-2V:

IMG_20230603_202058

imagen-20230603202037889

Como se mencionó anteriormente, los primeros dos datos son inutilizables al comienzo de la operación y deben descartarse.La medición posterior muestra que la frecuencia de la señal es 999957hz, con un error de 0.0043%.

Lo siguiente es lo que probé, y puede medir señales de diferentes formas de onda de frecuencia y diferentes amplitudes.

  • Onda cuadrada (el valor límite dentro de 8M, y luego sube, el nivel alto debe ser lo más alto posible y el nivel bajo debe ser lo más bajo posible)
    • Alto nivel 1.6——3V (3.3 es el límite superior, se recomienda usar dentro de 3V)
    • Bajo nivel - 200mv - 1.3v.
  • Seno (dentro de 1M)
    • Alto nivel 1.7V - 3V
    • Bajo nivel-200mv——1.3v
  • Triángulo (dentro de 1k)
    • Alto nivel 1.7V - 3V
    • Bajo nivel-200mv——1.3v

La siguiente tabla es la forma que probé con H750, y la precisión de la prueba de H7 es ligeramente superior a la de F1

frecuencia error
1k 0
10k 0
1M 22
10M 212
15M 317
Mi generador de señal no puede enviar más alto ————

práctica

  1. Reproduzca la rutina de este artículo y mida la frecuencia de la señal de onda cuadrada, onda sinusoidal y otras formas de onda bajo diferentes frecuencias de amplitud.
  2. El rango de medición de este método es alto, pero el tiempo de medición es largo. ¿Hay alguna forma de sacrificar ligeramente la precisión a cambio de una medición de frecuencia más rápida?
  3. La esencia del conteo externo es medir el número de flancos ascendentes externos. Cuando CNT alcance el valor ARR, se generará una interrupción de actualización. ¿Puede funcionar esta función en otros escenarios? ARR se puede cambiar dinámicamente.

posdata

Este artículo está incluido en:

Estación de deportes electrónicos de Tang Chengqian

Este artículo es la punta del iceberg en una serie de artículos, bienvenidos a la pequeña estación para ver.

Programa de apoyo:

Modo externo de temporización STM32cubemx para medir la frecuencia por encima de 10M rutina gitee

Imagen QQ 20230603203816

Supongo que te gusta

Origin blog.csdn.net/qq_34022877/article/details/131025473
Recomendado
Clasificación