Saltar al contenido
Apuntes GITT 4º

Escribe al menos dos letras.

    SEDAPulsos y capturaPEI1 · 19:00 en 20 días

    Temporizadores

    Pulsos y captura

    Un pulso de duración exacta y medir frecuencia, ciclo de trabajo y ancho con la captura

    Idea clave. Hasta aquí el Timer sacaba señales por los pines MAT. Ahora va al revés: con la captura, un flanco en un pin de entrada copia el valor del TC en un registro. Así se mide frecuencia, ciclo de trabajo o ancho de un pulso con la precisión del reloj, no con la de la ISR. Antes, un caso intermedio: sacar un solo pulso de duración exacta.

    Un pulso de duración T

    Para un único pulso de T segundos en MATn.1 (por ejemplo, MAT0.1 en P1.29):

    MR1=Ftick⋅T−1MR1 = F_{tick}\cdot T - 1
    void set_pulso_alto(float duracion) {           // duración en segundos
      LPC_TIM0->MR1 = Ftick * duracion - 1;
      LPC_TIM0->EMR = (1 << 1) | (1 << 6);          // EM1 = 1 (pin a 1), EMC1 = 01 (bajar en MR1)
      LPC_TIM0->TCR = 0x01;                         // arrancar
    }

    La subida es software (empieza cuando se ejecuta la función) y la bajada es hardware (exacta). El pulso dura justo T aunque la CPU tarde en llegar, porque el Timer empieza a contar en el mismo momento en que se sube el pin. Con F_tick = 25 MHz, la resolución es de 40 ns: un pulso de 1 µs son 25 cuentas.

    El modo captura

    Cada Timer tiene dos entradas de captura, CAPn.0 y CAPn.1, y dos registros CR0 y CR1. Cuando llega el flanco elegido, el hardware copia el TC en CRx y, si se pide, interrumpe. El TC sigue contando: la captura no lo para ni lo reinicia.

    TnCCR · control de captura
    BitsCampoQué hace
    0CAP0RE1 = capturar en CR0 con flanco de subida en CAPn.0
    1CAP0FE1 = capturar en CR0 con flanco de bajada (los dos a 1: ambos flancos)
    2CAP0I1 = interrumpir con cada captura en CR0
    3–5CAP1RE, CAP1FE, CAP1ILo mismo para CAPn.1 y CR1

    Los flags están en IR: los bits 0–3 son de MR0–MR3 y los bits 4 y 5 de CR0 y CR1. Como siempre, se borran escribiendo un 1.

    Algunos pines de captura: CAP0.0 en P1.26, CAP0.1 en P1.27, CAP1.0 en P1.18, CAP2.0 en P0.4 y CAP3.0 en P0.23. Hay que ponerlos en su función con PINSEL, como los MAT.

    a) Medir la frecuencia

    El TC corre libre (sin reset) y se captura en cada flanco de subida. Entre dos capturas hay un periodo:

    N=CR0k−CR0k−1f=FtickNN = CR0_{k} - CR0_{k-1} \qquad f = \frac{F_{tick}}{N}
    void TIMER0_IRQHandler(void) {
      static uint32_t anterior;
      uint32_t n;
      LPC_TIM0->IR = (1 << 4);           // flag de CR0
      n = LPC_TIM0->CR0 - anterior;      // cuentas de un periodo
      frecuencia = Ftick / n;
      anterior = LPC_TIM0->CR0;
    }

    El valor de CR0 es exacto aunque la ISR llegue tarde (la latencia solo retrasa cuándo se lee). Y con uint32_t, la resta da bien aunque el TC haya pasado de 2³² − 1 a 0 entre dos capturas.

    Los límites: a frecuencia muy baja, N se sale de 32 bits (con 25 MHz, por debajo de 0,006 Hz); a frecuencia muy alta, las capturas llegan más rápido de lo que la ISR las atiende. Con F_tick alto, N es grande y la medida más fina.

    b) Medir el ciclo de trabajo

    Se capturan los dos flancos (CAP0RE y CAP0FE a 1). La ISR entra dos veces por periodo y tiene que saber cuál ha llegado: se guarda en una variable (o se lee el pin).

    D=THT=CR0baja−CR0subeCR0sube,k−CR0sube,k−1D = \frac{T_H}{T} = \frac{CR0_{baja} - CR0_{sube}}{CR0_{sube,k} - CR0_{sube,k-1}}

    c) Medir el ancho de un pulso

    Es lo mismo pero solo hace falta T_H: más sencillo.

    void TIMER0_IRQHandler(void) {
      static uint32_t flanco_subida;
      static int esperando_subida = 1;
      LPC_TIM0->IR = (1 << 4);
      if (esperando_subida) {
        flanco_subida = LPC_TIM0->CR0;
        esperando_subida = 0;              // el siguiente será de bajada
      } else {
        ancho = LPC_TIM0->CR0 - flanco_subida;
        esperando_subida = 1;
      }
    }

    En vez de capturar en ambos flancos, se puede capturar solo en uno y cambiar el flanco en CCR dentro de la ISR (subida → bajada → subida…). Así no hay duda de qué flanco ha llegado.

    Preguntas de examen

    Configura TIMER1 para medir la frecuencia de una señal en CAP1.0 (F_PCLK = 25 MHz). ¿Qué registros tocas y qué hace la ISR?

    PINSEL para CAP1.0 (P1.18), PR = 0, MCR sin ningún reset (el TC corre libre), TCR = 1 para arrancar, CCR = CAP0RE | CAP0I (bits 0 y 2) y NVIC_EnableIRQ(TIMER1_IRQn). En la ISR: borrar IR bit 4, N = CR0 − anterior (uint32_t), f = 25·10⁶/N, anterior = CR0. (Respuesta redactada a partir de los apuntes.)

    ¿Por qué el pulso de set_pulso_alto dura exactamente T aunque la CPU sea lenta?

    Porque la bajada no la hace la CPU: la hace el Match (EMC1 = 01) cuando el TC llega a MR1, contando desde el arranque. La subida y el arranque se hacen juntos en software, así que el ancho solo depende de MR1 y F_tick. (Respuesta redactada a partir de los apuntes.)

    Una señal tiene T = 1 ms y T_H = 250 µs. Con F_tick = 25 MHz, ¿qué diferencias de CR0 lees y qué D sale?

    Periodo: 25 000 cuentas. Alto: 6 250 cuentas. D = 6 250/25 000 = 0,25. (Respuesta redactada a partir de los apuntes.)

    Material del curso usado: Apuntes de Miguel · Temporizadores del LPC17xx (diapositivas de clase) · UM10360 (manual del LPC17xx), cap. 8 y 21.