Alternar OC1A, OC1B y OC1C usando el temporizador en modo CTC

La mayoría de los microcontroladores AVR tienen tres pines dedicados para cada temporizador (por ejemplo, OC1A, OC1B y OC1C) que se pueden alternar automáticamente cuando el contador alcanza el llamado valor máximo en los tres registros correspondientes (OCR1A, OCR1B y OCR1C).

No estoy seguro de cómo pueden operar esos tres pines/registros dedicados en modo CTC para diferentes valores superiores independientes, y esto es lo que quiero lograr. Quiero alternar OC1A, OC1B y OC1C (aunque "comparar salida", no mediante interrupción o algo así) en diferentes intervalos (para ver que tienen tres registros y pines dedicados).

Digamos que quiero programar el temporizador AVR para alternar los pines OC1A, OC1B y OC1C en diferentes intervalos (por ejemplo, 1 segundo, medio segundo, un cuarto de segundo), pero no funciona como esperaba. Configuré comparar el registro de coincidencia A y B y C con los tres valores diferentes, teniendo el mayor valor en A (también intenté tenerlo en C).

Solo OC1A se alterna a la frecuencia necesaria.

Para mí, parece que si solo hicieran que la parte superior de OC1A borrara el contador, entonces sería posible que los tres pines funcionen en diferentes tres valores independientes. ¿Es esto correcto?

Aquí está el segmento que puse en la configuración de mi Arduino Lenoardo (basado en ATmega32U4 ). Dejé loop()vacío.

  // Initialize timer1
  noInterrupts();           // Disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1C = 0;
  TCNT1  = 0;

  OCR1A = 62500;            // Compare match register 16 MHz/256/1 Hz
  OCR1B = 31250;            // Compare match register 16 MHz/256/2 Hz
  OCR1C = 15625;            // compare match register 16 MHz/256/4 Hz

  // Toggle OC1A, OC1B and OC1C => (on Lenoardo) PB5, PB6 and PB7 => digital 9, 10, 11
  // TCCR1A = 0b01010100;
  TCCR1A |= (1 << COM1C0) | (1 << COM1B0) | (1 << COM1A0);
  // TCCR1B = 0b1100
  TCCR1B |= (1 << WGM12);   // CTC mode
  TCCR1B |= (1 << CS12);    // 256 prescaler

  interrupts();             // Enable all interrupts
¿Con qué AVR estás tratando?
¿Cuál es la frecuencia necesaria y cuál es la frecuencia real?
@jippie no se trata de una frecuencia específica ni de un chip, se trata de cómo usar cualquier AVR para que los pines OC1A y OC1B cambien automáticamente periódicamente a diferentes valores para OCR1A/OCR1B
Todavía están atados al mismo temporizador. No estoy seguro de por qué piensas que pueden tener períodos diferentes.
@ignacio-vazquez-abrams 3 registros diferentes y 3 pines diferentes, que desperdicio si pueden tener algo diferente. ¿Pueden tener diferentes fases? ¿cualquier cosa?
Por supuesto que pueden tener diferentes fases. Use PWM o CTC que tenga ICR1 como TOP y luego configúrelos en diferentes valores. O pueden ser diferenciales. Establezca uno en no inversor y otro en inversor, y asígneles el mismo valor.
@IgnacioVazquez-Abrams la pregunta es sobre CTC. de modo que OCR1A y ​​OCR1B ... están destinados a formar un cambio de fase diferente, no de frecuencia. por favor formúlelo como una respuesta y lo elegiré. por favor incluya código de muestra.

Respuestas (2)

Un temporizador en modo normal, PWM rápido o CTC cuenta directamente de ABAJO a ARRIBA si no se aplica ninguna influencia externa. A medida que pasa cada valor de OC, emite una interrupción y/o roba un pin, como está configurado para hacerlo. Cada valor de OC solo se cruza una vez , lo que significa que todos los OC para el mismo temporizador se ejecutan a la misma frecuencia .

Se pueden configurar para que tengan diferentes fases o para que operen en pares diferenciales en función de los valores de los bits OCRnr y COMnrb, pero la única forma de hacer que usen diferentes frecuencias directamente es manipular sus valores OCR cada vez que se invoca su ISR.

La forma más fácil de hacer que los pines cambien a diferentes frecuencias sería configurar el temporizador en el GCF/LCM de los diversos períodos/frecuencias deseadas, mantener un conteo de ciclos transcurridos y luego quitar los pines cuando haya pasado el número apropiado de ciclos. .

Para ser claros, la declaración "tres pines dedicados para cada temporizador (por ejemplo, OC1A, OC1B y OC1C)" en la pregunta no es cierta. OC1A, OC1B y OC1C están asociados con un solo temporizador, timer1 (temporizador de 16 bits).

El módulo temporizador le permite generar múltiples salidas con diferentes ciclos de trabajo, pero todas tendrán la misma frecuencia fundamental. Si desea generar diferentes frecuencias, deberá utilizar un método diferente. Hay dos formas principales de hacer esto. El primer método es usar tres temporizadores, cada uno operando a una frecuencia diferente. Si está tratando de generar salidas de frecuencia relativamente baja (1 kHz o menos), entonces puede usar un tic de temporizador razonable y una rutina de interrupción. Si desea generar 1 Hz, 2 Hz y 4 Hz, puede configurar un tic del temporizador de al menos 8 Hz y luego contar los tics y encender y apagar los pines en el momento adecuado. Con un tic del temporizador de 8 Hz, generar una salida de 4 Hz requeriría alternar el pin en cada ciclo, 2 Hz sería cada dos ciclos y 1 Hz sería cada 4 ciclos.

Estoy tratando de entender el uso de 3 registros TCCR1A, TCCR1B y TCCR1C y tener 3 pines correspondientes (OC1A, OC1B y OC1C) para alternar. por qué hay 3 pines, registros y valores dedicados si solo se usara uno prácticamente.