Forum: Mikrocontroller und Digitale Elektronik C ARM Cortex Mikrocontroller PIN ansteuern


von Raphael K. (wolly300)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich programmiere jetzt seit einiger Zeit mit ARM Prozessoren.

Angefangen habe ich mit einem STM32F401RE Board und bin jetzt bei einem 
eigenen PCB mit STM32F429BI Mikrocontroller.

Ich arbeite mit der JumpStart C for Cortex-M IDE mit eigener Cortex-M 
API.

Mit der API kann man ganz einfach einen pin mit:

portb.MakeOutput(10, OSPEED_VERYHIGH);

und

portb.Set(10);
portb.Clear(10);

ansteuern.

Damit habe ich auch einen I2C Bus programmiert. Jetzt will ich das ganz 
auf richtiges C Pin ansteuern um programmieren.

Bisher kann ich mit:

GPIOB ->BSRRL | GPIO_BSRR_BS10;
GPIOB ->BSRRH | GPIO_BSRR_BS10;

die Pins hoch und runter setzen (Habe ich mit der angehängten Datei 
gemacht).
Ich weiß aber, das man dass auch mit z.B.:

SDA = 1;
SDA = 0;

Pins setzen kann.
Ich würde das richtige Register ansteuern und die damit zusammenhängende 
Hardware Zugriffe gerne lernen.
Wie genau erstelle ich jetzt solche Hardware Zugriffe ?

Vielen Dank für eure Hilfe

: Verschoben durch Moderator
von abc (Gast)


Lesenswert?

Raphael K. schrieb:
> Wie genau erstelle ich jetzt solche Hardware Zugriffe ?

Schau dir am besten mal eine beliebige HAL an (z.B. libopencm3 oder die 
offizielle ST-HAL). Dort kannst du alle notwendigen Registeraufrufe 
ableiten.

Beitrag #5969401 wurde von einem Moderator gelöscht.
von Bernd K. (prof7bit)


Lesenswert?

low level (nur zum verstehn was vor sich geht)

für ein 401RE Nucleo board:
1
#include <stm32f401xe.h>
2
3
4
/*
5
 * The green LED is connected to port A5,
6
 * -> see schematic of NUCLEO-F401RE board
7
 */
8
#define LED_GPIO        GPIOA
9
#define LED_PIN         5
10
11
12
/**
13
 * Quick 'n' dirty delay
14
 *
15
 * @param time the larger it is the longer it will block
16
 */
17
static void delay(unsigned time) {
18
    for (unsigned i=0; i<time; i++)
19
        for (volatile unsigned j=0; j<20000; j++);
20
}
21
22
23
/**
24
 * Hello world blinky program
25
 *
26
 * @return never
27
 */
28
int main(void) {
29
30
    /*
31
     * Turn on the GPIOA unit,
32
     * -> see section 6.3.9 in the manual
33
     */
34
    RCC->AHB1ENR  |= RCC_AHB1ENR_GPIOAEN;
35
36
37
    /*
38
     * Set LED-Pin as output
39
     * Note: For simplicity this assumes the pin was configured
40
     * as input before, as it is when it comes out of reset.
41
     * -> see section 8.4.1 in the manual
42
     */
43
    LED_GPIO->MODER |= (0b01 << (LED_PIN << 1));
44
45
46
    while(1) {
47
48
        /*
49
         * LED on (drive the pin high)
50
         * A GPIO output pin is set to high by writing 1 to the
51
         * corresponding bit in the lower half of the BSRR register
52
         * -> see section 8.4.7 in the manual
53
         */
54
        LED_GPIO->BSRR = (1 << LED_PIN);
55
56
        delay(200);
57
58
        /*
59
         * LED off (drive the pin low)
60
         * A GPIO output pin is set to low by writing 1 to the
61
         * corresponding bit in the upper half of the BSRR register
62
         * -> see section 8.4.7 in the manual
63
         */
64
        LED_GPIO->BSRR = (1 << (LED_PIN + 16));
65
66
        delay(200);
67
    }
68
}

von Raphael K. (wolly300)


Lesenswert?

abc schrieb:
> Raphael K. schrieb:
>> Wie genau erstelle ich jetzt solche Hardware Zugriffe ?
>
> Schau dir am besten mal eine beliebige HAL an (z.B. libopencm3 oder die
> offizielle ST-HAL). Dort kannst du alle notwendigen Registeraufrufe
> ableiten.

Gibt es da auch genauere Infos ?

Die HAL von ST hat mehr als 1800 Seite!!!

https://www.st.com/content/ccc/resource/technical/document/user_manual/2f/71/ba/b8/75/54/47/cf/DM00105879.pdf/files/DM00105879.pdf/jcr:content/translations/en.DM00105879.pdf

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Raphael K. schrieb:
> Ich weiß aber, das man dass auch mit z.B.:
>
> SDA = 1;
> SDA = 0;
>
> Pins setzen kann.

