Hey ich möchte einen Stm32 Microcontroller programmieren und das funktioniert eigtl alles ganz gut. Der Code funktioniert zwar(LEDS blinken), aber ich möchte die Makros der Header Datei mit pointern die auf das Register zeigen ersetzten: Hier mal der Code. #include "stm32f10x.h" int main() { RCC->APB2ENR |= (1<<4); GPIOC->CRL |= ( (1<<16) | (1<<17) ); GPIOC->CRL &= ~( (1<<18) | (1<<19)); GPIOC->CRL |= ( (1<<20) | (1<<21) ); GPIOC->CRL &= ~( (1<<22) | (1<<23) ); GPIOC->CRL |= ( (1<<24) | (1<<25) ); GPIOC->CRL &= ~( (1<<26) | (1<<27) ); while(1){ int i = 0; GPIOC->BSRR = (1<<5); GPIOC->ODR |= (1<<4); //GPIOC->ODR = 1<<( while(i < 2000000){ i++; } GPIOC->BSRR = (1<<21); GPIOC->ODR &= ~(1<<4); //GPIOC->ODR = i = 0; while(i < 2000000){ i++; } } } RCC-APB2ENR soll zum Beispiel mit einem Pointer ersetzt werden, der auf diese Adresse zeigt. Ich habe mal im Datenblatt nachgeschaut nur versteh ich nicht auf welcher Adresse der Bus liegt. Hier noch der Link zum Datenblatt: https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwiG3qv-nervAhVE9IUKHSZ2AJEQFjABegQIAxAD&url=https%3A%2F%2Fwww.st.com%2Fresource%2Fen%2Freference_manual%2Fcd00246267-stm32f100xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf&usg=AOvVaw2GsY3qPMGEaY6As6a7xMbJ Ich hoffe ihr könnt mir helfen.
Guck doch einfach von den CMSIS headern ab, z.B. der Datei stm32f100xb.h: Die Basisadresse von RCC ergibt sich aus:
1 | #define PERIPH_BASE 0x40000000U
|
2 | #define AHBPERIPH_BASE (PERIPH_BASE + 0x00020000U)
|
3 | #define RCC_BASE (AHBPERIPH_BASE + 0x00001000U)
|
4 | #define RCC ((RCC_TypeDef *)RCC_BASE)
|
0x40000000 + 0x00020000 + 0x00001000 = 40021000 Dazu addierst du die Adresse des Registers innerhalb der Struktur:
1 | typedef struct |
2 | {
|
3 | __IO uint32_t CR; |
4 | __IO uint32_t CFGR; |
5 | __IO uint32_t CIR; |
6 | __IO uint32_t APB2RSTR; |
7 | __IO uint32_t APB1RSTR; |
8 | __IO uint32_t AHBENR; |
9 | __IO uint32_t APB2ENR; |
10 | __IO uint32_t APB1ENR; |
11 | __IO uint32_t BDCR; |
12 | __IO uint32_t CSR; |
13 | |
14 | |
15 | uint32_t RESERVED0; |
16 | __IO uint32_t CFGR2; |
17 | } RCC_TypeDef; |
APB2ENR ist das siebte 32 bit Register innerhalb der Struktur, also addierst dazu 6 mal 4 Bytes. 40021000 + 6 * 4 = 0x40021018 Das müsste die Adresse von dem Register RCC->APB2ENR sein, falls ich mich jetzt nicht verrechnet habe. Gibt es einen vernünftigen Grund, auf die CMSIS header zu verzichten?
Stefan ⛄ F. schrieb: > Gibt es einen vernünftigen Grund, auf die CMSIS header zu verzichten? Die Lizenz? War mal BSD, jetzt ist es nur noch ein Link auf eine bunte Seite irgendwo im Internet.
Bauform B. schrieb: > Die Lizenz? War mal BSD, jetzt ist es nur noch ein Link auf eine bunte > Seite irgendwo im Internet. Das ist die Lizenz direkt aus dem Paket. Ist sehe darin nichts hinderliches.
Stefan ⛄ F. schrieb: > 0x40000000 + 0x00020000 + 0x00001000 = 40021000 diese 40021000 steht auch direkt im Handbuch (RM0041), s.o. > Dazu addierst du die Adresse des Registers innerhalb der Struktur: Das muss wohl sein, wenn man die struct nicht benutzen will. Das wäre mir dann doch zu umständlich. Ich mache einen Kompromiss und benutze zwar eine ähnliche struct, aber keine CMSIS-#defines. Also zeigt der Pointer auf die 40021000 aus dem Manual und der GPIO-Takt wird so eingeschaltet:
1 | RCC->IOPCEN = 1; |
APB2ENR usw. schreibe ich nicht mit, das ist ja in der struct definiert, genau wie das Bit IOPCEN. Deshalb muss ich mir nicht merken, dass der Takt mit 1<<4 eingeschaltet wird und kann APB1 und AHB2 usw. nicht leicht verwechseln.
:
Bearbeitet durch User
Ist das wirklich so kryptisch bei den F100er Prozessoren? Ich habe einen H7, und da schreibe ich so etwas wie HAL_GPIO_WritePin(GPIOC, ui_PinBitmask, GPIO_PIN_SET); oder zum Abfragen State = HAL_GPIO_ReadPin(GPIOC,ui_PinBitmask); Finde ich über sichtlicher als GPIOC->ODR &= ~(1<<4); Warum gibt es für die F100 nicht so wtwas wie HAL. Letztendlich optimiert der Compiler ja eh auf den gleichen Code.
PittyJ schrieb: > Warum gibt es für die F100 nicht so wtwas wie HAL. Erstens benutzt die HAL natürlich die CMSIS-Definitionen, und zweitens... > Letztendlich optimiert der Compiler ja eh auf den gleichen Code. ... tut er das nicht. Die HAL gibt deutlich größeren und langsameren Code, und abgesehen davon nagelt sie Dich auch auf STM32 fest, weil dieser vendor lock-in der eigentliche Sinn dahinter ist.
In der CMSIS gibt es auch hilfreiche Makros wie
1 | SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN); |
2 | CLEAR_BIT(RCC->CR, RCC_CR_PLLON); |
3 | WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BS5); |
4 | MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSI); |
PittyJ schrieb: > Ist das wirklich so kryptisch bei den F100er Prozessoren? > Ich habe einen H7, und da schreibe ich so etwas wie > HAL_GPIO_WritePin(GPIOC, ui_PinBitmask, GPIO_PIN_SET); > Finde ich über sichtlicher als > GPIOC->ODR &= ~(1<<4); Das kannst du doch schreiben wie du willst, bei jedem Prozessor. Nur weil der Justin das oben so geschrieben hat, musst du das doch nicht nachmachen. Ersetze mal das 1<<4 durch etwas wie deine ui_PinBitmask. Schon besser. Im nächsten Schritt ersetze das noch durch einen Namen wie led_motor. Schon kann das jeder lesen, auch wenn er HAL nicht kennt. Und wenn er nicht sicher ist, was ODR genau ist, kann er das in dem selben Manual nachlesen, das er sowieso täglich benutzt.
Bauform B. schrieb: > PittyJ schrieb: >> Ist das wirklich so kryptisch bei den F100er Prozessoren? >> Ich habe einen H7, und da schreibe ich so etwas wie >> HAL_GPIO_WritePin(GPIOC, ui_PinBitmask, GPIO_PIN_SET); > >> Finde ich über sichtlicher als >> GPIOC->ODR &= ~(1<<4); > > Das kannst du doch schreiben wie du willst, bei jedem Prozessor. Nur > weil der Justin das oben so geschrieben hat, musst du das doch nicht > nachmachen. Ersetze mal das 1<<4 durch etwas wie deine ui_PinBitmask. > Schon besser. Im nächsten Schritt ersetze das noch durch einen Namen wie > led_motor. > > Schon kann das jeder lesen, auch wenn er HAL nicht kennt. Und wenn er > nicht sicher ist, was ODR genau ist, kann er das in dem selben Manual > nachlesen, das er sowieso täglich benutzt. Für mich ist nur nur so: Wenn man nach 5 Jahren wieder in seinen Source-Code schauen muss, weil ein Fehler festgestellt wird, dann weiss man bei HAL_GPIO_WritePin() sofort was dort passiert. Bei ODR muss man dann noch das Handbuch aufmachen und nachlesen, was war jetzt ODR. Also sucht man erst mal das Handbuch, dann nach dem Register ..... Und bei mir kommt es öfters vor, dass ich in uralten Projekten noch Änderungen vornehmen muss. Da freut man sich über jeden Kommentar und sinnvolle Benamung.
PittyJ schrieb: > Und bei mir kommt es öfters vor, dass ich in uralten Projekten noch > Änderungen vornehmen muss. Da freut man sich über jeden Kommentar und > sinnvolle Benamung. Meine Rede! Für die ältesten Funktionen könnte ich ein H-Kennzeichen beantragen, die sind in gutem Originalzustand ;) Nur bei der Suche nach ODR vs HAL_GPIO_WritePin() geht es mir genau umgekehrt wie dir.
PittyJ schrieb: > Für mich ist nur nur so: Wenn man nach 5 Jahren wieder in seinen > Source-Code schauen muss, weil ein Fehler festgestellt wird, dann weiss > man bei HAL_GPIO_WritePin() sofort was dort passiert. Bei ODR muss man > dann noch das Handbuch aufmachen und nachlesen, was war jetzt ODR. Absolut richtig. Deswegen sollte man diese Aufrufe in eine Funktion kapseln, die z.B. Pumpe_an() und Pumpe_aus() heißt.
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.