megaAVR 0-series Main Clock and SCL

Go To Last Post
45 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EDIT: This issue now seems to come down to a main clock problem; see further discussion for more info. 

 

Hello all,

 

I'm trying to become familiar with the workings of the TWI peripheral on my ATmega4808, but am confused with regards to the SCL frequency.

 

In order to set the Fscl, one needs to program a value into the TWI.MBAUD register, according to the following formula (megaAVR 0-series Family Datasheet, p352):

 

Fscl = Fclk_per / (10 + 2*BAUD + Fclk_er * Trise)

 

I am running the mega on 20MHz without prescaler to Fclk_per, so Fclk_per is 20MHz, or 20,000,000. 

VDD is 5V and slew rate is disabled, so, according to the mega-AVR 0-series 32-pin Data sheet (p17), the Trise is 1.5ns, or 0.0000000015s.

To get Fscl ~400kHz, we program a MBAUD value of 20 (20,000,000/(10+(2*20)+(20,000,000*0.0000000015)) = 399,760)

 

Unfortunately, using pulseview, I read not only an Fscl much lower than that (~60kHz), bu also one that is inconsistent once I drop the MBAUD value below 15. And seeing as I would need a Baud value of 5 to get ~1MHz Fscl for “Fast Mode+”, that is a problem.

 

I have no load connected to the SDA and SCL lines other than the logic analyzer.

You can find my code below. Note that this is purely to test the Fscl. It is bare, and I know that in real applications I should check bus states and flags in my functions, but I have ommitted as much as I could to hone in on the problem. 

/*
 * TWI SCL Test.c
 *
 * Created: 11/08/2019 13:26:48
 * Author : marti_k
 */ 

#include <avr/io.h>

void TWI_Initialize(void);
void TWI_Enable();
void TWI_Start(uint8_t addr);

int main(void)
{
    // Set Main Clock to 20MHz internal oscillator
    CCP = 0xD8;
    CLKCTRL.MCLKCTRLA = 0x0;
    // Disable Main Clock Prescaler (i.e. Fclk_main = Fclk_per)
    CCP = 0xD8;
    CLKCTRL.MCLKCTRLB = 0x0;
    
    TWI_Initialize();
    TWI_Enable();
    TWI_Start(0x78);
}

void TWI_Initialize(void)
{
    // Configure port C for TWI master
    PORTMUX.TWISPIROUTEA |= 1 << PORTMUX_TWI01_bp;
    // Set Master Baud rate
    TWI0.MBAUD = 20;
    // Reset TWI Master (clear MDATA and MADDR register)
    TWI0.MCTRLB |= TWI_FLUSH_bm;
    // Set Fast Mode+ (up to 1MHz Fscl)
    TWI0.CTRLA |= 1 << TWI_FMPEN_bp;
    // Clear interrupt flags
    TWI0.MSTATUS |= (1 << TWI_RIF_bp | 1 << TWI_WIF_bp);
}

void TWI_Enable()
{
    // Enable TWI Master
    TWI0.MCTRLA = 1 << TWI_ENABLE_bp;
    // Set bus state to idle
    TWI0.MSTATUS |= 1 << TWI_BUSSTATE0_bp;
}
void TWI_Start(uint8_t address)
{
    // Send address to SDA line
    TWI0.MADDR = address;
}

Here is a screenshot of PulseView using MBAUD 20:

 

PulseView1

 

I hope someone can give me some insight as to what it is I'm missing.

 

Kind regards,

 

Martin

Last Edited: Mon. Aug 12, 2019 - 09:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JustSomeNickname wrote:

 // Set Main Clock to 20MHz internal oscillator
    CCP = 0xD8;
    CLKCTRL.MCLKCTRLA = 0x0;

 

9.3.5 Configuration Change Protection
This peripheral has registers that are under Configuration Change Protection (CCP). In order to write to
these, a certain key must be written to the CPU.CCP register first, followed by a write access to the
protected bits within four CPU instructions.
It is possible to try writing to these registers at any time, but the values are not altered.

 

JustSomeNickname wrote:
I read not only an Fscl much lower than that (~60kHz),

 

60KHz is close to 1/6th of the 400KHz you want.

The default clock scaler is 6.  Are you really changing that to 1?

 

Verify that the Fclk_per is actually 20MHz by blinking a LED once per second and timing the blinks.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Motivated by your post, I'm now reading the system clock (CLK_PER) from PA7 with the logic analyzer. The CLKOUT bit, - used to enable or disable clock output to pin PA7 - is also located in one of the protected registers (CLKCTRL.MCLKCTRLA), and I'm using the same method for changing it (writing 0xD8 to CPU CCP register - see megaAVR 0-series Family Datasheet, p64):

 

	// Enable CLKOUT pin
	CCP = 0xD8;
	CLKCTRL.MCLKCTRLA |= 1 << CLKCTRL_CLKOUT_bp;

