STM32 Ein- und Ausgabe von digital Informationen

Hier sind die wesentlichen Befehle zur Ein- und Ausgabe von digitalen Werten beim STM32 Prozessor beschrieben.

Hier am Beispiel des STM32F107VC Prozessors. Die Port-Bits fangen bei Pin_0(!) an. GPIO_Pin_0 ist der Prozessorpin 15.

Bitausgabe

Setzen eines einzelnen Bitregisters direkt: (Pin6) auf Port C:

Bit 6 auf logisch 1 setzen: GPIOC->BSRR = GPIO_Pin_6;

Bit 6 auf logisch 0 setzen: GPIOC->BRR = GPIO_Pin_6;

Bit 6 invertieren: GPIOC->ODR ^= GPIO_Pin_6;

oder alternativ die Orginalfunktionen der STM Lib.

Bit 6 auf logisch 1 setzen: GPIO_SetBits(GPIOC,GPIO_Pin6)

Bit 6 auf logisch 0 setzen: GPIO_ResetBits(GPIOC,GPIO_Pin6)

Bit 6 und Bit 9 auf logisch 0 setzen: GPIO_ResetBits(GPIOC, GPIO_Pin6|GPIO_Pin9)

Die direkten Funktionen sind naturgemäß erheblich schneller. Allerdings müsste sich jemand den erzeugten Assembler Code anschauen ob es wirklich so ist.

Portausgabe

Die IO-Ports des STM32 sind jeweils 16 bit breit. Wenn man also einen ganzen Port beschreiben will muss man auch eine Funktion verwenden die 16 Bit variablen verwendet. Dies ist:

Write complete port : GPIO_Write(GPIOC,val);

wobei val eine 16bit variable uint16_t val

sein muss. Oder wieder einzelne Bits setzen mit folgendem Befehl:

GPIO_Write(GPIOC, GPIO_Pin6 | GPIO_Pin9);

Um den Zustand eines Ausgangsports zurückzulesen (weil man nicht weiß wie er gerade gesezt ist) kann man folgende Funktion verwenden:

uint16_t val;

val = GPIO_ReadOutputData(GPIOC, GPIO_Pin6 | GPIO_Pin9);

Achtung diese Funktion liest nur die (!) Setzregister NICHT den Ausgangszustand.

Biteingabe

Einlesen des kompletten Port C:

port_data = GPIO_ReadInputData(GPIOC);

Achtung: Beim Lesen eines Bits kann es passieren dass anscheinend nichts gelesen wird oder das Bit nicht erkannt wird. Die Ursache liegt in den vielfältigen Programmiermöglichkeiten die der STM32 bietet. Man muss vor der Verwendung definieren welche Art der Input sein soll. Hier die dazu benötigten Flags:

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // Pin Floating
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //Pin with pull up R
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //Pin with pull down R

Pin Floating ist z.B. sinnvoll wenn man externe Widerstände in anderen Schaltungsteilen hat.

Nachfolgend noch ein einfaches Demoprogramm.

/* Wolfram Koerver
 * STM32 Example for OLIMEX STM32P107 Test Board
 * Toggle green and yellow LEDs Test Program this is the "hello world for electronics"
 * 1.1.2013
 */

#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"

void init_GPIO(void);

void delay_nus(uint32_t nus);

int main(void)
{
	init_GPIO();
    while(1)
    {
		/* Toggle LEDs which connected to PC6 and PC7 ; Green/Yellow LEDs from Olimex Board*/
		GPIOC->ODR ^= GPIO_Pin_6;						// invert pin
		delay_nus (100000);								// delay a short time
		GPIOC->ODR ^= GPIO_Pin_7;						// toggle other LED
		delay_nus (100000);
    }
}

void init_GPIO(void)
{
    /* Initialize GPIO Structure, configure clock on peripheral bus
     * Enable GPIO Pins for LED which are connected to PC6,7*/
    /* Configure the GPIO_LED pin  PC6 = Green LED PC7 = Yellow LED
     * Configure direction and clock speed*/

	GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}

/***************************************************************************//**
 * @brief     delay in n us
 * @param[in] n:delay value
 * @return    None
*******************************************************************************/
void delay_nus(uint32_t nus)
{
 uint32_t temp;
 SysTick->LOAD = nus * 11;
 SysTick->VAL = 0x00;
 SysTick->CTRL = 0x01 ;
 do
 {
  temp=SysTick->CTRL;

 }while(temp&0x01&&!(temp&(1<<16)));
 SysTick->CTRL = 0x00;
 SysTick->VAL = 0X00;
}