With an Arduino Nano it is possible to get a 8 MHz clock signal on pin 9:
void setup ()
{
// set up 8 MHz timer on pin 9 (OC1A)
pinMode (9, OUTPUT);
// set up Timer 1
TCCR1A = bit (COM1A0); // toggle OC1A on Compare Match
TCCR1B = bit (WGM12) | bit (CS10); // CTC, no prescaling
OCR1A = 0; // output every cycle
} // end of setup
void loop ()
{
// whatever
} // end of loop
I am trying to achieve the same thing on a Nano Every. I have adjusted the PWM example in "getting started with TCB" and so far, I have succeeded in getting 4 MHz (see code below). I am quite proud since I am a beginner and I have just started to learn about timers, registers, ports, prescalers, etc.
Is using TCB in PWM mode the way to go or is there a better way? Is it possible to get a higher frequency out of it? I don't want to mess with the millis() function, I think I should use TCB1 or TCB0?
#include <avr/io.h>
#define TCB_CMP_EXAMPLE_VALUE (0x0101) // I adjusted this value to get the highest possible PWM frequency
void CLOCK_init (void);
void PORT_init (void);
void TCB3_init (void);
void CLOCK_init (void) {
CPU_CCP = CCP_IOREG_gc; /* Enable writing to protected register */
CLKCTRL.MCLKCTRLB = CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm; // I used 2X prescaler in stead of 64
CPU_CCP = CCP_IOREG_gc; /* Enable writing to protected register */
CLKCTRL.MCLKCTRLA = CLKCTRL_CLKSEL_OSC20M_gc; // I Selected OSC20M in stead of OSCULP32K
while (CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm) /* Wait for system oscillator changing to finish */
{ ; }
}
void PORT_init (void) {
PORTB_DIR |= PIN5_bm;
PORTB_OUT |= PIN5_bm;
}
void TCB3_init (void) {
TCB3.CCMP = TCB_CMP_EXAMPLE_VALUE; /* Load CCMP register with the period and duty cycle of the PWM */
TCB3.CTRLA |= TCB_ENABLE_bm; /* Enable TCB3 and Divide CLK_PER by 2 */
// TCB3.CTRLA |= TCB_CLKSEL_CLKDIV2_gc; // I removed this line as it slows things down
TCB3.CTRLB |= TCB_CCMPEN_bm; /* Enable Pin Output and configure TCB in 8-bit PWM mode */
TCB3.CTRLB |= TCB_CNTMODE_PWM8_gc;
}
int main(void) {
CLOCK_init();
PORT_init();
TCB3_init();
while(1) {}
}
with the ATmega4809 TCB is actually not the right timer for something like this. You can use the 8Bit PWM or maybe the TimeOut mode. Furthermore every TCBn has a specific WO pin. You can't just mix them. For that you need the manual.
The Nano Every Board has the following pinout.
TCB3 would have as WO pin PB5 or PC1. Both are not led out on the Nano Every board.
TCB2 would have pin PC0 or PB4 as WO. Both are not led out on the Nano Every Board.
TCB1 has pin PA3 or PF5 as WO. PF5 is led out on the Nano Every Board.
TCB0 has pin PA2 or PF4 as WO. PF4 is led out on the Nano Every Board.
We take TCB0 with WO PF4. This is Arduino pin 6. The WO portmux is not affected by the timer registers. That is done in another register. The 16 bit compare register splits into MSB and LSB 8bit.
MSB is the pulse width.
LSB is the frequency.
The setting 1 + 1 -> 0x0101 produces the highest possible frequency with Duty Cycle 50% with 8MHz.
For me it looks like this.
/*
Doc_Arduino - german Arduino Forum
Arduino IDE v1.8.13
Arduino Nano Every
13.04.2021
TCBn as 8 Bit PWM
License: GNU GPLv3
*/
#include <NanoEveryPin.h>
#include <megaAVR0TCBn.h>
OutputPin <6> pinPWM; // PF4
TCB <0> timerTCB0;
void setup (void)
{
initPins();
initTCB0();
}
void loop (void)
{
}
void initPins (void)
{
pinPWM.init();
}
void initTCB0 (void)
{
timerTCB0.reset();
timerTCB0.setCLKDIV1();
timerTCB0.setModePWM8();
timerTCB0.enableCCMPEN();
timerTCB0.setCompare(0x0101); // MSB Duty Cycle / LSB Periode
timerTCB0.enable();
}
Thank you for your reply. I was not able to login to the new forum because something was wrong with my account. It is finally solved now.
I took a look at your libraries, they look quite impressive. However, I can not find any C-files so I could not see exactly how you do it. In the mean time I found some code to get a 8 MHz clock signal on pin D3 using TCB1 and PWM:
my lib is header only because of the class template. There is no .c file because of that. If something would be missing you could not compile the sketch. The bit definitions are the standard definitions from Microchip. They are always present for the controller. Search on your computer for a file named iom4809.h
The pinout as shown in #2 is Arduino standard. As long as you don't change anything in the portmux register it will stay like this. However, if you are programming bare metal, then you need to set it.
The same result would have been as follows. Everything remains basically as it is. Only the timer number at initialization changes from 0 to 1. The names are adjusted additionally. And of course change the output pin from D6 to D3.
Here is how to get 8MHz on pin A5 without using any timer counters at all! Instead you use the Configurable Custom Logic feature of the ATmega4809 microcontroller. CCL allows some simple gated registers to be generated on chip. In this case we create a type D flip-flop, ~Q connected to D and clocked by the system (16MHz clock).
void setup() {
// LUT0 is the D input, which is connected to the flipflop output
CCL.LUT0CTRLB = CCL_INSEL0_FEEDBACK_gc; // Input from sequencer
CCL.TRUTH0 = 1; // Invert the input
CCL.SEQCTRL0 = CCL_SEQSEL0_DFF_gc; // D flipflop
// The following line configures using the system clock, OUTEN, and ENABLE
CCL.LUT0CTRLA = CCL_OUTEN_bm | CCL_ENABLE_bm;
// LUT1 is the D flipflop G input, which is always high
CCL.TRUTH1 = 0xff;
CCL.LUT1CTRLA = CCL_ENABLE_bm; // Turn on LUT1
CCL.CTRLA = 1; // Enable the CCL
}
void loop() {
}
@Doc_Arduino: I had been staring for quite some time over those "getting started" files, but for a beginner it is not that simple. Your link works, but many of the links on your link don't. For instance, the CCL link does not work...
@almytom: Thanks, that is good to know. But for my current project, I need my 8MHz pulse to be on pin D3. I assume that it is not possible to get it on D3 with that CCL method?
Sorry, the CCL would put it on A5 or A0. The Event System would allow routing the CCL output to A4, D5, A1, or D13. That's six pins, but unfortunately D3 is not among them. Why must D3 be used?
I can imagine that it slays you with all the information at first. But the Getting Started Manuals help, because they focus only on one specific feature.
All links work for me.
You go to the documents tab on the Microship page. Here you can see the many .pdf manuals. Then you click on the first app note "... with CCL". Land on the next page, move your mouse to the right and click on the .pdf icon next to Size. Either that opens in the browser or you download it.
If the links really don't work for you, for whatever reason, you can go directly to Github if necessary. GitHub App Notes
Revised table for faster overview. The formatting is not 100% correct.
@Doc_Arduino OK, from the documents tab, the links work.
@almytom I need it on D3 because the hardware is largely finished. I started this project on an Arduino Nano v3, but my program is becoming too big (too many global variables) so I want to change to a Nano Every which has more SRAM.
But like I said, I managed to get a 8MHz pulse on D3, so my problem is solved.