Initialize OCR1A to FAN02_MIN_DUTY and add PWM documentation

This commit is contained in:
2024-09-06 14:24:27 +02:00
parent b118631500
commit 82126d9aba
2 changed files with 82 additions and 16 deletions

View File

@@ -7,17 +7,6 @@ int PWM_Init(void)
// PD5: PWM NF-A8 Fan Peltier Cold Side // PD5: PWM NF-A8 Fan Peltier Cold Side
// PD7: PWM NF-R8 Fan Heating Element // PD7: PWM NF-R8 Fan Heating Element
DDRD |= BIT(PD4) | BIT(PD5); // | BIT(PD7);
// TIMER1: Fast mode, non-inverting, top=ICR1, prescale /1
TCCR1A = BIT(WGM11) | BIT(COM1A1) | BIT(COM1B1);
TCCR1B = BIT(WGM12) | BIT(WGM13) | BIT(CS10);
ICR1 = PWM_CYCLE_TOP; // 8000 MHz / 25000 KHz
OCR1A = FAN01_MIN_DUTY;
OCR1B = FAN02_MIN_DUTY;
// ATMega32A does not have more than two outputs for the // ATMega32A does not have more than two outputs for the
// 16-bit timer and the other 8-bit timers don't have modes // 16-bit timer and the other 8-bit timers don't have modes
// where the value of TOP can be changed. We can only get // where the value of TOP can be changed. We can only get
@@ -27,14 +16,91 @@ int PWM_Init(void)
// 8-bit this gives us a really low duty step size of 2.5%. // 8-bit this gives us a really low duty step size of 2.5%.
// Ideal would be two 16-bit timers with two outputs each. // Ideal would be two 16-bit timers with two outputs each.
DDRD |= BIT(PD4) | BIT(PD5) | BIT(PD7);
// PORTD &= ~BIT(PD7); // Turn off PD7
// TCCR1A Timer1 Control Register A
// 7 6 5 4 3 2 1 0
// COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10
// TCCR1B Timer1 Control Register B
// 7 6 5 4 3 2 1 0
// CNC1 ICES1 WGM13 WGM12 CS12 CS11 CS10
// The COM1A1:0 and COM1B1:0 control the Output
// Compare pins (OC1A and OC1B respectively) behavior.
// If one or both of the COM1A1:0 bits are written to
// one, the OC1A output overrides the normal port
// functionality of the I/O pin it is connected to.
// If one or both of the COM1B1:0 bit are written to
// one, the OC1B output overrides the normal port
// functionality of the I/O pin it is connected to.
// However, note that the Data Direction Register
// (DDR) bit corresponding to the OC1A or OC1B pin
// must be set in order to enable the output driver.
// COM1B1:0: Compare Output Mode, Fast PWM
// COM1A1/ COM1A0/ Description
// COM1B1 COM1B0
// 0 0 OC1A/OC1B disconnected.
// 0 1 WGM13:0 = 15: Toggle OC1A on match,
// OC1B disconnected. For other WGM13:0
// settings OC1A/OC1B disconnected.
// 1 0 Clear OC1A/OC1B on match and set at
// BOTTOM (non-inverting).
// 1 1 Set OC1A/OC1B on match and clear at
// BOTTOM (inverting mode).
// A special case occurs when OCR1A/OCR1B equals TOP
// and COM1A1/COM1B1 is set. In this case the compare
// match is ignored, but the set or clear is done at
// BOTTOM.
// FOC1A/FOC1B: Force Output Compare for Compare unit A/B
// For ensuring compatibility with future devices, these
// bits must be set to zero when TCCR1A is written when
// operating in a PWM mode.
// WGM11:0: Waveform Generation Mode
// Combined with the WGM13:2 bits found in the TCCR1B
// Register, these bits control the counting sequence of
// the counter, the source for maximum (TOP) counter
// value, and what type of waveform generation to be used.
// See page 115 of the ATMega32A data sheet for all modes.
// Mode WGM13 WGM12 WGM11 WGM10 Timer Mode TOP
// 14 1 1 1 0 Fast PWM ICR1
// CS12:0: Clock Select
// CS12 CS11 CS10 Description
// 0 0 0 No clock source.
// 0 0 1 clk I/O /1 no prescaling.
// 0 1 0 clk I/O /8 from prescaler.
// 0 1 1 clk I/O /64 from prescaler.
// 1 0 0 clk I/O /256 from prescaler.
// 1 0 1 clk I/O /1024 from prescaler.
// 1 1 0 External clock on T1 falling edge.
// 1 1 1 External clock on T1 rising edge.
// TIMER1: Fast mode, non-inverting, top=ICR1, prescale /1
TCCR1A = BIT(WGM11) | BIT(COM1A1) | BIT(COM1B1);
TCCR1B = BIT(WGM12) | BIT(WGM13) | BIT(CS10);
ICR1 = PWM_CYCLE_TOP; // 8000 MHz / 25000 KHz
OCR1B = FAN01_MIN_DUTY; // PD4
OCR1A = FAN02_MIN_DUTY; // PD5
// TIMER2: Fast mode, non-inverting, top=0xFF, prescale /8 // TIMER2: Fast mode, non-inverting, top=0xFF, prescale /8
// TOP set to 8000000 (f_cpu) / 8 (prescale) / 25000 (f_pwm) - 1
// Top set to 8000000 (f_cpu) / 8 (prescale) / 25000 (f_pwm) - 1
// TCCR2 = BIT(WGM20) | BIT(WGM21) | BIT(COM21) | BIT(CS21); // TCCR2 = BIT(WGM20) | BIT(WGM21) | BIT(COM21) | BIT(CS21);
// OCR2 = 40 - 1; // XXX: OCR2A=top OCR2B=duty // OCR2 = 40 - 1; // XXX: OCR2A=TOP OCR2B=duty
TCCR2 = 0; TCCR2 = 0; // Normal operation
OCR2 = 0; OCR2 = FAN03_MIN_DUTY; // PD7
return 0; return 0;
} }

View File

@@ -35,7 +35,7 @@ int Init(void)
Info("Initializing..."); Info("Initializing...");
// The watchdog timer is clocked from a separate // The watchdog timer is clocked from a separate
// on-chip oscillator which runs at 1MHz. Eight // on-chip oscillator which runs at 1 MHz. Eight
// different clock cycle periods can be selected // different clock cycle periods can be selected
// to determine the reset period. If the reset // to determine the reset period. If the reset
// period expires, the chip resets and executes // period expires, the chip resets and executes