Handle PWM on pin PD4, PD5 and PD7
This commit is contained in:
BIN
docs/ATMEGA32A.pdf
Executable file
BIN
docs/ATMEGA32A.pdf
Executable file
Binary file not shown.
BIN
docs/PWM-NOCTUA.pdf
Executable file
BIN
docs/PWM-NOCTUA.pdf
Executable file
Binary file not shown.
@@ -5,9 +5,13 @@
|
||||
|
||||
#define BIT(n) (0x1U << (n))
|
||||
#define UNUSED(s) (void)(s)
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define CLAMP(n, hi, lo) (MIN(hi, MAX(n, lo)))
|
||||
|
||||
void Info(const char *fmt, ...);
|
||||
void Error(const char *fmt, ...);
|
||||
double Clamp(double n, double upper, double lower);
|
||||
|
||||
#include <util/delay.h>
|
||||
#define Sleep(ms) _delay_ms(ms)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "common.h"
|
||||
#include "bus/usart.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
static void Puts(const char *str)
|
||||
{
|
||||
|
||||
139
src/main.c
139
src/main.c
@@ -5,6 +5,11 @@
|
||||
#include <avr/interrupt.h>
|
||||
#include <assert.h>
|
||||
|
||||
// Minimum speed for Noctua fans is 20%
|
||||
#define FAN_01_MIN_DUTY 255 / 100 * 20
|
||||
#define FAN_02_MIN_DUTY 255 / 100 * 20
|
||||
#define HEATER_MIN_DUTY 0
|
||||
|
||||
// ADS1115 (ADC)
|
||||
// PCA9546 (Multiplexer TWI)
|
||||
// ATH20 (3x)
|
||||
@@ -26,6 +31,9 @@
|
||||
|
||||
static void SetPinDefaults(void);
|
||||
static void SetTWIChannel(int channel);
|
||||
static void SetFan01Speed(int n);
|
||||
static void SetFan02Speed(int n);
|
||||
static void SetHeaterTemp(int n);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@@ -39,29 +47,18 @@ int main(void)
|
||||
Info("Initializing...");
|
||||
SetTWIChannel(0);
|
||||
|
||||
Sleep(500);
|
||||
SetFan01Speed(51);
|
||||
SetFan02Speed(51);
|
||||
SetHeaterTemp(0);
|
||||
|
||||
for (;;) {
|
||||
Info("PING");
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SetPinDefaults(void)
|
||||
{
|
||||
// Initialize Pin Outputs
|
||||
// ======================
|
||||
|
||||
// PB0: MOSFET #1 (Peltier)
|
||||
DDRB |= (1 << PB0); // Out
|
||||
PORTB &= ~(1 << PB0); // Low
|
||||
|
||||
// PB1: MOSFET #2 (Heating)
|
||||
DDRB |= (1 << PB1); // Out
|
||||
PORTB &= ~(1 << PB1); // Low
|
||||
|
||||
// PB2: MOSFET #3 (Lights)
|
||||
DDRB |= (1 << PB2); // Out
|
||||
PORTB &= ~(1 << PB2); // Low
|
||||
}
|
||||
|
||||
static void SetTWIChannel(int channel)
|
||||
{
|
||||
unsigned char crb;
|
||||
@@ -115,3 +112,107 @@ static void SetTWIChannel(int channel)
|
||||
|
||||
Info("TWI channel was switched to %d.", channel);
|
||||
}
|
||||
|
||||
static void SetPinDefaults(void)
|
||||
{
|
||||
// Initialize Pin Outputs
|
||||
// ======================
|
||||
|
||||
// PB0: MOSFET #1 (Peltier)
|
||||
|
||||
DDRB |= BIT(PB0); // Out
|
||||
PORTB &= ~BIT(PB0); // Low
|
||||
|
||||
// PB1: MOSFET #2 (Heating)
|
||||
|
||||
DDRB |= BIT(PB1); // Out
|
||||
PORTB &= ~BIT(PB1); // Low
|
||||
|
||||
// PB2: MOSFET #3 (Lights)
|
||||
|
||||
DDRB |= BIT(PB2); // Out
|
||||
PORTB &= ~BIT(PB2); // Low
|
||||
|
||||
// PD4: PWM Peltier Hot Side
|
||||
// PD5: PWM Peltier Cold Side
|
||||
// PD7: PWM Heating
|
||||
|
||||
DDRD |= BIT(PD4) | BIT(PD5) | BIT(PD7);
|
||||
|
||||
// Fast mode, 8-bit, non-inverting, no prescaling
|
||||
TCCR1A = BIT(WGM10) | BIT(COM1A1);
|
||||
TCCR1B = BIT(WGM12) | BIT(CS10);
|
||||
TCCR2 = BIT(WGM20) | BIT(WGM21) | BIT(COM21) | BIT(CS20);
|
||||
|
||||
// PD4 OC1B (Timer/Counter1 Output CompareB Match Output)
|
||||
OCR1A = 51; // Minimum speed for Noctua fans at 20% PWM
|
||||
|
||||
// PD5 OC1A (Timer/Counter1 Output CompareA Match Output)
|
||||
OCR1B = 51; // Minimum speed for Noctua fans at 20% PWM
|
||||
|
||||
// PD7 OC2 (Timer/Counter2 Output Compare Match Output)
|
||||
OCR2 = 0; // XXX: Set heater low to turn off?
|
||||
|
||||
// TODO: Update documentation below from ATMega32A sheet...
|
||||
// Had to skip the TCR0 timer and use TCR1 and TCR2 instead.
|
||||
|
||||
// TCCR0 8-bit Timer/Counter Register
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
||||
|
||||
// Waveform Generation Mode Bit
|
||||
// Mode WGM01 WGM00 Counter Mode
|
||||
// 0 0 0 Normal
|
||||
// 1 0 1 PWM Phase Correct
|
||||
// 2 1 0 CTC
|
||||
// 3 1 1 PWM Fast
|
||||
|
||||
// Compare Output Mode, Fast PWM Mode
|
||||
// COM01 COM00 Description
|
||||
// 0 0 Normal port operation, OC0 disconnected.
|
||||
// 0 1 Reserved.
|
||||
// 1 0 Clear OC0 on match, set OC0 at BOTTOM, (non-inverting mode).
|
||||
// 1 1 Set OC0 on match, clear OC0 at BOTTOM, (inverting mode).
|
||||
|
||||
// Compare Output Mode, Phase Correct PWM Mode
|
||||
// COM01 COM00 Description
|
||||
// 0 0 Normal port operation, OC0 disconnected.
|
||||
// 0 1 Reserved.
|
||||
// 1 0 Clear OC0 on match when up-counting, set when downcounting.
|
||||
// 1 1 Set OC0 on match when up-counting, clear when downcounting.
|
||||
|
||||
// Clock Select Bit
|
||||
// CS02 CS01 CS00 Description
|
||||
// 0 0 0 No clock source (Timer/Counter stopped).
|
||||
// 0 0 1 clk I/O 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 source on T0 pin. Clock on falling edge.
|
||||
// 1 1 1 External clock source on T0 pin. Clock on rising edge.
|
||||
}
|
||||
|
||||
static void SetFan01Speed(int n)
|
||||
{
|
||||
n = CLAMP(n, 0xFF, FAN_01_MIN_DUTY);
|
||||
Info("Setting FAN01 to PWM %d.", n);
|
||||
|
||||
OCR1B = (unsigned char) n; // PD4
|
||||
}
|
||||
|
||||
static void SetFan02Speed(int n)
|
||||
{
|
||||
n = CLAMP(n, 0xFF, FAN_02_MIN_DUTY);
|
||||
Info("Setting FAN02 to PWM %d.", n);
|
||||
|
||||
OCR1A = (unsigned char) n; // PD5
|
||||
}
|
||||
|
||||
static void SetHeaterTemp(int n)
|
||||
{
|
||||
n = CLAMP(n, 0xFF, HEATER_MIN_DUTY);
|
||||
Info("Setting HEATER to PWM %d.", n);
|
||||
|
||||
OCR2 = (unsigned char) n; // PD7
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user