Hallo, Ich mache meine Diplomarbeit auf dem TMS320VC5505 Evaluation Board. Vorher hatte ich noch nicht so viel Kontakt mit Mikrocontrollern/DSPs. Nur das was man so in den Vorlesungen hört. Stehe gerade in den Startlöchern und mache erste Gehversuche... D.h. "Hello World", serielle Ausgabe und Werte einlesen/ausgeben klappt... Nur leider klappt es nicht Werte äquidistant einzulesen... Ich verwende die CSL und möchte 1024 Werte pro Sekunde einlesen und über RS232 weitergeben (Als Block zum Beispiel jede Sekunde). Das Werte einlesen dachte ich mir mach ich mit Interrupts. Habe gesehen es gibt noch andere Möglichkeiten zum Beispiel direkt über DMA ins Memory oder Polling. Meinen Timer 0 habe ich jetzt so konfiguriert: hwConfig.autoLoad = GPT_AUTO_ENABLE; hwConfig.ctrlTim = GPT_TIMER_ENABLE; hwConfig.preScaleDiv= GPT_PRE_SC_DIV_6; hwConfig.prdLow = (sysClk)/4; hwConfig.prdHigh = 0x0000; wobei sysClk der Takt ist. Das Beispiel ist angelehnt an das CSL Beispiel "csl_gpt_example.c" Mein Interrupt gibt als Test immer die aktuelle Zeit aus: RTC_getTime(&getTime); printf("\nTime and Date is : %02d:%02d:%02d:%04d\n", getTime.hours,getTime.mins,getTime.secs,getTime.mSecs); Die Zeitdifferenz zwischen zwei Ausgaben ist jedoch immer unterschiedlich... Jetzt meine Fragen: 1) Was mach ich falsch mit den Interrupts? 2) Wie macht man so etwas eigentlich profimäßig (SAR und DMA, Werte schreiben in einen Ringpuffer?)
Zunächst würde ich für Zeitmessungen niemals Ausgaben über die serielle Schnittstelle verwenden (besonders nicht mit so komplizierten Funktionen wie printf), sondern immer einen Pin toggeln und am Oszilloskop messen. Dann weiß ich auch gerade nicht, wie die Uhr (getTime.xx) aus deinem Beispiel überhaupt funktioniert, bzw. ob sie richtig geht. 1024 samples pro Sekunde sind nicht sehr schnell. Das lässt sich problemlos in Interrupts behandeln. Man baut sich also zwei Interrupts: 1: Timerinterrupt, der mit der gewünschten Samplingfrequenz auslöst und die AD-Wandlung startet. 2: ADC-Conversion-Complete Interrupt, in dem das Wandlungsergebnis aus dem Wandler ausgelesen wird und irgendwo abgespeichert wird. Event-gesteuertes AD-Triggern und Kopieren der Daten mit DMA braucht man eigentlich erst, wenn es richtig schnell werden muss. Das wird beispielsweise bei Audioanwendungen langsam sinnvoll. Grüße, Peter
Du gibst 15 Zeichen aus, mal 10Bit*1024 ist schon mehr als 115200Baud, das kann so nicht gehen. Cheers Detlef
Ok, danke erstmal. Dass ich eine Funktion (die eventuell wiederum einen Interrupt auslöst) im Interrupt ausführe erscheint mir jetzt auch hirnrissig. Ich habe das ganze mit dem Oszi mal überprüft und komme jetzt auch zurecht mit der Taktung. @Detlef: Macht das EVM 5505 maximal ne Baudrate von 115200? Ich habe jetzt noch ein anderes Problem festgestellt. Und zwar versuche ich momentan dahinterzukommen wie die sysclock festgelegt wird. Eine Funktion aus der CSL habe ich direkt übernommen. Diese liefert aber bei 100Mhz einen Takt von 131203khz, bei 75Mhz 31195khz, bei 40Mhz 5151 usw. Komme jetzt nicht ganz hinter dieses System ;-) Aus den Registern und dem User Guide werde ich auch noch nicht so richtig schlau.
1 | Uint32 getSysClk(void) |
2 | {
|
3 | Bool pllRDBypass; |
4 | Bool pllOutDiv; |
5 | Bool pllOutDiv2; |
6 | Uint32 sysClk; |
7 | Uint16 pllVP; |
8 | Uint16 pllVS; |
9 | Uint16 pllRD; |
10 | Uint16 pllVO; |
11 | Uint16 pllDivider; |
12 | Uint32 pllMultiplier; |
13 | |
14 | pllVP = CSL_FEXT(CSL_SYSCTRL_REGS->CGCR1, SYS_CGCR1_MH); |
15 | pllVS = CSL_FEXT(CSL_SYSCTRL_REGS->CGICR, SYS_CGICR_ML); |
16 | |
17 | pllRD = CSL_FEXT(CSL_SYSCTRL_REGS->CGICR, SYS_CGICR_RDRATIO); |
18 | pllVO = CSL_FEXT(CSL_SYSCTRL_REGS->CGOCR, SYS_CGOCR_ODRATIO); |
19 | |
20 | pllRDBypass = CSL_FEXT(CSL_SYSCTRL_REGS->CGICR, SYS_CGICR_RDBYPASS); |
21 | pllOutDiv = CSL_FEXT(CSL_SYSCTRL_REGS->CGOCR, SYS_CGOCR_OUTDIVEN); |
22 | pllOutDiv2 = CSL_FEXT(CSL_SYSCTRL_REGS->CGOCR, SYS_CGOCR_OUTDIV2BYPASS); |
23 | |
24 | pllDivider = ((pllOutDiv2) | (pllOutDiv << 1) | (pllRDBypass << 2)); |
25 | |
26 | pllMultiplier = ((Uint32)CSL_PLL_CLOCKIN * ((pllVP << 2) + pllVS + 4)); |
27 | |
28 | switch(pllDivider) |
29 | {
|
30 | case CSL_PLL_DIV_000: |
31 | case CSL_PLL_DIV_001: |
32 | sysClk = pllMultiplier / (pllRD + 4); |
33 | break; |
34 | |
35 | case CSL_PLL_DIV_002: |
36 | sysClk = pllMultiplier / ((pllRD + 4) * (pllVO + 4) * 2); |
37 | break; |
38 | |
39 | case CSL_PLL_DIV_003: |
40 | sysClk = pllMultiplier / ((pllRD + 4) * 2); |
41 | break; |
42 | |
43 | case CSL_PLL_DIV_004: |
44 | case CSL_PLL_DIV_005: |
45 | sysClk = pllMultiplier; |
46 | break; |
47 | |
48 | case CSL_PLL_DIV_006: |
49 | sysClk = pllMultiplier / ((pllVO + 4) * 2); |
50 | break; |
51 | |
52 | case CSL_PLL_DIV_007: |
53 | sysClk = pllMultiplier / 2; |
54 | break; |
55 | }
|
56 | |
57 | /* Return the value of system clock in KHz */
|
58 | return(sysClk/1000); |
59 | }
|
>Diese liefert aber bei 100Mhz einen Takt von 131203khz...
Mit den C5000 kenn ich mich jetzt nicht wirklich gut aus, aber normal
gibt es diese Funktionen bidirektional.
Also eine, die die Pll auf eine gewünschte Ausgangsfrequenz konfiguriert
(natürlich nur, wenn das richtige Quarz angeschlossen ist).
Und eine andere, die man aufrufen kann, um die aktuell konfigurierte
Frequenz auszulesen.
Wenn darin kein Fehler ist, sollte sich genau die eingestellte Frequenz
auch wieder auslesen lassen.
Grüße,
Peter
Hallo garnix, da hat der Prof ja eine schöne Aufgabe gestellt :-) Ich arbeite mit dem 6713 und dem AIC23, also etwas anders als bei diesem Board. Hier meine Anmerkungen. Ich habe mir das Board und den DSP mal kurz angesehen. Da der 5505 ein Festkomma-DSP ist, muss bei den Algorithmen die Wortbreite des DSPs unbedingt berücksichtigt werden. Simulationen (Matlab) und die erste Implementierung von Algorithmen werden oft in mit Fließkommaoperationen durchgeführt. Die Umsetzung von Fließ- in Festkommaoperationen ist nicht trivial, anders als es vielleicht im ersten Moment aussieht. Das stellt einen erhöhten Schwierigkeitsgrad dar. Weiß das der Prof? Ich habe das früher so gemacht, dass für die Simulation in Matlab meine Algorithmen in C mit einstellbarer Wortbreite implementiert habe und somit die Dynamik der Algorithmen überprüft habe. Ach so, simulieren muss man eigentlich immer, wenn man mit dem DSP arbeitet. Unglücklich ist auch, dass sich die SPI-Schnittstelle zum AIC nur im Master-Mode betreiben lässt. So muss wahrscheinlich wirklich, wie oben schon erwähnt, mit dem Timer_IRQ zum Abholen der Samples gearbeitet werden. Eleganter geht's beim 6713: Der AIC ist im Master-Mode, liefert die Samples über die serielle Schnittstelle (McBSP), die Schnittstelle generiert einen IRQ zum EDMA-Controller, der sammelt die vorgegebene Anzahl von Samples ein (z.B.1024) und liefert dann, wenn alles vollständig ist, einen IRQ zum DSP. Der DSP ist die ganze Zeit nicht in den Transfer involviert. TI liefert seine Beispiele oft mit Pollin-Mode aus. Das ist sehr unelegant. Trotzdem würde ich mich zunächst an die Beispiel von TI halten. Werden bei Beispielen für dieses Board schon IRQs von TI verwendet? Läuft die FFT schon? Grüße, smithjnr
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.