I have put in an extra test to verify that this method works by disabling and enabling it a few times and using PulseView to check if the change is actually put through. It works.

 

Strange thing is that if I disable the main clock prescaler with:

 

	// Disable Main Clock Prescaler
	CCP = 0xD8;
	CLKCTRL.MCLKCTRLB &= ~(CLKCTRL_PEN_bm);

I read an output of 4MHz. Although not consistently; some cycles are 4.8MHz

 

If, on the other hand, I enable the prescaler and set division to 2 using:

 

	// Enable Main Clock Prescaler
	CCP = 0xD8;
	CLKCTRL.MCLKCTRLB |= CLKCTRL_PEN_bm;

	// Set prescaler
	CCP = 0xD8;
	CLKCTRL.MCLKCTRLB = (CLKCTRL_MCLKCTRLB & ~CLKCTRL_PDIV_gm) | CLKCTRL_PDIV_2X_gc;

I get a PulseView reading that is also inconsistent, reading either 8MHz clock cycles or 12MHz clock cycles, with no discernable pattern. 

 

 

I'm getting more and more confused.

 

S.O.S. smiley

Last Edited: Mon. Aug 12, 2019 - 08:04 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What board are you using?

Purchased board or home made breadboard or PCB?

 

If home made, show a schematic - at least a partial one showing power and ground connections.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I haven't yet worked with schematic software or practiced drawing up schematics at all, so I hope that these images provide enough information. If not, I will need some more time to figure out how to draw schematics. 

 

Setup 1Setup 2

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I now at once see a problem with my bypass capacitors. I have repositioned them to sit between VDD and GND rather than VDD and VDD. 

No change in Main Clock readings.

Last Edited: Mon. Aug 12, 2019 - 08:21 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fixed it for you.

I now at once see a problem with my missing 100nF bypass capacitors.

The 100nF caps should be connected at the uC pins.

 

Also, I can't tell if you have power connected to AVcc.

 

A simple hand drawn schematic showing power and ground connections

with bypass caps will suffice.

Last Edited: Mon. Aug 12, 2019 - 08:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Missing from where? Should they be added to the current ones? Or replace them? Or connected to different pins entirely?

AVcc is connected.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JustSomeNickname wrote:

Missing from where? Should they be added to the current ones? Or replace them? Or connected to different pins entirely?

AVcc is connected.

 

What current ones?  The photo shows only two large electrolytic caps.

 

Also, from the datasheet, AVdd is on pin 18 of the uC.  I don't see any 

connection to pin 18 in the photo.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Those 100uF electrolytic caps do not work as bypass capacitors? The smalles value I have is 1uF. Replacing the 100uF ones with 1uF ones seems to have no effect. 

 

About the AVdd: there is a yellow wire running from pin 18 'rail' to the power rail. I am not sure whether you have missed it, or if you are suggesting that it is in some way an inappropriate connection.

 

 

Last Edited: Mon. Aug 12, 2019 - 09:29 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Update: if I enable main clock prescaler, and set the division to 10, I get a (fairly) consistent reading of 2MHz on CLKOUT pin (Sampling some readings, I found 3 anomalies, which were not far off and I guess should be fine)

This is expected behaviour, for 20MHz / 10 is obviously 2MHz. 

 

It is baffling to me how disabled prescaler results in 4MHz, and division 10 prescaler results in 2MHz. 

 

For clarification, my entire code has now been reduced to:

 

#include <avr/io.h>

int main(void)
{
    //Set Main Clock to 20MHz internal oscillator
    CCP = 0xD8;
    CLKCTRL.MCLKCTRLA &= ~(CLKCTRL_CLKSEL_gm);
    
    // Main Clock Prescaler
    CCP = 0xD8;
    //CLKCTRL.MCLKCTRLB &= ~(CLKCTRL_PEN_bm);        // Disabled
    CLKCTRL.MCLKCTRLB |= CLKCTRL_PEN_bm;            // Enabled
    
    // Set prescaler
    CCP = 0xD8;
    CLKCTRL.MCLKCTRLB = (CLKCTRL_MCLKCTRLB & ~CLKCTRL_PDIV_gm) | CLKCTRL_PDIV_10X_gc;    // Division 10

    // Enable CLKOUT pin
    CCP = 0xD8;
    CLKCTRL.MCLKCTRLA |= 1 << CLKCTRL_CLKOUT_bp;
}

 

