Timer accuracy error

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

Hi,

 

I am running my Atxmega128A4U with a 16MHz crystal, creating a 128MHz PLL (CLK/4) and a 32MHz cpu clock. I try to generate with the hires unit a waveform on PORTE Pin3 (CCD). I am using the TCE0 Timer with the CCD Pin.

As you can see the clock is not very precise. Using the CCA pin it works perfect. Where does this problem come from?

 

You see two screenshots. At the first I only have written the counter value to the TCE0.CCA register. There you can see that the clock is ... just bullshit. Using CCA (PORT Pin0) it works this way without errors - but i have to use the PIN3.

At the second screen i have written the compare value to the registers CCA and CCD. Now it seems to work - BUT you can see a drift. Its not precise. Again, just using CCA and PIN0 its stable as a crystal.

 

Using just CCD I have again the bullshit waveform. CCC and CCD creates this drift. CCA und CCB works fine. The exact same problem is at TCD0.

 

Is there a way to repair this fault? Or do I have to make a residng of my PCB using Pin0 instead....?

 

Thank you!

 

#include <avr/io.h>
#define F_CPU 32000000UL
#include "util/delay.h"
#define FRQ 321000UL

int main(void)
{
	OSC.XOSCCTRL = OSC_FRQRANGE_2TO9_gc | OSC_XOSCSEL_XTAL_16KCLK_gc;				//setrup crystal
	OSC.CTRL = OSC_XOSCEN_bm;														//enable crystal
	while(!(OSC.STATUS & OSC_XOSCRDY_bm));											//wait for crystal
	OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | 8;											/*128MHZ PLL*/
	OSC.CTRL |= OSC_PLLEN_bm;														//enable pll
	while(!(OSC.STATUS & OSC_PLLRDY_bm));											/*wait for pll*/
	CCP = CCP_IOREG_gc;																/* Disable register security for clock update */
	CLK.PSCTRL = CLK_PSBCDIV_2_2_gc;												/*Divider for system clock*/
	CCP = CCP_IOREG_gc;																/* Disable register security for clock update */
	CLK.CTRL = CLK_SCLKSEL_PLL_gc;													/* Switch to PLL clock (32MHz)*/

	PORTA.DIR = 0xff;
	PORTB.DIR = 0xFF;
	PORTC.DIR = 0xFF;
	PORTD.DIR = 0xFF;
	PORTE.DIR = 0xFF;

	HIRESE.CTRLA = HIRES_HRPLUS_bm | HIRES_HREN_TC0_gc;								//High Resolution aktivieren
	TCE0.CNT = 0;
	TCE0_CTRLA = 1;																	//Timer für Ref.Freq. Pitch
	TCE0.CTRLB = 0b10000001;														//CCD; Frequenzmodus

	unsigned long dwFreq = 572000;

	TCE0.CCA = (unsigned long long)32000000*8/(dwFreq*2) - 8;
	//TCE0.CCD = (unsigned long long)32000000*8/(dwFreq*2) - 8;

	while(1){
	}
}

 

Attachment(s): 

Last Edited: Sat. Jun 24, 2017 - 12:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you tried using the CCxBUF registers?

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

Its the same. The value in buffer register is only used after the current cycle - its a buffer to not disrupt the current cycle.

Last Edited: Fri. Jun 23, 2017 - 01:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe some oscilloscope images would help... It's not clear what the nature of your issue is.

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

I see now, that all my frequency outputs are dritfting, even without the hires! I would need to make a video to see it, but measuring the frequency with an oscillocpe, it switches between 591 and 581kHz at a given static value for CCA. I ecpected that the freuency is very stable. How can it be, that its drifting that much?

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

You are using the RC32MHz oscillator. Even with DFLL it will drift around, especially with your crystal in low power mode.

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

Ok, then I haveto use a for example 16MHz crystal and double it with PLL (or make it up 128MHZ for the clk/4)? I will try it.
 

EDIT: It works! Crazy, how unprecise the internal oscillator is!

Last Edited: Sat. Jun 24, 2017 - 06:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Glad it's working.

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

Curby wrote:
Crazy, how unprecise the internal oscillator is!

That is generally the case with these RC oscillators - which is why it is generally recommended to use a crystal (not the RC) when UART comms is required...

 

BTW: Instructions on how to embed images in a post, so that they're visible in the post:

 

http://www.avrfreaks.net/wiki/em...

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

There is still an error. I updated title and the first post.

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

If you are using a 16MHz xtal, why are you setting the frequency range to 2 - 9 MHz?

OSC.XOSCCTRL = OSC_FRQRANGE_2TO9_gc ......

// shouldn't it be

OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc ......

 

Greg Muth

Portland, OR, US

Xplained Boards mostly

Atmel Studio 7.0 on Windows 10

 

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

Curby wrote:

There is still an error. I updated title and the first post.

 

Did you check the errata ? - Sounds like an errata type issue to me, and I seem to remember something about 'not all timer pins being equal' go past....  no idea if that was your part code.

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

Try running direct from the 16MHz oscillator without the PLL, see what happens.

 

With things like this it's generally best to write a minimal test case first and if that works built it up, or if it doesn't you know you found some kind of silicon issue.