Hallo,
ich versuche mich gerade an der Programmierung eines Stellaris Boards
(LM4F120)
Bisher habe ich wie folgt auf die Ports zugegriffen:
1
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
2
GPIO_PORTF_DATA_R=GPIO_PORTF_DATA_R^0x02
Nun gibt es aber laut Datasheet die Möglichkeit auf den Port maskiert
zuzugreifen. Dazu muss ein Offset zur Basisadresse hinzugrechnet werden.
Ich habe nun folgendes probiert:
1
#define GPIO_PORTF_ready (*((volatile unsigned long *)0x40025000+0x020)) //PF3
2
GPIO_PORTF_ready=0xff
Damit sollte eigentlich PF3 gesetzt werden, doch es passiert leider nix.
Kann mir jemand sagen was ich falsch mache?
Vielen Dank.
Tom schrieb:> #define GPIO_PORTF_ready (*((volatile unsigned long> *)0x40025000+0x020)) //PF3
Wo hast du denn die merkwürdigen Speicheradressen her?
Table 2-6. SRAM Memory Bit-Banding Regions:
0x4200.0000 - 0x43FF.FFFF Peripheral bit-band alias
The following formula shows how the alias region maps onto the bit-band
region:
bit_word_offset = (byte_offset x 32) + (bit_number x 4)
Normalerweise gibt es doch eigentlich für jeden µC eine fertige include
wo die ganzen define mit den Adressen drin sind so das man sich da nicht
selbst was zusammen phantasieren muss?
so wie ich es verstanden habe ist die Basisadresse für den PortF
0x40025000 (APB)
Auf diese muss ein offset addiert werden um die entsprechenden Bits
"freizuschalten"
Wenn ich nur Pin PF3 beschreiben möchte, müsste der Offset 0x20 sein.
Beschrieben hier auf dieser Seite:
https://filderbaer.wordpress.com/2014/12/30/2-gpio-programming/
Aus der kurzen Beschreibung im Datasheet bin ich leider nicht schlau
geworden.
Lad dir die CMSIS Header Dateien für deinen Kontroller runter, da sind
alle Basisadressen definiert. (müssten diese sein:
http://www.ti.com/tool/cmsis_dsp_headers)
Dann gibt es für jeden Port (und alle anderen Hardware Register) fertige
Makros.
Ich bin Anfänger und nutze eine vorkonfigurierte Umgebung von Keil.
Daher habe ich nicht soviel Ahnung von Headerdateien.
Der Tip mit der CMSIS Headerdatei klingt gut.
Ich habe mir die Dateien cmsis_ccs.h und core_cm4.h angeschaut, aber ich
kann dort keine Registerdefinitionen finden.
Vielleicht habe ich die falsche Datei heruntergeladen.
Ich denke, da muss mir jemand noch auf die Sprünge helfen.
Kenne das aus der Zeit als die noch Luminary Micro hiessen. Die hatten
ARMs PrimeCell PL061 als GPIOs drin. Ist offenbar immer noch so.
Da gibts einen Bereich von 256 Worten, in denen die Adressbits 9:2 eine
Maske für die Daten darstellen. Weshalb auch nur 8 GPIOs per Port drin
sind.
In den fehlenden Klammern liegt der Fehler. Der Cast bindet stärker als
die Addition, daher wird 0x20 zum Pointer addiert und folglich
implizit mit 4 multipliziert. Es kam also die Adresse 0x40025080 statt
0x40025020 raus. PF5 statt PF3.
Entweder vor dem Cast 0x20 draufaddieren, oder 0x08 danach:
1
#define GPIO_PORTF_ready (*((volatile unsigned long *)(0x40025000+0x20))) //PF3
2
#define GPIO_PORTF_ready (*(((volatile unsigned long *)0x40025000)+0x08)) //PF3
Wie schon gesagt solltest du mal in den Headern graben und die dortige
Definition zu diesem 256-Worte-Bereich auftreiben. Wenn der Bereich dort
beispielsweise GPIOFUBAR heissen sollte und ungefähr so aussieht:
Vielen Dank.
jetzt funktioniert es erst einmal.
Dazu noch eine Frage: Ist die Art der Maskierung bei allen ARMs gleich,
oder betrifft das nur die von TI?
Das mit den Headerdateien schaue ich mir noch an, da wird sicher noch
die eine oder andere Frage aufkommen
Tom schrieb:> Dazu noch eine Frage: Ist die Art der Maskierung bei allen ARMs gleich,> oder betrifft das nur die von TI?
Das sieht bei jedem Hersteller völlig anders aus.
Nur das Bitbanding haben alle ARM ab CM3.
Die Cortex Cores enthält zusätzlich zum Prozessor ein paar weitere
Bestandteile, wie Debugging, Systick, Interrupt-Controller und je nach
Typ das Bitbanding. Aber das wars dann auch. Der Rest ist davon
unabhängig.
Daneben bietet ARM einige PrimeCell genannte Funktionsmodule. GPIO,
Timer, UART, DMA usw. Die können Hersteller ebenfalls nutzen, oder
eigene Entwicklungen einsetzen. Die meisten haben Ansprüche, die über
diese PrimeCells hinausgehen. Bei Luminary Micro fand ich jedoch einige
davon.
Tom schrieb:> (*((volatile unsigned long *)0x40025000+0x020))
(*(volatile unsigned int*) reicht ein long ist sowieso auch 32 Bit lang.
Irgendwer schrieb:> Normalerweise gibt es doch eigentlich für jeden µC eine fertige include> wo die ganzen define mit den Adressen drin sind so das man sich da nicht> selbst was zusammen phantasieren muss?
Wieso denn nicht. Besser kann mit der Hardware kaum vertraut werden, als
im Datenblatt die Register nachzuschlagen.
Tom schrieb:> so wie ich es verstanden habe ist die Basisadresse für den PortF> 0x40025000 (APB)> Auf diese muss ein offset addiert werden um die entsprechenden Bits> "freizuschalten"> Wenn ich nur Pin PF3 beschreiben möchte, müsste der Offset 0x20 sein.
So ist es.
A. K. schrieb:> Bitbanding genauer beschrieben: ARM Bitbanding
Wieso braucht der Junge denn bitte Bitbanding?
Tom schrieb:> Die GPIOs haben scheinbar einen eigenen Bereich, der nicht im Bitbanding> Bereich liegt.
Sicher? Arbeite zwar eigentlich mit STM32 aber das kann ich mir kaum
vorstellen.
A. K. schrieb:> Das sieht bei jedem Hersteller völlig anders aus.
Jo is bei STM32 zB völlig anders. Iwie einfacher, jedenfalls was ich auf
die Schnelle gesehen habe. Lies dir hier
malhttp://www.mouser.com/ds/2/405/lm4f120h5qr-124014.pdf
10.2 durch, da ist alles was de brauchst.
Tom schrieb:> Ich bin Anfänger und nutze eine vorkonfigurierte Umgebung von Keil.> Daher habe ich nicht soviel Ahnung von Headerdateien.
Wenn du Keil benutzt, mach folgendes um die Adressen herauszufinden:
1. Ätzende Variante über Macros. Geh bei den Makros zB GPIOB->DDR (oder
wie die auch immer bei TI heissen) auf go to definition (also nen
rechtsklick auf "DDR" oder "GPIO") und guck dir an was da passiert. Da
kriegst du die Adressen dann.
2. Oder, weil ihr für Keil immerhin ne Menge Geld zahlt, grad deren
Funktionen nutzen. Im Debugger auf Peripherals -> dein GPIO Port und
dort stehen dann alle Register mit deren Adressen.
Gruss
Felix
Felix C. schrieb:> Wieso denn nicht. Besser kann mit der Hardware kaum vertraut werden, als> im Datenblatt die Register nachzuschlagen.
Im Datenblatt nachschlagen und auch mal einen Blick in die header
werfen, ja.
Aber deswegen braucht man die ganzen defines im eigene Quellcode nicht
nochmal abzutippen.
Tom schrieb:> Der Tip mit der CMSIS Headerdatei klingt gut.> Ich habe mir die Dateien cmsis_ccs.h und core_cm4.h angeschaut, aber ich> kann dort keine Registerdefinitionen finden.> Vielleicht habe ich die falsche Datei heruntergeladen.
Nein, der Tip namens CMSIS ist de facto SCHLECHT. Warum? Weil du
zugedröhnt wirst mit Zeugs, das keiner braucht. Guck stattdessen lieber
in das Referenzmanual zu deinem Controller. Ich benutze die von TI
aufgekauften Stellaris selber nicht, also kann ich dir lediglich
allgemeinere Hinweise geben, die bei vielen - ABER NICHT ALLEN -
Arm-haltigen Controllern zutreffen:
1. für normale Portzugriffe gibt es Register zum gezielten Setzen
(MYPORT_PSOR) und zum gezielten Löschen (MYPORT_PCOR) von Output-Pins.
2. für die von dir genannte maskierte Ausgabe gibt es ein Register für
die Maske, wo für jedes zu ändernde Bit im Port ein Bit gesetzt sein muß
(oder umgekehrt) und wo man dann, wenn die Maske im Register ist,
einfaach sein Bitmuster auf den Gesamtport (dessen PIN-Register)
ausgeben kann, ohne die von der Maske geschützten Bits zu versauen.
3. für jedes Bit im Port gibt es eine zweite Zugriffsadresse, die man
wie eine Boolean-Variable behandeln kann. Je nach Hersteller ein bool
oder ein longbool. Nennt sich Bitbanding.
W.S.
CMSIS selbst betrifft nur Core und NVic, also die cm* Files. Die
herstellerspezifischen Definitionen für GPIO, Timer, ... finden sich in
den cm* Files nicht.
W.S. schrieb:> Nein, der Tip namens CMSIS ist de facto SCHLECHT.
Wenn du irgendwelche Libraries meinst bin ich dabei. Aber die
Definitionsdateien für Adressen und Bits will man nicht unbedingt selber
eintippen, wenn vermeidbar.
W.S. schrieb:> Nein, der Tip namens CMSIS ist de facto SCHLECHT. Warum? Weil du> zugedröhnt wirst mit Zeugs, das keiner braucht
Da verwechselst du CMSIS mit der Cube-HAL
CMSIS sind nur defines und typedefs
A. K. schrieb:> CMSIS selbst betrifft nur Core und NVic, also die cm* Files. Die> herstellerspezifischen Definitionen für GPIO, Timer, ... finden sich in> den cm* Files nicht.
Jain
Die CMSIS besteht aus zwei Teilen.
Der erste Teil kommt von ARM und enthält Definitionen für Core und NVic
Der zweite Teil kommt vom Hersteller des SoC und enthält
Registerdefinitionen für die Peripherie