Last Edited: Mon. Aug 12, 2019 - 10:15 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Update:

Divion 4 gives me relatively consistent reading of 4.8MHz. Not entirely expected behaviour, and at first glance I notice more deviating cycles than with division 10, but it's relatively close. 

Division 2 gives me readings of 8MHz and 12MHz cycles, which seem to follow no pattern, but would appear to be divided about 50/50. So on average that would be 10MHz. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
 CCP = 0xD8;
 CLKCTRL.MCLKCTRLA &= ~(CLKCTRL_CLKSEL_gm);

You cannot reliably do &= or |= on these registers that have protection. You can view the asm source and prove me wrong, but I assume you get a LDS (2cycle), ANDI (1), STS (2)- that's 5 cycles. It needs to be done in 4.

If you need to preserve bits, then get a copy to work on-

uint8_t tmp = CLKCTRL.MCLKCTRLA;
tmp &= ~(CLKCTRL_CLKSEL_gm);
CCP = 0xD8
CLKCTRL.MCLKCTRLA = tmp;

 

You also have what looks like a nice debugger. Use it. If you step through you code, you can see the register values. If something is not getting set as you think it should, there is most likely a problem in your code, or how you reading the datasheet. Or you can put a breakpoint somewhere after your clock setup code, then check out the various registers to see if they are correct. This is probably one of the better uses for a debugger- simply looking at registers to see how they square up with the datasheet, how to set bits properly, how they react to different situations, etc.

