AVR 0 series - Error setting TCA in split mode to give me interrupts - Page 1
Forum section: electronics / general

author: sanka1p
author_rank: Contributor
timestamp: October 18, 2023, 09:12:16 pm
content: Hi All, I am trying to use TCA in split mode to give me interrupts in LUNF and LCMP0 condition. I am using Atmega1608. My goal is not generate the PWM at the output but to give me interrupts when LUNF and LCMP0 condition occurs. I used the code attached below to generate the PWM, but when I wrote the ISR for LUNF and LCMP0 condition, it is giving me an error that "Called object is not a function or function pointer" while clearing the interrupt flag. Please let me know what wrong in the code. I am using Microchip studio.Code:#define F_CPU 20000000UL#include <avr/io.h>#include <util/delay.h>#include <avr/interrupt.h>#define PERIOD_EXAMPLE_VALUE_L (200) // 48.5hz#define PERIOD_EXAMPLE_VALUE_H (255) // 38.14hz#define DUTY_CYCLE_EXAMPLE_VALUE_L (100) //50% duty cycle#define DUTY_CYCLE_EXAMPLE_VALUE_H (128) //50% duty cyclevoid TCA0_init(void);void PIN_init(void);ISR(TCA0_LCMP0_vect){TCA0.SPLIT.INTFLAGS= TCA_SPLIT_LCMP0_bm /* Clear the interrupt flag */PORTA.OUTSET|= PIN6_bm; /* Toggle PA6 GPIO */}ISR(TCA0_LUNF_vect){TCA0.SPLIT.INTFLAGS= 1<<4 /* Clear the interrupt flag */PORTA.OUTCLR|= PIN6_bm; /* Toggle PA6 GPIO */}void TCA0_init(void){/* set waveform output on PORT A */PORTMUX.TCAROUTEA = PORTMUX_TCA0_PORTA_gc;/* enable split mode */TCA0.SPLIT.CTRLD = TCA_SPLIT_SPLITM_bm;TCA0.SPLIT.CTRLB = TCA_SPLIT_HCMP0EN_bm /* enable compare channel 0 for the higher byte */| TCA_SPLIT_LCMP0EN_bm; /* enable compare channel 0 for the lower byte */TCA0.SPLIT.INTCTRL= TCA_SPLIT_LCMP0_bm | TCA_SPLIT_LUNF_bm;/* set the PWM frequencies and duty cycles */TCA0.SPLIT.LPER = PERIOD_EXAMPLE_VALUE_L;TCA0.SPLIT.LCMP0 = DUTY_CYCLE_EXAMPLE_VALUE_L;TCA0.SPLIT.HPER = PERIOD_EXAMPLE_VALUE_H;TCA0.SPLIT.HCMP0 = DUTY_CYCLE_EXAMPLE_VALUE_H;TCA0.SPLIT.CTRLA = TCA_SPLIT_CLKSEL_DIV1024_gc /* set clock source (sys_clk/1024) */| TCA_SPLIT_ENABLE_bm; /* start timer */}void PIN_init(void){PORTA.DIR |= PIN6_bm| PIN0_bm /* set pin 0 of PORT A as output */| PIN3_bm| PIN4_bm; /* set pin 3 of PORT A as output */}int main(void){_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm); // 10Mhz clk_perPIN_init();TCA0_init();sei();while (1){}}

author: cv007
author_rank: Frequent Contributor
timestamp: October 19, 2023, 06:50:26 am
content: Missing semicolons will cause various errors. You are missing a couple, and the error message(s) will at least point to where you need to look.Since I'm here, may as well comment on your use of the port-PORTA.OUTSET|= PIN6_bm;PORTA.OUTCLR|= PIN6_bm;Any use of set/clr/tgl for the port peripheral should only be assignment (=). The purpose of the set/clr/tgl registers is to make any pin manipulation atomic, and you lose that by using anything other than = (whether it matters or not may vary). In the case of the OUTCLR usage above, by using |= you are also clearing any other OUT bits on the same port that happen to be currently set. In the case of OUTSET usage above, it may at first appear it would be harmless since it would be setting the port OUT bits that are already set (in addition to the intended bit), but by using |= you have lost atomicity and may end up setting a (now) cleared bit if an interrupt occurred in the process.