tutorial salidas mega frecuencia ejemplo due c arduino ada avr pwm

salidas - Programando un PWM en un microcontrolador Arduino Mega ATmega2560



pwm arduino mega (4)

Mirando www.atmel.com/Images/doc2549.pdf página 136, veo una nota:

"El bit de Reducción de potencia / Contador3, PRTIM3, en" PRR1 - Registro de reducción de potencia 1 "en la página 57 debe escribirse en cero para habilitar el módulo de temporizador / contador3".

Puede ser relevante?

No sé cuáles son los valores predeterminados para los regs de administración de energía, y no he usado el 2560.

El resto se ve bien para mí, aunque he usado las librerías de temporizador avr-timer0.adb, etc. en el 328p en lugar de hacer las mías.

Estoy tratando de habilitar un PWM en un Arduino Mega ( ATmega2560 ), pero estoy enfrentando algunos problemas.

Primero, estoy tratando de programar esto en Ada . Deseo utilizar los tres canales Timer3 con FastPWM, así que escribí

procedure Main is begin -- Nullify Timer3 buffers TCCR3A := 0; TCCR3B := 0; TCCR3C := 0; -- Waveform Generation Mode -- Fast PW, 8-bit, TOP = 0x00FF, Update OCR3x at BOTTOM, TOV3 Flag Set on TOP -- => WGM33|WGM32|WGM31|WGM30 = 0|1|0|1 TCCR3A := TCCR3A or TCCR3A_WGM30; TCCR3B := TCCR3B or TCCR3B_WGM32; -- Compare Output Mode: -- Fast PWM, non-inverting mode -- => COM3A1|COM3A0|COM3B1|COM3B0|COM3C1|COM3C0 = 1|0|1|0|1|0 TCCR3A := TCCR3A or TCCR3A_COM3A1 or TCCR3A_COM3B1 or TCCR3A_COM3C1; -- Clock Select: clk/1024 => CS32|CS31|CS30 = 1|1|1 TCCR3B := TCCR3B or TCCR3B_CS32 or TCCR3B_CS31 or TCCR3B_CS30; -- Set Timer3 pins as output : -- Channel A : Digital Pin 5 / Chip Pin 5 (PE3/OC3A/AIN1) -- Channel B : Digital Pin 2 / Chip Pin 6 (PE4/OC3B/INT4) -- Channel C : Digital Pin 3 / Chip Pin 7 (PE5/OC3C/INT5) DDRE := DDRE_DDE3 or DDRE_DDE4 or DDRE_DDE5; OCR3AH := 0; OCR3AL := 250; OCR3BH := 0; OCR3BL := 250; OCR3CH := 0; OCR3CL := 250; end Main;

Las conexiones de hardware están bien; Lo probé usando un código simple en el Arduino IDE. Entonces, para mí, está muy claro que el código carece de algo o está haciendo algo mal, y esto debería ser causado por un problema en la inicialización de PWM. ¿Podría alguien explicarme dónde cometí tal error?

Gracias por adelantado.

Actualizar

Si Ada puede ser difícil de obtener toda la lógica, el código equivalente en C es (puedes construirlo usando AS6 , el resultado es el mismo, es decir, no se genera ninguna señal):

int main(void){ TCCR3A = 0; TCCR3B = 0; TCCR3C = 0; /* Waveform Generation Mode Fast PW, 8-bit, TOP = 0x00FF, Update OCR3x at BOTTOM, TOV3 Flag Set on TOP => WGM33|WGM32|WGM31|WGM30 = 0|1|0|1 */ TCCR3A = TCCR3A|(1<<WGM30); TCCR3B = TCCR3B|(1<<WGM32); /* Compare Output Mode: Fast PWM, non-inverting mode => COM3A1|COM3A0|COM3B1|COM3B0|COM3C1|COM3C0 = 1|0|1|0|1|0*/ TCCR3A = TCCR3A|(1<<COM3A1)|(1<<COM3B1)|(1<<COM3C1); /* Clock Select: clk/1024 => CS32|CS31|CS30 = 1|1|1 */ TCCR3B = TCCR3B|(1<<CS32)|(1<<CS31)|(1<<CS30); /* Set Timer3 pins as output : Channel A : Digital Pin 5 / Chip Pin 5 (PE3/OC3A/AIN1) Channel B : Digital Pin 2 / Chip Pin 6 (PE4/OC3B/INT4) Channel C : Digital Pin 3 / Chip Pin 7 (PE5/OC3C/INT5)*/ DDRE = DDRE|(1<<DDE3)|(1<<DDE4)|(1<<DDE5); /* Set PWM Duty Cycles */ OCR3AH = 0; OCR3AL = 250; OCR3BH = 0; OCR3BL = 250; OCR3CH = 0; OCR3CL = 250; }


No estoy seguro, pero si olvida el bucle infinito al final de su función principal, el programa se detiene, todas las interrupciones se desactivarán y los controladores entrarán en un bucle vacío.

Y sin interrupciones no PWM.

int main(void){ .... while (1) { } return 0; }



Una observación aparece a la vez, casi seguro de que esto no es correcto:

-- => COM3A1|COM3A0|COM3B1|COM3B0|COM3C1|COM3C0 = 1|0|1|0|1|0 TCCR3A := TCCR3A or TCCR3A_COM3A1 or TCCR3A_COM3B1 or TCCR3A_COM3C1;

¿Por qué? Porque las constantes con nombre como COM3A0 son solo alias para enteros que indican la posición del bit (0 a 7). En C, cuando configuramos hacemos algo como:

REGISTER |= (1<<COM3A0);

y COM3A0 = 3, luego se convierte en (1 << 3) u 8 que está ORed.

Que desplaza un 1 el número de lugares hacia la izquierda antes de ORing con el valor de registro actual. Entonces, a menos que su COM3A0, por ejemplo, ya haya cambiado de bit, todo lo que esta instrucción está haciendo es ORing varios unos y ceros y asignando el único resultado a TCCR3A.