Configuración de un PWM simple en atmega328 a cierta frecuencia

1

Me cuesta mucho configurar un PWM de 16 bits en atmega328 que funcione con una frecuencia de 50Hz y tenga un ciclo de trabajo que puede variar. También tengo mis dudas de que si puedo tener un ADC trabajando junto con este PWM de 16 bits ya que ambos usan timer1. Hay una selección de fuente de activación automática ADTSX en el registro ADCSRB que supuse que debería poder seleccionar la fuente de reloj para mi conversión analógica, pero he programado y nada cambió, no podría tener el ISR del temporizador 1 y la conversión analógica al mismo tiempo y No probé el PWM y el ADC juntos porque no sé cómo configurar el PWM.

Este es el código solo para configurar PWM que tengo ahora:

#include <avr/io.h>

int flag = 0;

ISR(TIMER1_COMPA_vect) {
  if (flag == 0)
    OCR1A = 11;
  else
    OCR1A = 160;    
}

int main(void) {
   DDRB |= (1 << DDB1);
   // PB1 as output
  OCR1A = 160;
  // set non-inverting mode
  TCCR1A |= (1 << COM1A1);
  // set 10bit phase corrected PWM Mode
  TCCR1B |= (1 << WGM12);
  // set no prescaler 
  TCCR1B |= (1 << CS10);
   while (1)
   {
   }
}

PS: variaré el ciclo de trabajo entre 1 ms a 2 ms activando un ESC que controla un motor sin escobillas.

    
pregunta Rinaldi Segecin

1 respuesta

2

Para una resolución completa de 16 bits, querrá el Modo de generación de forma de onda 8, es decir, WGM13: 0 = 1000b.

En este modo, define la resolución (= valor de contador máximo) a través del valor del Registro de captura de entrada, por lo que necesita ICR1 = 0xffff .

Dependiendo de la polaridad que desee, configure el modo de salida de comparación COM1A1: 0 a 10b u 11b.

ICR1 = 0xffff;

OCR1A = <initial duty cycle>;

TCCR1A =
    // Compare output mode:
    (1 << COM1A1) | (0 << COM1A0) | 
    // lower 2 WGM bits:
    (0 << WGM11) | (0 << WGM10);

TCCR1B =
    // upper 2 WGM bits:
    (1 << WGM13) | (0 << WGM12) |

    // Prescaler/start timer:
    (0 << CS12) | (0 << CS11 ) | (1 << CS10);

(No he intentado esto)

Ahora el temporizador está subiendo y bajando y alternando el pin OC1A cada vez que pasa OCR1A. Todo lo que tiene que hacer es establecer un nuevo valor de OCR1A cuando desee cambiar el ciclo de trabajo; el resto lo hace el hardware.

    
respondido por el JimmyB

Lea otras preguntas en las etiquetas