Last Edited: Mon. Aug 12, 2019 - 10:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is very educational for me, curtvm. Thank you. I will certainly look into the ASM and learn how to use the debugger (never debugged code before, so I'll have to learn how to do it). In fact, I will get started with that today. 

 

Meanwhile, in response to your comment, I have shortened my code yet again to the following:

 

#include <avr/io.h>

int main(void)
{
	// Set Main Clock to 20MHz internal oscillator & Enable CLKOUT
	CCP = 0xD8;
	CLKCTRL.MCLKCTRLA = 0x80; // Set CLKOUT bit and clear all others

	// Main Clock Prescaler
	CCP = 0xD8;
	CLKCTRL.MCLKCTRLB = 0x0;	// Disable prescaler
}

This should negate the previous issues with reliability of &= and |= commands used on protected registers. Yet, there is no change in the results; I'm still reading 4MHz with PulseView. 

 

Again, I will figure out how to use the debugging function, and see what I find. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

JustSomeNickname wrote:

Those 100uF electrolytic caps do not work as bypass capacitors? The smalles value I have is 1uF. Replacing the 100uF ones with 1uF ones seems to have no effect. 

 

About the AVdd: there is a yellow wire running from pin 18 'rail' to the power rail. I am not sure whether you have missed it, or if you are suggesting that it is in some way an inappropriate connection.

 

 

 

Well, not really. You should use much smaller caps (normally 100nF ceramic), placed much closer to the chip, i. e. soldered to the leads.

 

 

In your case, surface mount caps would probably be better, try to solder them directly to the same solder pads that connect to VDD and GND. The electrolytic caps don't hurt either, you don't need to remove them. It's better to have both: the electrolytics filter noise from the supply, while the decoupling caps filter high frequency noise generated by the chip.

 

Edit: normally you only need to put the supply filter caps near the connections to the power supply.

Last Edited: Mon. Aug 12, 2019 - 10:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for the information, El Tangas. I will order some SMD caps online and solder them directly to the pads. 

 

Could it be, though, that in this situation, wrong kind/value caps are the cause of 4MHz clock readings where 20MHz is expected?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JustSomeNickname wrote:
Could it be, though, that in this situation, wrong kind/value caps are the cause of 4MHz clock readings where 20MHz is expected?

 

Probably not. But I see a problem in your code when you do things like this:

 

	// Enable Main Clock Prescaler
	CCP = 0xD8;
	CLKCTRL.MCLKCTRLB |= CLKCTRL_PEN_bm;

 

The |= operation probably implies read/modify/write and the write may happen after the effect of protection unlock has expired. You should look at assembly output to make sure the write happens within 4 instructions.

 

edit: I would avoid stuff like "|=" and "&=" altogether on protected registers and use only plain "=".

Last Edited: Mon. Aug 12, 2019 - 11:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you using AS7 ? what device pack you have ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

edit: I would avoid stuff like "|=" and "&=" altogether on protected registers and use only plain "=".

 

curtvm suggested the same, and that is something I've now learned for good. I simplified my code to:

 

#include <avr/io.h>

int main(void)
{
	// Set Main Clock to 20MHz internal oscillator & Enable CLKOUT
	CCP = 0xD8;
	CLKCTRL.MCLKCTRLA = 0x80;       // Set CLKOUT bit and clear all others

	// Main Clock Prescaler
	CCP = 0xD8;
	CLKCTRL.MCLKCTRLB = 0x0;	// Disable prescaler
}

And still I'm reading 4MHz on CLKOUT. 

 

Moe123 wrote:

Are you using AS7 ? what device pack you have ?

 

I'm using AS 7.0.1931 with ATmega4808. I am uncertain about what you mean by "device pack". If you could tell me where to find this information, I will gladly supply it.

Last Edited: Mon. Aug 12, 2019 - 11:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

device packs are device "support" or a HAL abstraction layer "you can call it", so you dont need to do something like:

 

CCP = 0xD8;

but rather something more simple, like :

 

ccp_write_io((void *)&(CLKCTRL.MCLKCTRLB),
	CLKCTRL_PDIV_4X_gc /* prescaler 4 */
	| 0 << CLKCTRL_PEN_bp /* Prescaler enable: disabled */);

in AS7, you can go to Tools -> Device Pack manager. and then check for updates.

 

alternatively, you can check for the latest device packs in:

http://packs.download.atmel.com/

Last Edited: Mon. Aug 12, 2019 - 11:50 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

you can also download the latest packs from:

 

https://packs.download.microchip...

 

now, what is the difference between the atmel packs and the microchip packs in Atmega4808 is a mystery for me!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I installed every update available just to be sure, though the only pack relevant to me seems to be the ATmega_DFP. I searched for "4808" in the manager and installed one more "part" of the ATmega_DFP pack that came up and wasn't already installed. Restarted AS, but still no effect. 

 

If I try to use the ccp_write_io function, I get the implicit declaration error. On Google, I cannot find if there is a library that I need to include in order to use this function. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

well, to make it in a more simple way, you may use Atmel Start, configure some pins...and then you will have everything automatically there for you...I dont suggest using Atmel start...but its just a beginning.

 

as for your question, for using the "ccp_write_io" you need to include the header

#include <ccp.h>

this ccp_write_io, is:

 

static inline void ccp_write_io(void *addr, uint8_t value)
{
  protected_write_io(addr, CCP_IOREG_gc, value);
}

 

Last Edited: Mon. Aug 12, 2019 - 12:18 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is another piece of useful info- your logic analyzer will be lying to you if you don't have it set to sample fast enough. Trying to get a good reading on a 20Mhz clock when sample rate is 200khz, just will not work. Maybe you already have that sorted out, but your initial photo of pulseview shows a 200khz sample rate it looks to me.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Keen observation, curtvm. But as you already guessed, I increased the sample rate to 24MHz when trying to read 20MHz clock. 

Last Edited: Mon. Aug 12, 2019 - 12:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JustSomeNickname wrote:
And still I'm reading 4MHz on CLKOUT. 

 

Did you configure the CLKOUT pin as output? I know the mega AVR-0 chips do this automatically for many peripherals, but I'm not sure about CLKOUT.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

Did you configure the CLKOUT pin as output? I know the mega AVR-0 chips do this automatically for many peripherals, but I'm not sure about CLKOUT.

 

I had not done that. Did it now and had no effect. Good reminder though! And confirmation that the chip had already done this itself. 

 

Interesting side-note: even if I add "PORTA.OUTCLR |= 1<<7" to the end of my code, the readings on the pin are still the same. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess I'm out of ideas, then. If you post your test code, I can try to run it, I have some mega AVR-0 chips (probably only tomorrow).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

I guess I'm out of ideas, then. If you post your test code, I can try to run it, I have some mega AVR-0 chips (probably only tomorrow).

 

#include <avr/io.h>

int main(void)
{
	// Set Main Clock to 20MHz internal oscillator & Enable CLKOUT
	CCP = 0xD8;
	CLKCTRL.MCLKCTRLA = 0x80;	// Set CLKOUT bit and clear all others
	
	// Disable prescaler
	CCP = 0xD8;
	CLKCTRL.MCLKCTRLB = 0x0;	// Clear all bits in register
}

I would appreciate it very much. 

 

For now, I'm going to program the Timer/Counter to blink an LED and see if I can predict the frequency. In that way I can determine if the problem lies with the frequency of the clock, or the reading of it on PA7.

Also, I'll learn about debugging and some ASM. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have a pull-up resistors on SCL and SDA ?

 

EDIT: also what pins are you using for TWI ?

Last Edited: Mon. Aug 12, 2019 - 01:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Moe123 wrote:

Do you have a pull-up resistors on SCL and SDA ?

 

 

EDIT: also what pins are you using for TWI ?

 

I had them when I was testing TWI, yes. Now I'm just testing the main clock on CLKOUT without any TWI interfacing, and am not using any pull-up resistors. 

 

EDIT: I was using PC2 for SDA and PC3 for SCL, using "PORTMUX.TWISPIROUTEA |= PORTMUX_TWI0_ALT2_gc;" to configure them as such. 

Last Edited: Mon. Aug 12, 2019 - 01:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, could you please post your schematic... a sketch or anything that shows your setting.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Honestly, I don’t even know where to begin drawing up a sketch like that. But seeing as this is the second request for said sketch, I made an attempt. Though I hardly believe it will be of use to you.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, thanks for the pic. So, here is the thing, when we say a sketch, we dont mean a block diagram...we mean a sketch that contains the electronics components, mcu...caps...resistors...etc.

 

we said a sketch because we suppose you dont have a schematic.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does this help?

Resistors are 4k7, caps 1uF.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have a schematic ? yes/no ? I cant understand your PCB like this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do not. And if I need to provide one, I first need to learn how to draw one up. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

then please take a look at this application note:

 

http://ww1.microchip.com/downloa...

pay special attention to decoupling capacitors...how they are connected..etc

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will study the application note when I get off work. Thank you Moe123. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


in page 19, you can take a look at the basic hardware for Atmega4808 schematic:

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>I increased the sample rate to 24MHz when trying to read 20MHz clock. 

 

Probably not enough. There are also other settings you may have to adjust- threshold levels, etc.

 

I have a DSLogic hooked up to a mega4809, and just tried various clkout settings. Unless I have it sample at 100MHz, the 20MHz clkout is not reading very accurate or stable. I also had to lower the threshold level a bit or would get nothing at 20MHz. I don't have a scope, but I imagine clkout doesn't look like a nice rail-to-rail perfect square wave and gets worse as speed increases.

 

 

I have my own code to set clock freq, etc-

Clkctrl::clk_sel( 10000000 ); //uses fuse setting at compile time to figure out what to do get that (or next lower if unable)

Clkctr::out( true );

 

but I also tried your code above, and it works ok and the produced asm shows no surprises. The protected writes are really not that hard to pull off unless you are doing and/or ops without a temp copy. If you keep the two write operations consecutive and don't have some macros in use that may hide what is happening, it is probably hard to fail unless using -O0 which should never be used.

 

Last Edited: Mon. Aug 12, 2019 - 02:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JustSomeNickname wrote:
But as you already guessed, I increased the sample rate to 24MHz when trying to read 20MHz clock. 

 

Ah, ok this explains it. You need to sample at least at 2x the sampled frequency (Nyquist theorem) in your case 40MHz, or else you have aliasing at a frequency you can calculate: https://sciencing.com/calculate-...

 

It so happens that sampling a 20MHz signal @24MHz sample rate, aliases to 4MHz, as you observe (24-20 = 4).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for taking the time to try the code curtvm.

 

I just set up the Timer/Counter to flash an LED at a frequency of 1Hz, assuming CLK_PER of 20MHz, after disabling the CLK_MAIN prescaler in the same manner as discussed above. It works just as expected. This tells me that the prescaler and main clock settings are fine, but the Logic Analyzer is displaying unreliable readings. 

 

I'm going to go back to my TWI code and try some things again. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

Ah, ok this explains it. You need to sample at least at 2x the sampled frequency (Nyquist theorem) in your case 40MHz, or else you have aliasing at a frequency you can calculate: https://sciencing.com/calculate-...

 

It so happens that sampling a 20MHz signal @24MHz sample rate, aliases to 4MHz, as you observe (24-20 = 4).

 

Very educative! I have much to read and learn based on this thread. Thank you very much for your input!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

El Tangas wrote:

JustSomeNickname wrote:
But as you already guessed, I increased the sample rate to 24MHz when trying to read 20MHz clock. 

 

Ah, ok this explains it. You need to sample at least at 2x the sampled frequency (Nyquist theorem) in your case 40MHz, or else you have aliasing at a frequency you can calculate: https://sciencing.com/calculate-...

 

It so happens that sampling a 20MHz signal @24MHz sample rate, aliases to 4MHz, as you observe (24-20 = 4).

 

@OP

For fun, take some graph paper and draw a 20MHz square wave. Now draw a 24MHz square wave below it. Below that draw the result of sampling the 20MHz waveform every time the 24MHz waveform goes from low to high. Now join the dots of your new waveform and see what you get.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss