Frequency counter for Attiny3226 #991
-
Hello. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 15 replies
-
Connect the pin to an event channel as generator using EVSYS, set the TCB (probably TCB0, since we're defaulting TCB1 for millis?) as the event user, configure the TCB for input capture frequency measurement, figure out an appropriate clock source for the TCB. Assuming you're running at 20 MHz and do CLK_PER/2, that would get you a 0.1 us resolution (though the whole value would be off by... usually under 1% at room temp... because the oscillator speed isn't perfect (the notches from which the cal pretty much always picks the best of for operation at 25 C are 110-270 kHz apart, commonly a chip might be measured to have between 120kHz and 230kHz) and you can measure up to 2^16 - 65.5 milliseconds. |
Beta Was this translation helpful? Give feedback.
-
Thanks for reply. I build below codes. Please control it. #include <avr/io.h> // Define a variable to store the captured value void setup() { // Configure TCB0 as the event user for EVSYS_CH0 // Configure TCB0 for input capture mode // Set the appropriate clock source for TCB0 // Enable global interrupts void loop() { } // Capture interrupt service routine |
Beta Was this translation helpful? Give feedback.
-
Here is an example
|
Beta Was this translation helpful? Give feedback.
-
This was meant to be mosted yesterdaty Here's the part i don't get // Configure Pin as an Event Output (Generator) for EVSYS_CHMUX
PORTB.DIRSET = PIN0_bm; // Set PB0 as an output
PORTMUX.EVSYSROUTEA |= PORTMUX_EVOUT0_bm; // Route PB0 to Event Channel 0 Comment after third line is total nonsense, and makes no sense to me in the context of what you're trying to do. The EVSYS takes inputs from "Generators" that many peripherals have. You connect a generator to a channel - if you want to measure a signal coming in on PB0, you want PB0 selected as the generator. EVSYS.CHANNEL0 = EVSYS_CHANNEL0_PORTB_PIN0_gc; Yes, that is the channel number in the name of the group code. That's because these are pre-Ex-series parts. so the channels are non-fungible - 2 ports are available to each channel to act as generator - here for example channels 0-1 get ports A and B, channels 2-3 get C and A, and channels 4-5 get ports B and C. (note - the generator and user organization, if you ever have to work with a 1 series, is hellish. It's so bad. and the subtle deficiencies end up being sufficiently noticeable that they interfere with your ability to use the parts. There are in fact, prior to the EA-series, no two event channels on any single device that - were you to list their generators, no two channels would be identical. without knowing what generator was needed you could never say "I can use this channel or that channel" You could say that once you knew the generator needed, because depending on the part (as long as it's not a 0/1-series tiny, which are a warren of special cases and are impossible to speak coherently about because the designers were not thinking coherently yet), one of the following three cases will be applicable: It is neither a pin nor RTC generator -> any channel can be used. It is a pin. There are 2 (or 4 on the tiny2's) channels that can carry a given pin, with consecutive numbers. On tiny2, the channels have 3 ports and 6 channels each of which can handle 2 ports. so they did obvious thing - 0/1 gets A (0x40-47) and B (0x48-4F) 2/3 gets C and A, and 4/5 gets B and C. And after 1-series but before EA series, for all parts (DA-DD, unknown which side of the line the DU will be on, hopefully EA's side- consistent with the chronology, but the Dx and Ex parts seem to be based on different designs. And EVSYS.USERTCB0CAPT should be set to (channel number + 1) in order to use that channel as an event input. It's very important to keep straight event inputs and outputs, as the names don't always make it obvious which it is. The GENERATORS, that is, the output instead get names like EVSYS_CHANNEL#_PERIPHERAL_EVENTNAME_gc, and these are values that you write to the CHANNELn registers to connect the channel to that geneator. Each channel can connect to 1 generato The EVOUT stuff relates to having a pin change state based on the event channel. You want the opposite so it has no place here. |
Beta Was this translation helpful? Give feedback.
Then just work from the raw "timer_capture" value and create your own logic from there.
The demo I made uses integers and divisions, so is rounding anything down to whole numbers. Especially the calculation of "period" is losing a factor 20 of resolution.
Look at the "Timer capture" value when you slightly change your frequency and you will see it changing with much higher resolution than the frequency number.