Trying to turn multiple outputs on simultaneously at a specific PWM duty cycle and frequency (31kHz) . I've managed to achieve this with timer TCB0 for pin D6:
if the pins are present on the Nano Every or if you re-route them, you are welcome to try the code.
Is tested with the ATmega4809 Curiosity Nano Board.
Replace the function "atmel_start_init" with your own config.
It contains the setting of the CPU clock (not applicable for the Arduino) and the setting of the pins to output.
#include <avr/io.h>
#include <atmel_start.h>
void Port_Init(void);
void TCA0_HardReset(void);
void TCA0_SplitMode_Init (void);
uint8_t low_TCA_Frequenz = 88;
uint8_t low_TCA_DutyCycle = 88;
uint8_t high_TCA_Frequenz = 199;
uint8_t high_TCA_DutyCycle = 199;
int main(void)
{
atmel_start_init(); // Initializes MCU, drivers and middleware
TCA0_HardReset();
Port_Init();
TCA0_SplitMode_Init();
while (1)
{
}
}
void TCA0_SplitMode_Init (void)
{
PORTMUX.TCAROUTEA = PORTMUX_TCA0_PORTA_gc; // set waveform output default PORT.A, Manual 14.2
TCA0.SPLIT.CTRLD = TCA_SPLIT_SPLITM_bm; // enable split mode
TCA0.SPLIT.CTRLB |= TCA_SPLIT_LCMP0EN_bm; // PA0, enable compare channel 0 for the lower byte, Datasheet 4.1
TCA0.SPLIT.CTRLB |= TCA_SPLIT_LCMP1EN_bm; // PA1, enable compare channel 1
TCA0.SPLIT.CTRLB |= TCA_SPLIT_LCMP2EN_bm; // PA2, enable compare channel 2
TCA0.SPLIT.CTRLB |= TCA_SPLIT_HCMP0EN_bm; // PA3, enable compare channel 0 for the higher byte
TCA0.SPLIT.CTRLB |= TCA_SPLIT_HCMP1EN_bm; // PA4, enable compare channel 1
TCA0.SPLIT.CTRLB |= TCA_SPLIT_HCMP2EN_bm; // PA5, enable compare channel 2
TCA0.SPLIT.LPER = low_TCA_Frequenz; // set PWM Frequenz
TCA0.SPLIT.LCMP0 = low_TCA_DutyCycle/7*1; // set Duty Cycles
TCA0.SPLIT.LCMP1 = low_TCA_DutyCycle/7*2;
TCA0.SPLIT.LCMP2 = low_TCA_DutyCycle/7*3;
TCA0.SPLIT.HPER = high_TCA_Frequenz; // set PWM Frequenz
TCA0.SPLIT.HCMP0 = high_TCA_DutyCycle/7*4; // set Duty Cycles
TCA0.SPLIT.HCMP1 = high_TCA_DutyCycle/7*5;
TCA0.SPLIT.HCMP2 = high_TCA_DutyCycle/7*6;
TCA0.SPLIT.CTRLA = TCA_SPLIT_CLKSEL_DIV8_gc; // set Prescaler 8
TCA0.SPLIT.CTRLA |= TCA_SPLIT_ENABLE_bm; // start Timer
}
void Port_Init(void)
{
PORTA.DIR |= PIN0_bm; // set PA0 as output
PORTA.DIR |= PIN1_bm;
PORTA.DIR |= PIN2_bm;
PORTA.DIR |= PIN3_bm;
PORTA.DIR |= PIN4_bm;
PORTA.DIR |= PIN5_bm; // set PA5 as output
}
void TCA0_HardReset(void) // must be used when switching from single mode to split mode
{
TCA0.SINGLE.CTRLA &= ~(TCA_SINGLE_ENABLE_bm); // stop timer
TCA0.SINGLE.CTRLESET = TCA_SINGLE_CMD_RESET_gc; // force a hard reset
}