¿Es posible usar Timer1 en un ATMega para generar una interrupción de comparación en OCR1A y salida PWM en OCR1B? Lo he intentado con algo similar a lo siguiente, pero tampoco funciona con todo lo que he probado.
TCCR1A = _BV(COM1B1) | _BV(WGM11) | _BV(WGM10);
TCCR1B = PRESCALE1_8;
OCR1B = 0;
// set compare match register for 1000Hz
OCR1A = 2000;
// turn on CTC mode
TCCR1B |= _BV(WGM12);
Nota al margen: sé que esto es extremadamente similar a otra pregunta mía , pero eso se refería a PWM en un temporizador e interrupciones en otro. Esta vez tengo problemas para sacar ambos del MISMO temporizador.
Su código establece el contador para la operación PWM de fase correcta con el valor superior 0x3FF, por lo que el primer problema que enfrentará es que las interrupciones de comparación de coincidencias no se activarán en intervalos iguales debido a la forma en que funciona este modo, que cuenta hasta la parte superior y luego cambie de dirección y cuente hacia atrás.
El otro problema es que el contador cuenta hasta 1023 (0x3ff) y vuelve a 0, por lo que no hay forma de obtener una interrupción de coincidencia por un valor de 2000 (OCR1A = 2000)
Operación PWM de fase correcta:
Este es un código mínimo para mega328 que se ejecuta a 16 MHz que configura el temporizador 1 para generar un PWM rápido con una frecuencia de aproximadamente 1 KHz (frecuencia establecida por ICR1 y función establecida por OCR1B) y también proporciona una interrupción de desbordamiento del temporizador 1 con una tasa de 1 KHz.
#include <avr/io.h>
#include <avr/interrupt.h>
// Timer1 overflow interrupt service routine
ISR(TIMER1_OVF_vect)
{
PORTB ^= 1; // invert PORTB.0
}
int main(void)
{
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=Out Bit1=In Bit0=Out
DDRB = 0x05;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 2000,000 kHz
// Mode: Fast PWM top=ICR1
// OC1A output: Disconnected
// OC1B output: Non-Inverted PWM
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 1,0245 ms
// Output Pulse(s):
// OC1B Period: 1,0245 ms Width: 0,12806 ms
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << COM1B1) | (0 << COM1B0) | (1 << WGM11) | (0 << WGM10);
TCCR1B = (0 << ICNC1) | (0 << ICES1) | (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
TCNT1 = 0;
ICR1 = 2048;
OCR1A = 0;
OCR1B = 256;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1 = (0 << ICIE1) | (0 << OCIE1B) | (0 << OCIE1A) | (1 << TOIE1);
// Global enable interrupts
sei();
while(1)
{
// Place your code here
}
}
adam haile
alexan_e
adam haile
alexan_e
adam haile
alexan_e
adam haile
alexan_e
TCCR1A = _BV(WGM11) | _BV(WGM10);
PWM, Phase Correct, 10 bits , ese 10 bit significa que el valor SUPERIOR es 0x03FF (está en la hoja de datos) y es lo que realmente establece la frecuencia PWM.adam haile
adam haile
alexan_e
TIMSK1=(1<<TOIE1);
y agregue el controlador de interrupción, se llamará a una velocidad de 917 Hz, cada vez que el contador llegue al fondo (0). Timer2 es independiente de timer1, ninguno de los anteriores lo afecta.adam haile
alexan_e
alexan_e
david normando
alexan_e
david normando
alexan_e
david normando