Hallo, als langjähriger Nutzer von BASCOM AVR (Programmierung von Atmel 8-Bit-Controllern unter BASIC - wobei ich aber über das Stadium eines Hobbyprogrammierers nie hinaus gekommen bin, d.h. ich habe z.B. nie irgendwelche zusammengesetzten Datentypen ("struct") benutzt, weil ich diese nie gebraucht aber auch nie verstanden habe - will ich jetzt endlich auf ARM-Controller umsteigen. Es war zu erwarten, dass trotz intensivster Bemühung meinerseits die Programmiersprache C und mit ihr auch die Entwicklungsumgebung CoIDE (mit dem GCC-Compiler), von der hier viel geschrieben wird, leider, leider nicht an mich gehen; ich blicke da einfach nicht durch. Das bedeutet, dass ich mit den zahlreichen, gut gemeinten und aufwändig geschriebenen ARM-Tutorials, wie ich sie hier im Forum gefunden habe, kaum etwas anfangen kann. Ich habe aber eine sehr schöne Entwicklungsumgebung in BASIC gefunden, nämlich MikroBasicPro for ARM (gibt's auch in Pascal und C), die bei Bedarf auch ohne die ganzen komplizierten Strukte auskommt. Man kann z.B. jederzeit jedes beliebige Register mit einem einfachen Integerwert erreichen. Unter CoIDE ist mir das nicht gelungen, weil dort die Register gar nicht einzeln unter den im Manual verwendeten Namen definiert sind. Stattdessen kann man dort nur unter Zuhilfenahme spezieller Funktionen, deren Namen und Variablen man erst mal kennen muss, auf die Register zugreifen - was für mich als "Hardware-Mensch" immer undurchschaubar blieb. Da aber MikroBasicPro meinem geliebten BASCOM auch strukturmäßig ziemlich ähnlich ist und zudem ohne jenes endlose und für mich völlig unüberschaubare Einbinden unzähliger #include-Dateien auskommt, kam ich damit auf Anhieb gut zurecht. Somit scheint zumindest vorläufig die Compilerfrage gelöst. Das nur mal vorab zur Einschätzung meiner "Fähigkeiten" als Programmierer. Hingegen traue ich mir hardwaremäßig wesentlich mehr zu. Nachdem die ersten Gehversuche mit einem STM32F407-Discovery-Modul ganz gut geklappt haben, will ich für eine erste konkrete Anwendung eine eigene Platine mit einem STM32F407VET bauen. Für das Projekt benötige ich 10 bis 12 digitale Eingänge (für Taster), einen 8-Bit-A/D-Wandler (nebst Timer und Interrupt-Steuerung für ca. 350000 Samples pro Sekunde), einen D/A-Wandler für die Ausgabe von NF bis 8 kHz (nebst Timer), ein externes DRAM mit mindestens 4 Megabytes, eine Micro-SD-Card als Massenspeicher, ein USART (mit externem USART/USB-Konverter (z.B. FT232RL) zwecks Emulieren eines Virtuellen COM-Ports im PC, und eine batteriegepufferte Echtzeituhr. Auf die Verwendung eines der beiden USB-Module, die der STM32F407 bietet (anstelle der USART-Schnittstelle), will ich verzichten, weil ich von USB absolut keine Ahnung habe, bzw. weil ich beim Durchlesen der diesbezüglichen Abschnitte nur noch Bahnhof verstanden habe. Mein Problem ist folgendes: Bei all der Fülle an Peripherie, die der STM32F407 bietet, bin ich bei der Frage, welches der einzelnen Komponenten ich letztendlich verwenden soll, vollkommen überfordert. Trotz intensiven Studiums des 1700 Seiten starken Reference Manuals nebst 178 Seiten Datenblatt fürchte ich nämlich, bei der Auswahl dieser Module grobe Anfängerfehler zu machen. So finde ich bei der Betrachtung der Alternate Functions Liste (Datenblatt, Table 9 auf den Seiten 60-68) z.B. 4 USARTs und 2 UARTs, außerdem 7 SDIOs (von denen ich wohl 2 Stück für die SD-Card und das DRAM brauche), 11 Timer usw. Dazu sehe ich eine Mehrfachbelegung mancher Anschlusspins, z.B. durch die unverzichtbaren SWD-Programmieranschlüsse, durch die beiden MCO-Taktausgänge, die ich fürs Debuggen gerne erhalten würde und sogar durch teilweise Überlappung gleichartiger Module. Ich frage mich also: Ist der STM32F407 insofern streng "orthogonal" so dass all diese Module tatsächlich nebeneinander gleichberechtigt sind? Nur in diesem Fall könnte ich unter Vermeidung von Doppelbelegungen frei nach der Verfügbarkeit entscheiden. Oder ist es eher so, dass manche dieser Peripheriemodule gegenüber anderen zu bevorzugen sind, z.B. weil diese universeller sind oder weil dadurch andere wichtige Möglichkeiten verloren gehen? Kann mir jemand einen Tipp für eine möglichst sichere, vielleicht sogar allgemein übliche Verwendung der von mir benötigten Peripheriemodule geben?
Also 7 SDIO hat der STM32F407 sicher nicht :-) und Timer sind es sogar 14 (nicht 11) es gibt eine schöne Übersicht im UserManual vom STM32F4-Discovery da ist die CPU als Blockdiagramm gezeichnet mit allen "internen" Teilen und zu deiner Frage : da es sich das ganze Projekt etwas umfangreich anhört, würde ich gar nicht mit einer eigenen Platine anfangen, sondern das Discovery benutzen bis alle Teilfunktionen einzeln auf einem "Breadboard" laufen also : 1. UART 2. ADC 3. DAC 4. SD-Karte usw und wenn jedes Teil einzeln läuft, kannst du dich an das erstellen deiner Platine wagen und die benötigten CPU Pins entsprechend "aufteilen" spätestens dann weißt du z.B. auch das der DAC nur an zwei Pins benutzt werden kann aber es 20 RX/TX-Pins gibt (und alle UARTs gleich funktionieren) also...das ganze schritt für schritt angehen sonst geht es in die Hose Gruss Uwe
Uwe B. schrieb: > da es sich das ganze Projekt etwas umfangreich anhört, würde ich > gar nicht mit einer eigenen Platine anfangen, sondern > das Discovery benutzen bis alle Teilfunktionen einzeln > auf einem "Breadboard" laufen > also...das ganze schritt für schritt angehen sonst geht es in die Hose Dem kann ich voll zustimmen. Du schreibst von DRAM, wobei ich nicht weiß, welches Du verwenden möchtest. Da würde ich zu einem STM32F429-Disco-Board raten. Der F429 hat einen SDRAM-Controller und das recht günstige Disco-Board ein SDRAM mit 8MB. Das vorhandene Display kannst Du außer Acht lassen. Wegen der IO-Belegung drucke Dir am besten die Tabelle aus dem ref-Manual aus und plane mit einem Bleistift die Verwendung der Pins. Die SWD-Pins sind keine Verschwendung sondern ein Segen, um selbst im Zielsystem noch entwickeln zu können.
Hallo Uwe, herzlichen Dank für Deine Antwort! Du hast natürlich Recht; der STM32F407 hat nur einen SDIO. Ich hatte nicht richtig hingesehen und den Eintrag "SDIO_D7" für das 7. SDIO-Modul gehalten... Das von Dir erwähnte Blockdiagramm im Discovery-Manual habe ich gefunden. Bei all den anderen, dickleibigen Infoquellen, mit denen ich inzwischen zu tun hatte, hatte ich dieses längst aus den Augen verloren. Auch hinsichtlich des Breadboards hast Du wahrscheinlich Recht. Meine Überlegung war nur die, dass ich für die benötigten externen Peripherie-Bauteile (FT232RL, DRAM, Steckfassung für die Micro-SD-Card) - die ja alle nur in feinen SMD-Gehäusen erhältlich sind - ohnehin eine (teure) Musterplatine anfertigen lassen muss. Und wenn ich das schon mache, dann kann ich doch auch gleich noch einen STM32F407 draufsetzen und bin dann vom Discovery-Modul (mit all dem darauf befindlichen Spielzeug, das ich nicht brauche und das nur unnötig IO-Pins belegt) unabhängig. Aber beim derzeitigen Stand der Entwicklung und in meiner Situation als absoluter ARM-Anfänger gibt es wohl tatsächlich noch viel zu viele Unwägbarkeiten. Dabei bin ich beim "In-die-Seile-Hängen" allerfeinster vielpoliger SMD-ICs mithilfe dünner CuL-Drähtchen über einer groben Versuchsplatine durchaus nicht ungeübt. Doch weil das (mit meinen 64 Jahren) wirklich nicht mehr so ganz einfach ist, werde ich erst mal versuchen, eine selbst geätzte Platine nur mit den nackten ICs (zzgl. Stützkondensatoren) zu erstellen und die Signalleitungen (soweit nicht völlig klar) über ordentliche Lötaugen von Hand verdrahten. Viele Grüße Norbert
Norbert Graubner schrieb: > Unter CoIDE ist mir das nicht gelungen, weil dort die > Register gar nicht einzeln unter den im Manual verwendeten Namen > definiert sind. Doch, du musst nur #include <stm32f4xx.h> schreiben. Wenn du tatsächlich unbedingt direkt auf die Register schreiben willst... Man kann auch C erst am PC mit Büchern lernen, das geht ganz gut und dann kann man's. Aber egal. Es gibt von ST das Programm microXplorer (scheinbar jetzt in STM32CubeMX umbenannt?!), das ist ungemein hilfreich dabei eine Pinbelegung festzulegen bei der sich keine Pins überschneiden. Und wenn du DRAM verwenden willst, solltest du einen STM32F429 verwenden, der hat einen DRAM-Controller.
Ein Hallo an den Gast, der mir soeben auch geantwortet hat! Das 427-Disco-Board mit dem Display und dem 8-MB-DRAM habe ich bereits (zusätzlich zu dem 407-Discovery-Board). Ich habe mich bisher nur nicht dran getraut (es war mir sozusagen "heilig"), weil ich das schöne, anspruchsvolle Grundprogramm mit dem Touch-Display nicht löschen wollte. Es hat mir aber inzwischen jemand verraten, wo ich die Original-Firmware finde, so dass ich diese notfalls wieder einspielen kann. Weil ich aber fürs Debuggen zuallererst eine Virtuelle COM-Schnittstelle haben möchte (so kenne ich das von BASCOM her), nützt mir dieses Disco-Board erst mal nicht allzu viel. Erst wenn ich etwas fitter geworden bin, werde ich mich näher mit der SWD-Schnittstelle auseinander setzen können. Ich habe beobachtet, dass z.B. die Entwicklungsumgebung CoIDE (mit dem GCC-Compiler) beim Debuggen direkt auf das Board zugreift - das wäre dann wohl der Zugriff auf den Controller. Aber mit CoIDE komme ich nicht zurecht und mein MikroBasicPro hat leider nur einen Simulator - da bleibt dann fürs echte Debuggen nur die Serielle Schnittstelle. Dass die Anschlüsse für die SWD-Schnittstelle zwingend notwendig sind, ist mir durchaus klar. Viele Grüße Norbert
Norbert Graubner schrieb: > Ein Hallo an den Gast, der mir soeben auch geantwortet hat! Hallöchen ;-) Debuggen mit SWD und einem "richtigen" Debugger wie in CooCox ist extrem hilfreich, damit kann man sehr gut mit wenig Aufwand genau betrachten was das Programm so macht, oder wo genau ein Crash passiert ist. Debuggen mit Ausgaben über die Serielle Schnittstelle dagegen ist ziemlich mühselig und bei Crashes eher Stochern im Dunkeln... An das F429 Discovery Board kannst du dir wie bei allen anderen Mikrocontroller-Boards doch leicht einen TTL-UART -> USB Adapter (wie zB ebay 271361620831) dranhängen und darüber deine Ausgaben machen.
Hallo Dr. Sommer! natürlich habe ich das mit allen möglichen #include-Direktiven versucht - auch mit #include <stm32f4xx.h>! Ich habe es soeben nochmal überprüft. Obwohl diese Anweisung oben drin steht, kommt bei CoIDE bei der Zuweisung // PLLQ = 7, HSE to PLL, PLLP1 = 2, PLLN = 336, PLLM = 8: RCC_PLLCFGR = 0x07405408; die folgende Fehlermeldung: 4: error: 'RCC_PLLCFGR' undeclared (first use in this function) ' Dabei ist ein Register mit genau dieser Zeichenfolge im Reference Manual enthalten und wird z.B. auch von MikroBasicPro so akzeptiert. Was das Erlernen von C am PC betrifft: Das habe ich seit ziemlich genau 25 Jahren (zuerst mit Borlands Turbo C) in mehreren, wirklich ernst gemeinten Anläufen immer wieder vergeblich versucht. Diese Sprache mit ihren völlig uneinsichtigen Kürzeln (und vor allem: mit ihren Tücken!) finde ich derart grauenvoll, dass sie einfach nicht an mich geht. Wie schön ist doch dagegen eine strukturierte Sprache wie Pascal - das liest sich beinahe wie Klartext! Und das noch mit sauberen Typprüfungen, die Anfängerfehler erst gar nicht zulassen! Und dass das klassische C nicht einmal den Datentyp String kennt (so dass man das alles höchst mühsam über Zeigerarithmetik und Funktionen implementieren muss), empfinde ich inzwischen nicht nur verwirrend, sondern zunehmend auch unzeitgemäß. Ich denke inzwischen, dass die Fähigkeit, die Sprache C zu begreifen, in erster Linie eine Mentalitätsfrage ist. Ich bin ein sehr konkret und real denkender Mensch; ich muss alles unmittelbar einsehen und die Zusammenhänge, bzw. Abläufe begreifen (im Sinne von Anfassen) können. Mit Abstrahierungen und "Structen" wie ich sie vor allem unter C immer wieder sehe (zuletzt bei SiSy ARM und auch bei CoIDE) (es scheint unter C-Programmierern geradezu eine Lust zu sein, alles, was nicht unmittelbar zum Problem gehört, zu verstecken oder zu abstrahieren um so angeblich die Lesbarkeit zu verbessern ...) verliere ich SOFORT den Boden unter den Füßen (daher z.B. auch mein Wunsch, selber auf die Register des Controllers zugreifen zu können). Und so war es sicher kein Zufall, dass ich nach Turbo-Pascal nicht auf Visual C sondern zunächst auf Delphi gekommen bin (obwohl ich damals schon sehr genau wusste, dass C der weltweite Programmierer-Standard ist und ich mir das allein schon aus beruflichen Gründen nur zu gerne angeeignet hätte). Auf Basic, bzw. BASCOM AVR bin ich nur gekommen, weil ich im Studium schon mal das sehr ähnliche Fortran kennen gelernt hatte, deshalb Basic sofort verstand und weil ich hiermit eine äußerst leicht verständliche Entwicklungsumgebung für die 8-Bit-Controller von Atmel gefunden hatte. Viele Grüße Norbert
Norbert Graubner schrieb: > 4: error: 'RCC_PLLCFGR' undeclared (first use in this function) Ah, es muss RCC->PLLCFGR heißen, in dieser Header-Datei sind immer die Register die zu einer Funktion gehören zu einem "Block" (struct) zusammengefasst, und man greift dann darüber zu. Hat zB bei GPIO's den Vorteil dass man die als Pointer übergeben kann. Ist halt blöde von ST die in der Doku mit "_" und nicht "->" zu beschreiben. Aber Dokumentation ist eh nicht deren Stärke... > Was das Erlernen von C am PC betrifft: ... Tja, deswegen verwendet man auch C++, das in Bezug auf Typen strenger ist und auch einen String-Typ hat ;-) > Ich denke inzwischen, dass die Fähigkeit, die Sprache C zu begreifen, in > erster Linie eine Mentalitätsfrage ist. ... Abstrahierung ist nunmal eines DER zentralen Konzepte der Software-Entwicklung und ist absolut essentiell für größere Projekte. Zur "Übung" und zur besseren Skalierbarkeit wird das dann auch bei kleinen angewendet. Aber im Ernst - String ist doch auch eine Abstraktion! Wenn du keine Abstraktionen magst, ist C mit "char*" doch ideal, da siehst du immer genau was passiert. In C am PC verwendet man fopen() um eine Datei zu öffnen - und keinen 1000-Zeiligen Algorithmus, um die entsprechenden Blöcke auf der Festplatte zu finden, den Index des Dateisystems auszulesen etc. - das ist doch eine sehr sinnvolle Abstraktion. Bei Abstraktionen mit "structs" und den entsprechenden Zugriffs-Funktionen (in OOP-Sprachen dann noch mehr mit Klassen) geht es doch darum, dass du dich eben nicht um jedes einzelne Detail kümmern musst, was die Code-Größe und Entwicklungsaufwand drastisch sinken lassen. Wenn du structs nicht verstehst, stell sie dir einfach als mathematisches Tupel vor, oder als "IC" - heutzutage wird auch nicht jede Schaltung aus einzelnen Transistoren zusammengebaut, sondern fertige IC's verwendet die eine komplexe Funktion bieten.
Norbert Graubner schrieb: > da bleibt dann fürs echte Debuggen nur die Serielle > Schnittstelle "debuggen" kannst du das nicht nennen, eher "monitoren" aber ich kann mir schon denken was du meinst eine neue CPU "ARM" und gleichzeitig eine neue Sprache "C" in einem so komplexen Projekt wird zwangsläufig schiefgehen versuche soviel wie möglich unbekannte auszuschließen, also wenn du mit deiner IDE zurechtkommst bleib dabei (auch wenn sie keinen Hardware-Debugger unterstützt) aber mach dich auf einen Alleingang gefasst, denn so gut wie alle Beispiele und Code-Schnippsel für den STM sind in "C" geschrieben Hinweis zum externen RAM : am 100Pin Package sind die Adressleitungen A0 bis A15 nicht an der CPU zugänglich...also musst du Latches vorsehen für 4MBit SRAM am STM32F407 hab ich mal ein Projekt gemacht : http://mikrocontroller.bplaced.net/wordpress/?page_id=2067 Gruss Uwe
Hallo Dr. Sommer, ich bin sehr froh, dass ST jedem einzelnen Register seinen eigenen Namen zugeordnet hat. Genau deswegen verstehe ich das ja. Hingegen kann ich mit der Ausdruck RCC->PLLCFGR gar nichts anfangen. Wer ist RCC und wer ist PLLCFGR? Es doch zusammen nur ein einziges, ganz bestimmtes Register mit einer klar zugewiesenen Adresse (zugegeben: es ist das Konfigurationsregister für die PLL im Reset-&Clock-Control-Block)! Und dass es sich bei dem merkwürdigen Zeichen zwischen den beiden Namen um einen Zugriffsoperator für einen Indirektzugriff handelt, habe ich nur mit Mühe in einem C-Tutorial von Andreas Hammer gefunden. Aber was der genau macht, habe ich noch nicht rausgekriegt. Für einen 8-Bit-Atmel-Controller (ATMega162) habe ich in Assembler mal einen ganz netten, sogar ziemlich schnellen Grafikcontroller für ein QVGA-Display geschrieben. Da habe ich auch indirekte Adressierung machen müssen. Aber das fand ich durchaus überschaubar. Eben weil es fast auf Maschinenebene ablief. Hingegen erkenne ich gar keinen Sinn und keine Notwendigkeit, ein einzelnes Register im RCC-Block indirekt adressieren zu müssen. Jedes der dort befindlichen Register hat doch ganz unterschiedliche Aufgaben! Da kann man doch auch direkt drauf zugehen. Dass man eine Datei auf der PC-Festplatte über ihren Namen, also über eine Abstrahierung anspricht und das Zusammensuchen der Blöcke und Sektoren einer Funktion (oder gar einem externen Controller) überlässt, finde auch ich sehr sinnvoll, denn es bewirkt eine starke Vereinfachung. Hingegen empfinde ich den Zugriff auf ein einzelnes Register mithilfe eines Structs als eine künstliche, in meinen Augen (zunächst?) unnötige Verkomplizierung. Es mag sein, dass ich das nur deshalb so sehe, weil ich beim Programmieren nie die höheren Weihen erlangt habe; ich habe stets nur mit den Grund-Datentypen und evtl. Arrays hiervon gearbeitet. Mag sein, dass meine Programme umständlich und manchmal zu aufwändig waren. Aber sie haben funktioniert und waren auch für andere Leute immer leicht verständlich. Man brauchte kein Hintergrundwissen über die Namen irgendwelcher Konstanten und Spezialfunktionen. Alles was man fürs Verständnis brauchte, stand im Quelltext - und wenn er 6000 Zeilen lang war! Auf diese Weise sind mehrere, sehr schöne, große Anwendungen entstanden. Wenn ich jetzt auf einen ARM -Controller wechseln will, dann nur wegen dessen höherer Leistung, bzw. Rechengeschwindigkeit, z.B. weil ich für ein neues Projekt eine FFT oder wenigstens massenweise Multiplikationen mit mehreren hundert kHz Takt brauche. Dabei würde es mir vollkommen genügen, wenn ich das mit meiner bisherigen, schlichten (und meinetwegen aufwändigen und umständlichen) Programmiertechnik erreichen würde. Ein schlichter Programmierstil muss ja nicht zwangsweise zu einem langsamen Programmablauf führen. Die Vorteile, die ein erhöhtes Maß an Abstrahierung - sinnvoll eingesetzt - mit sich bringen können, sehe ich sehr wohl. Mein Problem besteht aber darin, dass ich bei diesem - von der Hardware weitgehend losgelösten - abstrakten Denken gar zu schnell an meine persönlichen Grenzen komme; ich schaffe es einfach nicht! Viele Grüße Norbert
Hallo Uwe, über Deine anteilnehmende Stellungnahme zu meiner enormen Schwierigkeit beim gleichzeitigen Erlernen einer unbekannten CPU und einer unbekannten Programmiersprache bin ich sehr erleichtert. Erschwerend kommt noch die mir total gegen den Strich gehende Tendenz zum Abstrahieren hinzu; als Ingenieur habe ich seit nunmehr fast 40 Dienstjahren eher das Gegenteil - also immer die Konkretisierung bestehender Aufgaben und deren Auflösung bis hin zum kleinsten Widerstand - angestrebt. Dass ich mich bei meiner jetzigen IDE auf einen Alleingang gefasst machen muss, ist mir schon klar. Das war aber unter CooCox auch schon so, denn die in C verfügbaren Beispiele habe ich ja wegen der Abstrahierung (wenn überhaupt) ohnehin meist nur ansatzweise verstanden. Danke auch für Deinen Hinweis zur Verwendung eines externen SRAMs! Sowas habe ich schon mal gemacht - auch mit einem Latch und zwar mit einem Atmel XMega128A1, einem AHC573 und einem IS61WV10248B. Das hat fast auf Anhieb bestens geklappt. Weil aber dieses 8-MegaBit-SRAM eigentlich noch zu klein war, noch größere Chips aber richtig teuer werden, will ich jetzt im Folgeprojekt erstmals ein deutlich billigeres und größeres DRAM verwenden (damals hatte ich noch Schiss davor...). Das soll meine nächste Herausforderung (an einem Cortex M4) sein. Viele Grüße Norbert
Norbert Graubner schrieb: > Hallo Dr. Sommer, > > ich bin sehr froh, dass ST jedem einzelnen Register seinen eigenen Namen > zugeordnet hat. Genau deswegen verstehe ich das ja. Hingegen kann ich > mit der Ausdruck RCC->PLLCFGR gar nichts anfangen. Wer ist RCC und wer > ist PLLCFGR? RCC ist der Block an Registern der die "RCC"-Einheit konfiguriert (Reset and Clock Control), und PLLCFGR ist eines dieser Register. > Es doch zusammen nur ein einziges, ganz bestimmtes Register > mit einer klar zugewiesenen Adresse (zugegeben: es ist das > Konfigurationsregister für die PLL im Reset-&Clock-Control-Block)! Und > dass es sich bei dem merkwürdigen Zeichen zwischen den beiden Namen um > einen Zugriffsoperator für einen Indirektzugriff handelt, habe ich nur > mit Mühe in einem C-Tutorial von Andreas Hammer gefunden. Aber was der > genau macht, habe ich noch nicht rausgekriegt Das steht auch in jedem C-Buch. Beim RCC macht das ganze nicht so viel Sinn weil der Controller nur einen hat, da ist das nur aus Gründen der Konsistenz so gemacht. Aber beim GPIO schon mehr. Da kann man sich zB schreiben:
1 | void configurePort (GPIO_TypeDef* port) { |
2 | port->MODER = 0xAEAEAEAE; |
3 | port->ODR = 0xAAAAAAAA; |
4 | }
|
5 | int main () { |
6 | configurePort (GPIOA); |
7 | configurePort (GPIOB); |
8 | configurePort (GPIOC); |
9 | }
|
(Werte frei erfunden) so kann man abstrakt eine GPIO-Einheit an eine Funktion übergeben, und die Funktion macht etwas mit dieser Einheit. > > Für einen 8-Bit-Atmel-Controller (ATMega162) habe ich in Assembler mal > einen ganz netten, sogar ziemlich schnellen Grafikcontroller für ein > QVGA-Display geschrieben. Da habe ich auch indirekte Adressierung machen > müssen. Aber das fand ich durchaus überschaubar. Eben weil es fast auf > Maschinenebene ablief. Hingegen erkenne ich gar keinen Sinn und keine > Notwendigkeit, ein einzelnes Register im RCC-Block indirekt adressieren > zu müssen. Jedes der dort befindlichen Register hat doch ganz > unterschiedliche Aufgaben! Da kann man doch auch direkt drauf zugehen. Die Aufgaben gehören aber alle zum RCC... Die ATmega haben auch mehrere Register die zusammen gehören, wie Timer-Register oder Pin-Register - die hätte Atmel auch zusammenfassen können. > Hingegen empfinde ich den Zugriff auf ein einzelnes Register mithilfe > eines Structs als eine künstliche, in meinen Augen (zunächst?) unnötige > Verkomplizierung. Es bleibt ja meist nicht bei einem Register, ein Timer hat davon einen ganzen Satz... > Es mag sein, dass ich das nur deshalb so sehe, weil ich beim > Programmieren nie die höheren Weihen erlangt habe; ich habe stets nur > mit den Grund-Datentypen und evtl. Arrays hiervon gearbeitet. Mag sein, > dass meine Programme umständlich und manchmal zu aufwändig waren. Aber > sie haben funktioniert und waren auch für andere Leute immer leicht > verständlich. Man brauchte kein Hintergrundwissen über die Namen > irgendwelcher Konstanten und Spezialfunktionen. Alles was man fürs > Verständnis brauchte, stand im Quelltext - und wenn er 6000 Zeilen lang > war! Im Endeffekt steht immer alles im Quelltext - du kannst dir die 7000 Zeilen der stm32f4xx.h auch in deinen Code kopieren, dann steht auch alles drin und ist einfach verständlich. Aber mit dieser Einstellung wird man in der IT-Branche auf nicht viel Gegenliebe stoßen; die meisten Programmierer ziehen es vor mehr Konstrukte EINMAL zu lernen und dadurch kompaktere Programme schreiben zu können, als immer wieder in jedem Programm riesige Mengen Quellcode lesen zu müssen, die vielleicht keine besonderen Konstrukte verwenden... > Auf diese Weise sind mehrere, sehr schöne, große Anwendungen > entstanden. Wenn ich jetzt auf einen ARM -Controller wechseln will, dann > nur wegen dessen höherer Leistung, bzw. Rechengeschwindigkeit, z.B. weil > ich für ein neues Projekt eine FFT oder wenigstens massenweise > Multiplikationen mit mehreren hundert kHz Takt brauche. Dabei würde es > mir vollkommen genügen, wenn ich das mit meiner bisherigen, schlichten > (und meinetwegen aufwändigen und umständlichen) Programmiertechnik > erreichen würde. Ein schlichter Programmierstil muss ja nicht > zwangsweise zu einem langsamen Programmablauf führen. Das kannst du ja für dich so machen, aber wenn du eben externen Code einbindest wie die ST-Header-Dateien mit den Register-Definitionen oder die ST USB-Library, musst du dich mit deren Konventionen abfinden... > Die Vorteile, die ein erhöhtes Maß an Abstrahierung - sinnvoll > eingesetzt - mit sich bringen können, sehe ich sehr wohl. Mein Problem > besteht aber darin, dass ich bei diesem - von der Hardware weitgehend > losgelösten - abstrakten Denken gar zu schnell an meine persönlichen > Grenzen komme; ich schaffe es einfach nicht! Hm, das verstehe ich wieder nicht ganz... Wenn man sich z.B. das sehr abstrakte Arduino-API ansieht, hat man Funktionsaufrufe im Code wie:
1 | pinMode(9, OUTPUT); |
2 | analogWrite(9, 55); |
Das reicht schon um eine PWM einzuschalten. Man braucht keine komplizierten Bitrechnereien um die Registerinhalte zu bekommen, sondern kann sehr leicht erkennen was der Code macht. Solch Abstraktion ist doch nicht so schwierig?!
Lade Dir folgende Datei: http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf Unter Punkt 7 findet sich die Beschreibung von RCC mit seinen Registern und unter Punkt 7.3.25 die Abbildung der RCC-Register im Speicher.
@ Gast: Danke für den Tipp! Bei dem Dokument handelt es sich um das Reference Manual - für mich in der Tat die einzige wirklich tragfähige "Referenz"! Schon vor mehreren Wochen hatte ich mir den kompletten Abschnitt 7 (zuvor auch Abschn. 8 über die GPIOs) mit den darin enthaltenen genauen Beschreibungen der einzelnen Register ausgedruckt und durchgearbeitet. Bei insgesamt 1700 Seiten ist das ein ziemlich mühsamer Weg, aber auf genau dieser Grundlage (direkter, leicht verständlicher Zugriff auf die einzelnen Register) komme ich unter MikroBasicPro bisher gut damit zurecht.
Nach dem, was Du geschrieben hattest, kennst Du auch noch die schönen Handbücher (Hardware Manual), die man auf dem Sofa, dem Bett, an einem stillen Ort ausgiebig studieren konnte. Die gibt es leider nicht mehr :-( Wenn ich mit Peripherie-Geschichten neu zu tun habe, drucke ich mir das betreffende Kapitel insgesamt aus und lese es komplett durch, bevor ich nur eine Zeile Code schreibe. Dabei bekomme ich einen Gesamteindruck, was geht, oder was ich erwartet hatte, aber nicht vorhanden ist. (Der hochgelobte F407 hat nämlich auch seine Schattenseiten.) Vielleicht liegt Dir diese Vorgehensweise.
m.n. schrieb: > Wenn ich mit Peripherie-Geschichten neu zu tun habe, drucke ich mir das > betreffende Kapitel insgesamt aus und lese es komplett durch, Wenn das mal alle machen würden, wäre dieses Forum ein friedlicherer Ort... Aber diese 1700 Seiten sind ja noch nicht alles, man muss sich ja noch die 1020 Seiten für den ARM Kern durchlesen: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0403c/index.html @ Norbert: Warum machst du dir so einen Aufwand mit dem RCC? Es gibt von ST wunderbare Beispiel-Codes, wie man den RCC initialisiert sodass er auf maximalem Takt läuft; den muss man nur in sein Projekt kopieren und dann kann man sich den interessanteren Hardware-Teilen widmen, wie I/O Pins und Timer etc. Falls man dann doch irgendwann mal einen niedrigeren Takt haben will kann man das immer noch anpassen. Lediglich die einzelnen Takte für die einzelnen Peripherie-Module muss man noch einschalten, aber das sind ja nur einzelne Bits.
Hallo Norbert, http://www.mikrocontroller.net/articles/STM32_-_Einstieg_mit_Em::Blocks http://www.mystm32.de/doku.php Folge mal den Links und schau ob es hilft.
@ Gast: Das mit dem Bett wollte ich zuerst schreiben, dachte aber, dass das vielleicht doch etwas zu naiv und altmodisch wirkt. Aber in der Tat: Ich bin mehrere Abende extra etwas früher ins Bett gegangen und habe mir dort die ausgedruckten Kapitel in aller Ruhe und ganz entspannt zu Gemüte geführt. Auszugsweise habe ich diese anschließend für einen Freund sogar schriftlich ins Deutsche übersetzt (auch dabei lernt man noch was). Erst danach habe ich aus eigener Einsicht - d.h. mit dem zugehörigen Verständnis im Hinterkopf - die erste Zeile Code geschrieben. Die Bücherwand in meinem Arbeitszimmer ist übrigens immer noch voll mit besonders wertvollen Datenbüchern (Analog Devices, Burr Brown, Harris, International Rectifier, Maxim, Microchip, Motorola, National Semiconductor, Philips, Siemens, Texas Instruments ...) @ Dr. Sommer: Der Aufwand, den ich mir mit dem RCC mache, rührt daher, dass ich dieses System erst mal verstehen lernen musste. Im AtMega gabs nur einen einzigen Takt, wenn man Glück hatte vielleicht noch eine PLL (Xmega) - aber das wars dann auch. Als ich (über SiSy ARM) zum ersten Mal Kontakt mit einem ARM-Controller bekam, war ich allein von der Komplexität des RCC total irritiert ("wozu so viele verschiedene Takte???"). Ich bin halt der vielleicht etwas altmodischen Auffassung, dass man nur dann optimale Ergebnisse erwarten kann, wenn man ein System verstanden hat. Beim Abschreiben (oder gar Kopieren) von fremdem Code lernt man aber nicht genug. So blieb für mich die RCC-Konfigurierung unter Huwalds SiSy ARM - obwohl sie auf Anhieb funktionierte - ein Buch mit Sieben Siegeln. Erst nachdem ich im Reference Manual die Seiten über GPIO und RCC durchgelesen hatte, was es für mich ein Leichtes, die paar Register selber zu konfigurieren. Das funktionierte beinahe auf Anhieb. Jetzt arbeitet mein STM32F407 mit quarzgesteuerten 168 MHz und auch die Peripherie hat die richtigen Taktfrequenzen. Danke für den Tipp zum Handbuch über den ARM-Kern! Das werde ich mir dann auch noch zu Gemüte führen ... @ Bernd: Den ersten von Dir genannten Link hatte ich schon mal aufm Bildschirm. Leider handelt es sich um eine (nicht gerade billige) professionelle Entwicklungsumgebung. Die darin enthaltenen Tipps sind sicher wertvoll, aber ich muss auch darauf achten, dass ich meine nicht unendliche Zeit und Kraft auf die richtigen Pfade lenke. Ich werds mir aber nochmal näher ansehen. Hingegen könnte der zweite Link sehr interessant werden. Noch vor wenigen Wochen hätte ich sonstwas drum gegeben, ein C-Tutorial auf Basis eines ARM-Controllers zu finden. Ich war in mehreren Buchhandlungen, habe dort aber nur Standardwerke über C gefunden, die allesamt (mit der allseits beliebten Funktion printf() ) auf einem PC laufen. Eines davon habe ich gekauft, aber wie Du hier nachlesen kannst, nützte es mir herzlich wenig. Vielleicht wird Dein Link für mich doch nochmal ein (verzweifelter) Anlauf, in die Sprache C einzusteigen (seuftz...) ... Viele Grüße an Alle! Norbert
Der erste Link führt zu einem EMBlocks tutorial und EMBlocks ist kostenlos, hier mal der direkte Link zur Software... http://www.emblocks.org/web/ C lernt man nicht auf einem MC aber alles was du brauchst gibts auch hierfür kostenlos. http://www.it-ebooks.info/book/704/ PDF Version ist frei zu haben. Wenn du das durcharbeitest verstehst du auch die STM Libs denn die C Grundlagen hierfür sind im PDF bestens erklärt. Also schau noch einmal genauer hin.
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.