Hallo zusammen,
ich habe mir ein CMSIS-Projekt für ein STM32 Discovery-Board aufgebaut
und wollte nun mal ein bisschen spielen... Leider kam ich nicht dazu,
nicht einmal einen Port bekam ich gesetzt.
Ich habe mich entlang des Reference Manuals vorgearbeitet und mir die
entsprechenden Aliasse aus der Datei stm32f0xx.h herausgesucht. Von
einem Syntaxfehler (ist ja überschaubar) gehe ich jetzt nicht aus...
Kann mir vllt. jemand helfen? Ich vermute, dass es am Takt liegt, da ich
im BSRR Register das Setzen Bit aktivieren, aber sich im ODR Register
nichts tut...
void Periph_Init()
{
RCC->AHBENR |= RCC_AHBENR_GPIOCEN;
// Takt an GPIOC aktivieren
GPIOC->MODER |= GPIO_MODER_MODER8_0 | GPIO_MODER_MODER9_0;
// PortC.8/.9 als Ausgang setzen
GPIOC->OTYPER &= ~(GPIO_OTYPER_OT_8 | GPIO_OTYPER_OT_9);
// PortC.8/.9 als Push/Pull setzen
GPIOC->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR8 | GPIO_OSPEEDER_OSPEEDR9);
// PortC.8/.9 LowSpeed setzen
GPIOC->PUPDR &= ~(GPIO_PUPDR_PUPDR8 | GPIO_PUPDR_PUPDR9);
// PortC.8/.9 PullUp/Down deaktivieren
GPIOC->BSRR = GPIO_BSRR_BS_8 | GPIO_BSRR_BS_9;
// PortC.8/.9 highLevel treiben
}
Hast Du einen Debugger? Dann lasst die die Werte der GPIO Register
ausgeben, jenachdem wie kompiliert wuerde mit
p /x *GPIO1
oder
p /x *(GPIO_TypeDef*) 0xXXXXXXXX
0xXXXXXXXX musst Du Dir heraussuchen...
Domenik schrieb:> ich habe mir ein CMSIS-Projekt...> nicht einmal einen Port bekam ich gesetzt.
Ja, so geht das, wenn man an sowas wie ein Friseur rangeht - und die
bisherigen eingetrudelten hilflosen Antworten machen die Sache nur noch
viel schlimmer.
Also mein Rat:
1. lade dir den Keil herunter und benutze ihn in der auf 32 K
beschränkten Bastelversion. Da hat man wenigstens eine verläßliche
Basis, wo auch der Assembler mit einer erträglichen Syntax daherkommt.
Dich mit dem GCC herumschlagen kannst du später immer noch nach
Belieben.
2. schreib dir deinen Startupcode selber. Als Vorlage kannst du dir die
angehängte Quelle hernehmen und an die Gegebenheiten deines Controllers
anpassen. Dazu ist ein Blick in das RefMan nötig, denn nur dort findest
du das Speicherlayout und die tatsächlichen interruptvektoren.
3. übersetze dann deinen Startupcode mal von Hand - ähh.. per Aufruf des
Assemblers von der Kommandozeile bzw. Batchdatei.
4. schreib dir dein STM32Fblabla.h selber und füge dort NUR!! das zeugs
ein, was du tatsächlich brauchst - das sind erstmal wirklich NUR die
Adressen der in der hardware vorhandenen Register und sonst nix. Also
beispielsweise etwa so in dieser Art:
/* Ports PA..PG ..wo: RefManual ab Seite 139 */
struct T_GPIO
{ volatile unsigned long CRL; /* Config Bits 0..7 */
volatile unsigned long CRH; /* Config Bits 8..15 */
volatile unsigned long IDR; /* Port-Inputs (r/o) */
volatile unsigned long ODR; /* Port-Outputs (r/w) */
volatile unsigned long BSRR; /* Bit-SetReset:
Bits 0..15->set ODR Bits 0..15,
Bits 16..31->reset ODR Bits 0..15 */
volatile unsigned long BRR; /* Bit-Reset: Bits 0..15->reset ODR Bits
0..15 */
volatile unsigned long LCKR; /* Port lock: freeze CRL, CRH */
};
#define GPIOA ((struct T_GPIO*) 0x40010800)
#define GPIOB ((struct T_GPIO*) 0x40010C00)
#define GPIOC ((struct T_GPIO*) 0x40011000)
#define GPIOD ((struct T_GPIO*) 0x40011400)
#define GPIOE ((struct T_GPIO*) 0x40011800)
#define GPIOF ((struct T_GPIO*) 0x40011C00)
#define GPIOG ((struct T_GPIO*) 0x40012000)
Oder je nach deinem Geschmack auch ohne struct's etwa so in dieser Art:
/* Externer Bus */
#define FSMC_BCR1 (*(volatile unsigned long*) 0xA0000000)
#define FSMC_BTR1 (*(volatile unsigned long*) 0xA0000004)
5. dann mache dich an eine vorläufig ganz einfache main.c und setze dort
erstmal einen Port so auf, wie es dein Board erfordert. Mir ist es in
solchen Fällen hilfreich, mit sowas zu arbeiten:
/* Hilfsbezeichnungen zum Port-Konfigurieren */
/* Beispiel: #define wert_fuer_pa0 (mode?+conf?) */
#define input 0 /* Pin ist Input */
#define out10 1 /* Pin ist Output, max. 10 MHz schnell */
#define out2 2 /* Pin ist Output, max. 2 MHz schnell */
#define out50 3 /* Pin ist Output, max. 50 MHz schnell */
#define conf0 0 /* in:analog, out:gpio */
#define conf1 4 /* in:hi-z, out:open drain */
#define conf2 8 /* in:pullup/dn, out:alternate function */
#define conf3 12 /* in:verboten, out:alternate fkt mit open drain
*/
/* aufgedröselte Port-Konfiguationen: */
/* CNF=0 */
#define in_analog 0
#define out10_gpo 1
#define out2_gpo 2
#define out50_gpo 3
/* CNF=1 */
#define in_gpi 4
#define out10_od 5
#define out2_od 6
#define out50_od 7
/* CNF=2 */
#define in_pupd 8
#define out10_altfu 9
#define out2_altfu 10
#define out50_altfu 11
/* CNF=3 */
#define verboten 12
#define out10_altfu_od 13
#define out2_altfu_od 14
#define out50_altfu_od 15
Die Verwendung von sowas geht dann etwa so:
/* Port B: */
#define wf_PB0 (in_pupd) /* ? an Testpunkt */
#define wf_PB1 (in_pupd) /* ? an Testpunkt */
#define wf_PB2 (out50) /* out Enable für USB-rstout ??
*/
#define wf_PB3 (out50_altfu) /* JTAG TDO */
#define wf_PB4 (out50_altfu) /* JTAG RST */
#define wf_PB5 (out50_altfu) /* interrupt CLK vom PS/2 Mini-Din
*/
#define wf_PB6 (out2_altfu_od) /* I2C1 SCL (RTC8564)*/
#define wf_PB7 (out2_altfu_od) /* I2C1 SDA (RTC8564)*/
#define wf_PB8 (in_gpi) /* in DATA vom PS/2 Mini-Din */
#define wf_PB9 (in_pupd) /* ? an Testpunkt */
#define wf_PB10 (out2_altfu) /* TXD3 */
#define wf_PB11 (out2_altfu) /* RXD3 an Messerleiste TTL-Pegel
*/
#define wf_PB12 (input+conf2) /* SPI2=I2S Audio: L/R WCLK */
#define wf_PB13 (input+conf2) /* SPI2=I2S SCK */
#define wf_PB14 (input+conf2) /* SPI2=I2S MISO */
#define wf_PB15 (input+conf2) /* SPI2=I2S MOSI */
#define wf_GPIOB_CRL (wf_PB0 | (wf_PB1<<4) | (wf_PB2<<8) |
(wf_PB3<<12) | (wf_PB4<<16) | (wf_PB5<<20) | (wf_PB6<<24) |
(((unsigned)wf_PB7)<<28))
#define wf_GPIOB_CRH (wf_PB8 | (wf_PB9<<4) | (wf_PB10<<8) |
(wf_PB11<<12) | (wf_PB12<<16) | (wf_PB13<<20) | (wf_PB14<<24) |
(((unsigned)wf_PB15)<<28))
und dann hiermit hinein in die Peripherie:
GPIOB->CRL = wf_GPIOB_CRL;
GPIOB->CRH = wf_GPIOB_CRH;
So. damit hast du erstmal nen Port verwendbar gemacht (Obiges ist ein
BEISPIEL und muß auf deine Gegebenheiten übertragen werden!!!!!) und nun
kanns du wenigstens erstmal ein simples Blinky damit machen.
W.S.
Whoah. Also die Tipps von W.S. machen dich zwar nachher zum echten
Profi, der Weg zu den ersten Erfolgsergebnissen ist aber IMHO lang.
Meiner Meinung nach ist das ein späterer Schritt, wenn du ihn den
irgendwann überhaupt gehen musst.
Mein Tipp: Verwendet die Stm Peripheral Lib oder die Stm32 Cube Library.
Es gibt auch sehr viele Beispiele von ST für jeden Controller wie du
dich rantasten kannst. Vorteil: Man neigt dazu nicht alles zu bedenken,
die Libraries geben einem da einiges auf den Weg, die Beispiele auch.
Noch besser für den Einstieg: Fertige Projekte nutzen und eine gute
Entwicklungsumgebung mit Debugger Unterstützung. Hier z.B. gibts
Beispiele http://mikrocontroller.bplaced.net/wordpress/?page_id=744. Die
Projekte sind mit CooCox nutzbar.
Mal so eine Frage:
Wieso macht sich heute einer noch die Mühe, einen ARM ohne BSP zu
programmieren? STM hat eine sehr sehr gute Standard Peripheral Library.
Mit dieser habe ich schon mehrere Industrieprojekte umgesetzt. Klar
musste man an gewissen Stellen optimieren...
Hier ist der Code für einen STM32F4xx (da der TO nicht weiter auf den
Typ eingeht.). Sollte aber innerhalb von 30sec auf JEDEN Cortex von STM
portierbar sein.
// ODER, was je nach Einstellungen effizienter umgesetzt wird
22
/* Set PC9 */
23
GPIOC->BSRRL=GPIO_Pin_9;
24
/* Reset PC9 */
25
GPIOC->BSRRH=GPIO_Pin_9;
Aber wenn man jedesmal das Rad neu erfinden will... Man kennt dann zwar
den Controller perfekt (jedes Bit), aber das zahlt heute niemand mehr.
(Meine Meinung, so jetzt könnt Ihr widersprechen).
Patrick B. schrieb:> Wieso macht sich heute einer noch die Mühe, einen ARM ohne BSP zu> programmieren? STM hat eine sehr sehr gute Standard Peripheral Library.
Wiebitte?
Diese hirnrissige ST-Lib ist der allerletzte Schund. Anstatt für
irgendetwas einen ordentlichen Treiber zu liefern, bewirkt sie nur
eines: eine gewaltige Schaumschlägerei ohne Sinn und Verstand.
Das sieht man hier sehr deutlich:
Patrick B. schrieb:> /* Configure PC9 and PC8 in output pushpull mode */> GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;> GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;> GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;> GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;> GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;> GPIO_Init(GPIOC, &GPIO_InitStructure);
Überlege doch mal, was da bei einem 120 Pinner so an Code zusammenkommt,
bloß dazu, daß die lumpigen GPIO's aufgesetzt werden sollen.
Ich geb dir hier mal ne Gegendarstellung:
/* Pin-Funktionen aufsetzen */
GPIOA->CRL = wf_GPIOA_CRL;
GPIOA->CRH = wf_GPIOA_CRH;
GPIOB->CRL = wf_GPIOB_CRL;
GPIOB->CRH = wf_GPIOB_CRH;
GPIOC->CRL = wf_GPIOC_CRL;
GPIOC->CRH = wf_GPIOC_CRH;
GPIOD->CRL = wf_GPIOD_CRL;
GPIOD->CRH = wf_GPIOD_CRH;
GPIOE->CRL = wf_GPIOE_CRL;
GPIOE->CRH = wf_GPIOE_CRH;
GPIOF->CRL = wf_GPIOF_CRL;
GPIOF->CRH = wf_GPIOF_CRH;
GPIOG->CRL = wf_GPIOG_CRL;
GPIOG->CRH = wf_GPIOG_CRH;
/* Pin-Remap */
AFIO->MAPR = wf_AFIO_MAPR;
Damit werden ALLE Pins eines STM32F103 aufgesetzt - und das sind
verdammt viele. Überlege mal, was du mit deinem oben zitierten Gehampel
mit GPIO_Initstructure.xyz veranstalten müßtest...
Ganz ähnlich sieht das bei peripheren Cores aus. Versuche mal, mit der
ST-Lib einen tatsächlich zuverlässig arbeitenden USB-VCP aufzusetzen. Da
landet tonnenweise sinnloser Code in deinem Projekt und den eigentlichen
VCP mußt du trotzdem noch selber designen.
Patrick B. schrieb:> Aber wenn man jedesmal das Rad neu erfinden will... Man kennt dann zwar> den Controller perfekt (jedes Bit), aber das zahlt heute niemand mehr.> (Meine Meinung, so jetzt könnt Ihr widersprechen).
ja, deine Meinung. Es wäre natürlich viel einfacher, wenn so ein elender
Hersteller seine Controller mit besseren Quellcodes unterstützen würde
- aber bei ST ist dies definitiv NICHT der Fall.
Abgesehen erwartet ein Chef tatsächlich, daß jemand wie du den von dir
verwendeten Controller kennt undnicht wie ein Kind mit Bauklötzchen
herumspielt, dafür einen teureren Chip braucht und anschließend trotzdem
stundenlang vor dem Debugger sitzt - eben wegen fehlenen Verstehens ganz
am Anfang der Entwicklung.
Merke: wer von den Zutaten zu wenig versteht, sitzt später die dreifache
Zeit am Debugger.
W.S.
W.S. schrieb:> Überlege doch mal, was da bei einem 120 Pinner so an Code zusammenkommt,> bloß dazu, daß die lumpigen GPIO's aufgesetzt werden sollen.
Ist doch egal, die STM32 haben bis zu Megabytes an Flash. Und da die Pin
Initialisierung typischerweise eh nur 1x beim starten läuft, macht die
1ms auch nix.
W.S. schrieb:> Diese hirnrissige ST-Lib ist der allerletzte Schund.
Ja. Aber den kompletten Header für alle Peripherie-Definitionen (bis zu
10000 Zeilen) selbst zu schreiben ist nicht hirnrissig? Vor allem wenn
du die dann genauso schlecht machst wie die von ARM/ST (also mit #define
statt Konstante usw.)? Come on.
W.S. schrieb:> dafür einen teureren Chip braucht und anschließend trotzdem> stundenlang vor dem Debugger sitzt
Du sitzt lieber wochenlang am schreiben von Headern, die man auch vom
Hersteller herunter laden könnte?
W.S. schrieb:> 2. schreib dir deinen Startupcode selber.
Hier gilt das selbe wie für den Header - sinnlose Arbeit
... Der Fehler liegt hier höchstwahrscheinlich nicht an einem kaputten
Header oder Startup-Code von ST. Wenn schon falsch gemessen, falsch
gestartet, falsche Compiler-Optionen...
PS: Wenn man schon grundsätzlich keinen fremden Code akzeptiert, sollte
man es wenigstens selber besser können!
Programmierer schrieb:> Hier gilt das selbe wie für den Header - sinnlose Arbeit
Für dich scheint alles, was irgendwie nach eigener Arbeit aussieht, eine
sinnlose Arbeit zu sein. Für solche Leute gibt es ne Reihe von weniger
schönen Bezeichnungen.
OK, wenn du BWLler bist, dann wäre es aus deiner Sicht das Beste, die
gesamte Arbeit an ein dafür geeignetes Ingenieurbüro zu vergeben. Da
brauchst du dich garnicht mehr um Sachdetails zu kümmern, sondern nur um
andere dir wichtigere Dinge.
Also:
1. Wenn ein Hersteller eine ordentliche prozessortyp.h liefert, dann
kann man die auch nehmen. Das ist bei ST definitiv NICHT der Fall. Von
deiner Behauptung "(bis zu 10000 Zeilen)" ist man aber vernünftigerweise
meilenweit entfernt. Hab hier grad einen .h von NXP vorliegen, 1136
Zeilen und 74 K Gesamtgröße. Geht doch - da liegst du mit deinen 10000
Zeilen krass daneben.
2. Für die Verwendung in konkreten Projekten macht man sich auch einen
sinnvollen Startupcode, denn das, was gemeinhin bei den diversen
Toolchaines mitgeliefert wird, ist "for evaluation only" und nicht
wirklich praxistauglich. Siehe Exceptionhandler, die nur aus einem B .
bestehen. Wenn du mir sowas in einem konkreten Projekt liefern würdest,
gäbe es ne saftige Abreibung für dich von mir. Ich stell mir grad vor,
das ABS in meinem Wagen würde bei einem Gewitter in der Nähe eben mal
auf nen B . aufschlagen bis zum nächsten Start des Wagens...
3. Sowas wie ein wirklich guter Startupcode und eine benutzbare
prozessor.h sind quasi Anschaffungen für's Prozessorleben. Eine auf
10000 Zeilen aufgeblasene und mit tausenderlei Bezeichnern angefüllte .h
ist hingegen schlecht bis unbenutzbar, weil man in all dem überflüssigen
Zeug praktisch ersäuft. Ist kontraproduktiv und extrem fehlerträchtig -
man sucht sich halbtot und benutzt dann doch versehentlich hie und da
mal was völlig Verkehrtes.
4. Und nochwas: wir reden hier von C und da gibt es #define und das
war's. Punkt.
Aber nochmal zu deinem Beitrag: Anstatt herumzunörgeln und bloß die
eigene Bequemlichkeit zur Schau zu stellen, wäre ein positiver
Sachbeitrag zum Lösen des Problems des TO wesentlich sinnreicher
gewesen.
W.S.
W.S. schrieb:> Wiebitte?> Diese hirnrissige ST-Lib ist der allerletzte Schund. Anstatt für> irgendetwas einen ordentlichen Treiber zu liefern, bewirkt sie nur> eines: eine gewaltige Schaumschlägerei ohne Sinn und Verstand.> Das sieht man hier sehr deutlich:
Ok, dafür sind aber die Erratas, die Datenblätter und die App-Notes von
NXP absoluter Müll.
W.S. schrieb:> Damit werden ALLE Pins eines STM32F103 aufgesetzt - und das sind> verdammt viele. Überlege mal, was du mit deinem oben zitierten Gehampel> mit GPIO_Initstructure.xyz veranstalten müßtest
Mhm, mahl überlegen...
1
#define RCC_AHB1Periph_GPIO_ALL 0x1FF // Neu definieren
/* Configure PC9 and PC8 in output pushpull mode */
10
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;
11
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
12
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
13
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
14
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
15
GPIO_Init(GPIOA,&GPIO_InitStructure);
16
GPIO_Init(GPIOB,&GPIO_InitStructure);
17
GPIO_Init(GPIOC,&GPIO_InitStructure);
18
GPIO_Init(GPIOD,&GPIO_InitStructure);
19
GPIO_Init(GPIOE,&GPIO_InitStructure);
20
GPIO_Init(GPIOF,&GPIO_InitStructure);
21
GPIO_Init(GPIOG,&GPIO_InitStructure);
22
GPIO_Init(GPIOI,&GPIO_InitStructure);
=> 22 Zeilen gegen 18 (wobei das Clockmanagement bei dir noch fehlt),
übersichtlich (verständlicher und lesbarer/intepretierbarer Code), und
als nettes Feature gibts noch die Assertion für jeden Fall (also die
Redundanz steigt...).
W.S. schrieb:> Versuche mal, mit der> ST-Lib einen tatsächlich zuverlässig arbeitenden USB-VCP aufzusetzen. Da> landet tonnenweise sinnloser Code in deinem Projekt und den eigentlichen> VCP mußt du trotzdem noch selber designen.
Komisch, bei mir lief das ohne Probleme. Musste auch nichts erweitern,
da die Lib komplett mit DMA- und Interrupt-Funktionalitäten ausgerüstet
ist.
W.S. schrieb:> 2. Für die Verwendung in konkreten Projekten macht man sich auch einen> sinnvollen Startupcode
Das gilt dann aber auch für das Interrupt handling und das ganze
Programm. Nur der Startup-Code macht dein Controller nicht
"unsterblich".
W.S. schrieb:> Aber nochmal zu deinem Beitrag: Anstatt herumzunörgeln und bloß die> eigene Bequemlichkeit zur Schau zu stellen, wäre ein positiver> Sachbeitrag zum Lösen des Problems des TO wesentlich sinnreicher> gewesen.
Wurde in etwa 3-facher Ausführung mit unterschiedlichen Ansätzen zur
Verfügung gestellt. Und wir kommen vom Thema ab, so für mich ist hier
Schluss.
W.S. schrieb:> Programmierer schrieb:>> Hier gilt das selbe wie für den Header - sinnlose Arbeit>> Für dich scheint alles, was irgendwie nach eigener Arbeit aussieht, eine> sinnlose Arbeit zu sein. Für solche Leute gibt es ne Reihe von weniger> schönen Bezeichnungen.
Ich verwende meine Arbeitskraft lieber auf sinnvolle Dinge. Zum x.ten
Mal exakt das gleiche (!!) zu schaffen was schon existiert ist sonnlos.
> Also:> 1. Wenn ein Hersteller eine ordentliche prozessortyp.h liefert, dann> kann man die auch nehmen. Das ist bei ST definitiv NICHT der Fall.
Interessant. Wo genau ist jetzt der Unterschied zwischen der
prozessortyp.h von ST und deinem Vorschlag? Bis darauf dass ST
wenigstens sinnvollerweise die Adressen berechnet, sodass man sie
leichter anpassen kann?
> Von> deiner Behauptung "(bis zu 10000 Zeilen)" ist man aber vernünftigerweise> meilenweit entfernt.
Stimmt, die stm32f4xx.h ist nur 9194 Zeilen lang.
> Hab hier grad einen .h von NXP vorliegen, 1136> Zeilen und 74 K Gesamtgröße. Geht doch - da liegst du mit deinen 10000> Zeilen krass daneben.
Ja, es gibt auch kleine Controller. Und was machst du wenn du einen
STM32F4 hast?
> 2. Für die Verwendung in konkreten Projekten macht man sich auch einen> sinnvollen Startupcode, denn das, was gemeinhin bei den diversen> Toolchaines mitgeliefert wird, ist "for evaluation only" und nicht> wirklich praxistauglich.> Siehe Exceptionhandler, die nur aus einem B .> bestehen. Wenn du mir sowas in einem konkreten Projekt liefern würdest,> gäbe es ne saftige Abreibung für dich von mir.>
Ich stelle mir gerade vor wie du vermutlich alter verbitterter Sack, der
nach 30 Jahren Anstellung immer noch auf dem untersten
Code-Monkey-Posten hockt, deinem vermutlich dann vorgesetzten Software
Architect eine "Abreibung" geben willst :3
Was hat das "b ." im Startupcode verloren? Nichts. Die Exception-Handler
kommen in den eigenen C/C++ Code. Das interessiert den Startupcode
überhaupt nicht.
> Ich stell mir grad vor,> das ABS in meinem Wagen würde bei einem Gewitter in der Nähe eben mal> auf nen B . aufschlagen bis zum nächsten Start des Wagens...
Genau, das Gewitter löst ja freundlicherweise einen Lightning_Handler
aus, den man einfach nur behandeln muss um sämtliche EMV-Probleme aus
der Welt zu schaffen. Únd das muss natürlich im Startupcode sein, weil
Interrupthandler im C/C++ Code ja, hm, uncool sind. Wenn "Alle Interrupt
Handler im Startupcode behandeln" dein Konzept zur Sicherheit ist, dann
gute Nacht.
> 3. Sowas wie ein wirklich guter Startupcode und eine benutzbare> prozessor.h sind quasi Anschaffungen für's Prozessorleben. Eine auf> 10000 Zeilen aufgeblasene und mit tausenderlei Bezeichnern angefüllte .h> ist hingegen schlecht bis unbenutzbar, weil man in all dem überflüssigen> Zeug praktisch ersäuft. Ist kontraproduktiv und extrem fehlerträchtig -> man sucht sich halbtot und benutzt dann doch versehentlich hie und da> mal was völlig Verkehrtes.
Genau, alle Werte aus dem Manual abschreiben und in die prozessor.h
schreiben ist total nicht fehleranfällig. Die prozessortyp.h sind
typischerweise aus der SVD generiert o.ä. ...
Ich verrate dir mal einen Geheimtip: Anständige IDE's haben
Codenavigation und Strg+F. Da sind ein paar Tausend Zeilen Library-Code
überhaupt kein Problem. Bei vielen Frameworks zB am PC hat es noch viel
mehr Bezeichner, und da hat auch (außer dir?) Probleme mit
durchzublicken.
> 4. Und nochwas: wir reden hier von C und da gibt es #define und das> war's. Punkt.
Es gibt "static const". Und selbst wenn man meint dumme Textersetzungen
aus der Zeit er Makro-Assembler verwenden zu müssen, kann man sie
wenigstens korrekt anwenden, sprich überall Klammern hinpacken.
> Aber nochmal zu deinem Beitrag: Anstatt herumzunörgeln und bloß die> eigene Bequemlichkeit zur Schau zu stellen, wäre ein positiver> Sachbeitrag zum Lösen des Problems des TO wesentlich sinnreicher> gewesen.
Mein Beitrag war auch wesentlich hilfreicher und bezogen auf das
eigentliche Problem, anstatt deiner üblicher Stänkerei das Rad zum 100.
Mal neu zu erfinden.
W.S. schrieb:> Ganz ähnlich sieht das bei peripheren Cores aus. Versuche mal, mit der> ST-Lib einen tatsächlich zuverlässig arbeitenden USB-VCP aufzusetzen. Da> landet tonnenweise sinnloser Code in deinem Projekt und den eigentlichen> VCP mußt du trotzdem noch selber designen.>
und du hast deinen USB-VCP Code komplett selbst geschrieben ?
solange du davon nicht einen Teil hier postest
(damit man ihn mit dem "Sinnlosen-Code" von ST vergleichen kann)
sage ich da nur : LOL