Und woher weißt du das, bzw. glaubst du, das zu wissen?

Also, die GPIO-Peripherie-Cores sind von Hersteller zu Hersteller und 
Chipfamilie zu Chipfamilie durchaus unterschiedlich.

Was also beim einen funktioniert, muß beim anderen ganz anders gemacht 
werden. Das solltest du dir gut merken.

Bei vielen Chip-Sorten gibt es mehrere Methoden, Pins zu setzen. Eine 
davon besteht darin, daß es zusätzlich zu den eigentlichen 
GPIO-Registern noch ein Array gibt (komme grad nicht auf den Namen), wo 
jedes einzelne Pin einem Byte, Word oder DWord zugeordnet ist, so daß 
man dort tatsächlich so schreiben kann wie du oben. Aber das gibt's 
nicht ÜBERALL.

Also lies dir das GPIO-Kapitel im RefManual für deinen Chip gründlich 
durch, um zu erfahren, was man da so alles machen kann.

W.S.

von Bernd K. (prof7bit)


Lesenswert?

Raphael K. schrieb:
>> Schau dir am besten mal eine beliebige HAL an (z.B. libopencm3 oder die
>> offizielle ST-HAL). Dort kannst du alle notwendigen Registeraufrufe
>> ableiten.
>
> Gibt es da auch genauere Infos ?
>
> Die HAL von ST hat mehr als 1800 Seite!!!

Noch genauer als 1800 Seiten? Die nächsthöhere Genauigkeitsstufe wäre 
wohl in den Code der HAL selber reinzuschauen, dort steht alles 
supergenau drin, sogar das was in den 1800 Seiten nicht steht.

von Stefan F. (Gast)


Lesenswert?

Lies mal diesen Absatz:
http://stefanfrings.de/stm32/stm32f3.html#digital

Das wurde für den STM32F3 geschrieben, aber ich denke, es trifft auf den 
STM32F4 ebenso zu.

Das Anwendungsbeispiel steht weiter oben auf der Seite:
http://stefanfrings.de/stm32/stm32f3.html#delayloop

Es verwendet die CMSIS Makros SET_BIT, MODIFY_REG und WRITE_REG, 
die auch in HAL Projekten zur Verfügung stehen, weil die HAL auf CMSIS 
aufbaut. Diese (und ein paar weitere) Makros sind von ARM 
standardisiert.

Die konkreten Register auf die man zugreifen muss sind allerdings 
Hersteller-Spezifisch. Sie sind in 
https://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf 
Kapitel 8 (General-purpose I/Os GPIO) beschrieben.

von Christopher J. (christopher_j23)


Lesenswert?

Stefanus F. schrieb:
> Es verwendet die CMSIS Makros SET_BIT, MODIFY_REG und WRITE_REG, die
> auch in HAL Projekten zur Verfügung stehen, weil die HAL auf CMSIS
> aufbaut. Diese (und ein paar weitere) Makros sind von ARM
> standardisiert.

Ich meine (d.h. bin mir nicht ganz sicher), dass die Makros SET_BIT, 
MODIFY_REG, etc. eine Dreingabe von ST sind und nicht CMSIS-Standard. 
Man kann sie sich natürlich jederzeit für einen Controller eines anderen 
Herstellers anlegen. Ist ja alles kein Hexenwerk.

von Bernd K. (prof7bit)


Lesenswert?

Christopher J. schrieb:
> Ich meine (d.h. bin mir nicht ganz sicher), dass die Makros SET_BIT,
> MODIFY_REG, etc. eine Dreingabe von ST sind und nicht CMSIS-Standard.
> Man kann

...natürlich auch komplett auf diesen Blödsinn verzichten denn die 
machen mehr Tipparbeit und Obfuskation als sie nützen.

von Christopher J. (christopher_j23)


Lesenswert?

Bernd K. schrieb:
>> Man kann
>
> ...natürlich auch komplett auf diesen Blödsinn verzichten denn die
> machen mehr Tipparbeit und Obfuskation als sie nützen.

oder so. Jeder wie er mag ;)

von Stefan F. (Gast)


Lesenswert?

Christopher J. schrieb:
> Ich meine (d.h. bin mir nicht ganz sicher), dass die Makros SET_BIT,
> MODIFY_REG, etc. eine Dreingabe von ST sind und nicht CMSIS-Standard.

Hmm, jetzt wo du es sagst... guck nach....scheint zu stimmen.

Die Makros sind trivial und daher sicher Geschmackssache.

MODIFY_REG finde ich hilfreich, um besser lesbaren Code zu schreiben.

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
Noch kein Account? Hier anmelden.