PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Taktgenerator: UART, Timer, PWM?



blitzgeist
25.03.2007, 13:43
Hallo zusammen,
ich möchte gerne einen Taktgenerator implementieren. Ich benutze den PIC28F2550. Der Tak soll zb. n bit lang sein. Frequenz einstellbar. Nachdem n Bit gesendet wurden soll nichts merh gesendet werden. Progge in C

Dachte mir über einen UART könnte man das machen, in dem man das Datum 55h sendet. Doch das könnte zu Problemen kommen zwischen den einzelnen Daten, wenn man sich unter http://de.wikipedia.org/wiki/EIA-232 Punkt Timing anschaut (besonders die Stelle Ruhe). Von was hängt das "Ruhe bit" überhaupt ab?

Wie sieht das ganze mit einem Timer aus? In diese Materie muss ich mich noch einlesen, aber wie sage ich dem Timer Bit n erreicht, stopp? Denke mit der einstellbaren Frequenz, da kann man mit den Parametern spielen.

Und es mit PWM zurealisiren? Wäre das ein besserer Ansatz?

Ach ja, wie ist das eigendlich generel wenn es über den UART geht: es ist nämlich so, wenn die Applikation den Takt über TxD bekommt, empfängt der PIC Daten über RxD, gleichzeitig. Das geht? Meine ich wüsste nicht warum nicht.

So, das sind ein paar Fragen. Wäre aber sehr dankbar für Antworten=)

lg,
blitzgeist

Mobius
25.03.2007, 16:46
Ähm... hä?
Sorry, erstmal langsam, also, wie ich das verstanden habe, willst du einen Takt mit variabler Frequenz erzeugen, so war es weit einmal klar. Geht wundervoll mit einem Timer oder PWM, wenn du einen variablen Duty-Cycle willst, UART ist überhaupt keine gute Idee für sowas zu missbrauchen, wozu auch, der ist für was ganz anderes gedacht.

Aber, was sollte das "n bit lang" bedeuten? Willst du, dass nur eine bestimte Anzahl dieser Takte ausgegeben wird, oder, dass du sagen kannst, wie lang der Duty-Cycle ist, oder beides?
Für's erste ist der Timer am Besten, weil bei dem kannst du durch den Interrupt genau zählen beim wievielten Periode du schon bist. Beim zweiten eignet sich der PWM, beim Dritten, naja, geht auch mit'm PWM mit ein wenig triksen, aber der Timer wäre da zu empfehlen.

Also, bitte, mal genauer erklären, was du haben willst ^_^
MfG
Mobius

P.S.: AJa, es ist ein PIC18F2550 was du da hast ;)

blitzgeist
25.03.2007, 18:46
Hi Mobius,

danke für deine Antwort. Ja, auf einen Timer bin ich jetzt auch gekommen =)
Mit n Bit meine ich, dass mein Taktgenerator nur n Takzzyklen durchläuft und dann der Timer ausgeschaltet wird... Bin gerade daran :-k

Ach ja, klar meine PIC18F...

lg,
blitzgeist

blitzgeist
26.03.2007, 09:42
Hallo zusammen,
habe es nun mit dem Timer0 probiert. So sieht mein Code aus:



void ServiceTimer0(void)
{
static byte timer_state = 0;

if(timer_state == 0)
{
OpenTimer0(TIMER_INT_OFF &
T0_8BIT &
T0_SOURCE_INT &
T0_PS_1_1);
timer_state++;
}

else if(timer_state == 1)
{
if((unsigned char) ReadTimer0() > 25)
{
mTaktausgang = 1;
WriteTimer0(0);
timer_state++;
}
}

else if(timer_state == 2)
{
if((unsigned char) ReadTimer0() > 25)
{
mTaktausgang = 0;
WriteTimer0(0);
timer_state--;
}
}
}


Mein Timer0 ist getaktet mit Fosc=20Mhz /5 prescaler = 1 =>5Mhz. Also alle 200ns erhöt sich mein Wert im Timer0 Reg. Wenn ich nun z.B. 100kHz erzeugen möchte: halbe Taktdauer sind 5us, also 5us/200ns => 25. Ist somit der Wert 25 im Timer0 Reg erreicht, wird mein Taktazsgang entsprechend gesetzt. Eigendlich müsste if((unsigned char) ReadTimer0() = 25) stehen, aber das ist sehr zeitkritisch, deshalb erst mal > 25. Aber das ganze funktioniert nicht. Egal wie ich meinen Wert (25) setze habe immer einen Takt von 25kHz am Pin anliegen. Was ist daran falsch?

lg,
blitzgeist

blitzgeist
26.03.2007, 10:26
Hallo zusammen,

also habe das ganze mal durch den debugger laufen lassen und komme zu folgendem Schluss: Da ich mit dem PIC18F2550 ein USB Device realisiere ist das ganze so aus:
main
while(1)
->USBTasks()
->USBCheckBusStatus()
->USBdriverService()
->ProcessIO()
->ServiceRequests()
->ServiceTimer()

In der ServiceTimer() steht das drin, was ich oben gepostet habe. Die ganzen anderen Funktionsaufrufe sind nötig, damit alles mit USB funktioniert. Wenn ich nun im Register TMR0L schaue, wann dieser wieder auf 0 gestezt wird und somit ein Flankenwechsel am Pin entsteht, steht da abwechseln 202->208->202->208 usw. Z.B 202 mal 200ns ergibt meine 24kHz. Das heißt also: mit USB ist ein Takt mit nur max. 24kHz zu realisieren? Dann habe ich ein Problem ](*,)

lg,
blitzgeist

Der Gärtner
26.03.2007, 16:28
Ich habe zwar bis jetzt nur ~1Hz-Takte + Interrupt mit dem 2550/4550 im CCD-Betrieb verwendet, aber mit der Geschwindigkeit dürftest du noch nicht den USB-Betrieb stören (ist mir mit meinem DISP passiert, hab nicht auf die Initialisierung vom USB gewartet...). Ich hab zwar immer noch kaum Dunst was du machen willst und was deine Kiste kann (du hast von USB geredet), aber ich versuch dir mal zu helfen.

[highlight=red:e843cddfa5]Zum Thema:[/highlight:e843cddfa5]
In den C18-Compiler examples gibts einen BSP-Code für TMR0+Interrupt, kopier den Raus und bei jedem Überlauf ladest du einen neuen wert in die Register TMR0L//TMR0H + machst das was du wolltest (pin ändern z.b.)

[highlight=red:e843cddfa5]Weiteres seltsames Detail am Rande: [/highlight:e843cddfa5]
Mir fällt gerade auf, dass du was von 20Mhz/5 für den Timer im einen und "USB" im anderen redest. Das geht nicht gut miteinander. Ich nehme einmal an, dass du Fullspeed fährst und die dein Configbyte auf "HS-PLL" gesetzt ist. dann hast du 20Mhz(Quarz)/5 für die PLL und die spuckt 96Mhz(!) aus, das ganze durch 2 und du hast 48Mhz für usb und mit "CPUDIV" stellst du einen Teiler von den 96Mhz für die CPU ein. Das läuft dann von 16Mhz - 48Mhz. Die Timer haben dann einen Takt von 4-12Mhz. AUFPASSEN!!!

PS: hände weg von den builtin-funktions zum steuern von Timern, ich schieß mir damit immer ins Knie, ich mach das oldschool über register ;)