Hallo,
ich versuche jetzt schon eine ganze Weile erfolglos, meinen mbed zu
schnellen Pin-Toggles zu überreden. Über 900kHz bin ich bisher
allerdings nicht gekommen und das reicht vorn und hinten nicht für
größere Datenübertragungen. Mein Hauptproblem ist, dass ich wegen der
Verbrauchsrandbedingungen den ARM nur mit 12 MHz betreiben kann. Aber
auch damit sollten doch wenigstens ein paar MHz machbar sein.
Als Bibliothekssammlung nutze ich Tollos mit mbed, kompiliert wird also
mit arm-none-eabi-gcc. In diesem Mini-RTOS arbeite ich derzeit
ausschließlich in der init-Routine, habe also noch die "volle"
Rechenleistung zur Verfügung. Da die vom RTOS zur Verfügung gestellten
Routinen Dank OOP-Overhead zu langsam sind (PinToggle bei ca. 30 kHz),
muss ich direkt an die Register.
Hier die relevanten Codefragmente:
1 | int init(void) {
|
2 | ...
|
3 | uint32_t p0=(1<<23)|(1<<24)|(1<<25)|(1<<26); // Port0 Pin23-26 sind mbed p15-18; Port1 Pin 18/20/21/23 sind LEDs
|
4 | uint32_t* GPIO0_DIR = (uint32_t)0x2009C000;
|
5 | uint32_t* GPIO0_MASK= (uint32_t)0x2009C010;
|
6 | uint32_t* GPIO0_PIN = (uint32_t)0x2009C014;
|
7 | uint32_t* GPIO0_SET = (uint32_t)0x2009C018;
|
8 | uint32_t* GPIO0_CLR = (uint32_t)0x2009C01C;
|
9 | *GPIO0_DIR=p0;
|
10 | *GPIO0_MASK=!p0;
|
11 | while(1){
|
12 | *GPIO0_PIN=p0;
|
13 | sysPause(1);
|
14 | *GPIO0_PIN=!p0;
|
15 | sysPause(1);
|
16 | }
|
17 | }
|
So funktioniert das Togglen einwandfrei, Dank der zwei sysPause-Aufrufe
mit nur 500 Hz, erleichtert aber den 1. Funktionstest via Oszi ;) So und
jetzt das eigentliche Problem: Wenn man die sysPause herausnimmt, kommt
das Löschen schneller als das Setzen und die Pins bleiben gelöscht. Beim
Herumprobieren habe ich mittels sinnloser for-Schleifen und anderer
Verzögerungen das Tooglen zwar auch hinbekommen, aber halt mit unter
1/12 der Taktfrequenz. Auch die SET-/CLR-Register arbeiten nicht
schneller als das PIN-Reg. In anderen Threads hatte ich gelesen, dass es
einige Leute schon geschafft haben, auf ca. 1/5 und mehr zu kommen - nur
wie?
Gibt es evtl. einen Befehl, der dem ARM sagt, dass er seine
Port-Register sofort auswerten soll oder eine Möglichkeit, diese
Auswertungsgeschwindigkeit hochzustellen? Im User-Manual habe ich bisher
nichts gefunden, also zumindest rund um die Port-Reg-Definitionen steht
nichts zu dem Thema.