Hallo,
ich habe eine Frage bzgl. der waveform generation des xmega. Ich benutze
den Atxmega128A4U mit einem 16MHz Quarz. Daraus generiere ich eine
128MHz PLL (CLK*4) und einen 32MHz CPU Takt.
Ich möchte auf PORTE Pin3 eine ca. 500kHz Rechteckfrequenz ausgeben.
Dazu benutze ich die hires unit mit der CLK*4.
Folgendes Problem besteht:
Versuche ich auf Pin0 diese Frequenz auszugeben funktioniert alles
bestens und das Ganze ist stabil wie ein Quarz. Verwende ich PIN3 sehe
ich zwei Prolemfälle.
1. Ich schreibe nur in TCE0.CCD oder TCE0.CCA den compare-Wert. Dann
sehe ich nur eine undefinierbare Frequenz auf dem Ausgang. Nichts
verwertbares (siehe screenshot)
2. Ich schreibe den in beide register, TCE0.CCD und TCE0.CCA. Dann sehe
ich meine 500kHz Frequenz. Wie man dem Screenshot entnehmen kann, aber
äußerst ungenau. Es hängt nichts am Pin, dieser hängt frei in der Luft
bis jetzt.
3. Benutze ich Pin0 und nur TCE0.CCA habe ich absolut wie gesagt kein
Problem.
Ich habe die Vermutung, dass die hires hier probleme macht und mit
unterschiedlichen registern arbeitet CCA und CCD. Bei exakt 500kHz, wo
ein sauberer Teil rauskommt, funktioniert es perfekt. Benutze ich 501kHz
sehe ich diese drift. Auch hier wieder ber Pin0 und nur CCA funktioniert
es mit beiden Frequenzen. Mache ich die hires unit aus, funktioniert es
auch auf CCD, dann aber halt nur in sehr groben Schritten.
Was soll das? Oder mache ich selber etwas falsch?
Danke! Mein Code:
1 | #include <avr/io.h>
|
2 | #define F_CPU 32000000UL
|
3 | #include "util/delay.h"
|
4 | #define FRQ 321000UL
|
5 |
|
6 | int main(void)
|
7 | {
|
8 | OSC.XOSCCTRL = OSC_FRQRANGE_2TO9_gc | OSC_XOSCSEL_XTAL_16KCLK_gc; //setrup crystal
|
9 | OSC.CTRL = OSC_XOSCEN_bm; //enable crystal
|
10 | while(!(OSC.STATUS & OSC_XOSCRDY_bm)); //wait for crystal
|
11 | OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | 8; /*128MHZ PLL*/
|
12 | OSC.CTRL |= OSC_PLLEN_bm; //enable pll
|
13 | while(!(OSC.STATUS & OSC_PLLRDY_bm)); /*wait for pll*/
|
14 | CCP = CCP_IOREG_gc; /* Disable register security for clock update */
|
15 | CLK.PSCTRL = CLK_PSBCDIV_2_2_gc; /*Divider for system clock*/
|
16 | CCP = CCP_IOREG_gc; /* Disable register security for clock update */
|
17 | CLK.CTRL = CLK_SCLKSEL_PLL_gc; /* Switch to PLL clock (32MHz)*/
|
18 |
|
19 | PORTA.DIR = 0xff;
|
20 | PORTB.DIR = 0xFF;
|
21 | PORTC.DIR = 0xFF;
|
22 | PORTD.DIR = 0xFF;
|
23 | PORTE.DIR = 0xFF;
|
24 |
|
25 | HIRESE.CTRLA = HIRES_HRPLUS_bm | HIRES_HREN_TC0_gc; //High Resolution aktivieren
|
26 | TCE0.CNT = 0;
|
27 | TCE0_CTRLA = 1; //Timer für Ref.Freq. Pitch
|
28 | TCE0.CTRLB = 0b10000001; //CCD; Frequenzmodus
|
29 |
|
30 | unsigned long dwFreq = 572000;
|
31 |
|
32 | TCE0.CCA = (unsigned long long)32000000*8/(dwFreq*2) - 8;
|
33 | //TCE0.CCD = (unsigned long long)32000000*8/(dwFreq*2) - 8;
|
34 |
|
35 | while(1){
|
36 | }
|
37 | }
|