Aufgabe für STM32 Mikrocontroller

Gast #6340054
Lesenswert?

Hallo ich habe eine Klausuraufgabe zur Vorbereitung auf eine Klausur
bekommen.

Aufgabe 3: Virtueller Parallel Port a)  In einer Anwendung wird ein
32-Bit GPIO-Port benötigt. Der Mikrocontroller STM32 bietet lediglich
eine GPIO-Breite von 16 Bits an. Daher soll der 32- Bit Port durch
Software erweitert werden. Die Ansteuerung des verwendeten Ports GPIOA
(niederwertige Bits des 32-Bit GPIO) und GPIOB (höherwertige Bits) soll
ohne Verwendung der Libary Folgende I/O-Register der GPIOx  (x={A,B}
werden in dieser Aufgabe betrachtet, die weiteren Einstell-Möglichkeiten
werden hier vernachlässigt.  GPIOx ODR: 16-Bit output Dataregister zum
schreiben (und Lesen) der Outputs GPIOx.IDR 16-Bit Input Dataregister
zum Lesen der Inputs GPIOx BSRR 32-Bit „Set oder Reset“ –Register ->
Niedrige 16 Bits zum Setzen, hohe Bits zum Löschen

b) Funktionen zu implementieren: Void configme_input_output(uint32_t)
//every set bit in bitmask means bit (becomes output) // reset Bits
become input

c) Ab jetzt gehen wir davon aus, dass alle Pins als Outout Konfigurieren
werden. Implementieren Sie die folgende Funktion zum Umschalten der
Pins. Void toggle_bits (uint_32_t bitmask) // every set bit means:
toogle this bit in virtual 32 Bit Port

d) Implementieren Sie folgende Funktion wie unten beschrieben Void
atomic_reset_single_bit (uint8_t bitnumber) // bitnumber = {0…31} The
corresponding bit shall be reset // without changing any other bit using
the BSRR

e)  Folgende Funktion ist zu implementieren. Die Funktion solle von der
Benutzeroberfläche aus mit einem String-Argument „0“ … „15“ aus größer
werden. Bool test_and_set_bit (char*bitnumber) // string argument! //
set single bit and return it´s previous value // examples:
test_and_set_bit(“13“) Test-and_set_bit(“0“)



Hier habe ich mal meine Lösung die ich probiert habe ich bin für Tipps
sehr dankbar.

GPIO_TypeDef *GPIOA( int gpioNumber)
{
  GPIO_TypeDef *gpio = AH1PERIPH_BASE + gpioNumber*0x400;

  return gpio;

}

void init_port_output(int gpioNumber, int pinNumber)
{
GPIO_TypeDef *gpio = GPIOA; // Adresse des IO Port A zuweisen
RCC->AHB1ENR |= (1<<gpioNumber); // Enable GPIO Peripheral clock
gpio->MODER |= 0b01<<(2*pinNumber);// GP IO Ausgang
//gpio->BSRR = 1<< (16+pinNumber); // Start mit LED aus = reset output
}


void init_port_output(int gpioNumber, int pinNumber)
{
GPIO_TypeDef *gpio = GPIOB; // Adresse des IO Port B zuweisen
RCC->AHB1ENR |= (1<<gpioNumber); // Enable GPIO Peripheral clock
gpio->MODER |= 0b01<<(2*pinNumber);// GP IO Ausgang
//gpio->BSRR = 1<< (16+pinNumber); // Start mit LED aus = reset output
}



void configure_ports_output (int gpioNumber, uint16_t PinMask)
{
unsigned int  pinPosition =0;

while (PinMask > 0)
{
int a = PinMask & 0b1; // Test auf unterstes Bit gesetzt

if (a==1)
  init_port_output(gpioNumber, pinPosition); //initialisierung mit
init_port_output

  PinMask = PinMask >> 1; //pinMask um eine Stelle nach rechts schieben
  pinPosition++;
}
}

void virtual_port(uint16_t vport)
{
  uint32_t porta, portb, vporta, vportb;

  vporta = vport & 0xe0;
  vporta >>= 5;
  vportb = vport & 0x1f;
  portb = GPIOB -> ODR;
  porta = GPIOA -> ODR;
  porta &= 0xfff8; // Bits zu Null maskieren
  portb &= 0xf83f;  // Bit zu Null maskieren
  // Überlagerung (ODER-Operation) der Werte zurück
  GPIOA -> ODR = porta | (~vporta);
  GPIOB -> ODR = portb | (~vportb);
}
Beitrag #6340442 wurde von einem Moderator gelöscht.
#6340465
Lesenswert?

Dominik K. schrieb:
> Wie verbindet man den zwei Ports softwaremäßig zu einem virtuellen Port?

Wie der Name schon sagt, virtuell.

Dies ist nur für dich ein Pseudo-Code um es zu veranschaulichen.
1
void set_port_level(GPIO *port, uint16_t value)
2
{
3
   port->ODR = value;
4
}
5

6
void set_virtual_port_level(uint32_t value)
7
{
8
   uint16_t tmp;
9

10
   tmp = (value & 0x0000FFFF);
11
   set_port_level(GPIOA, tmp);
12

13
   tmp = (value & 0xFFFF0000) >> 16;
14
   set_port_level(GPIOB, tmp);
15
}
#6340652
Lesenswert?

Dominik K. schrieb:
> Ja schon, die Frage ist nur kann ich einfach über die Variablen beliebig
> groß machen meine Größe vom Port definieren?

Puhhhhhh, Sorry, aber erstens versteh ich nicht was du uns fragen 
möchtest und zweitens bekomm ich da Kopfschmerzen, wenn ich das so lese.

Jetz streng dich mal bissel an :-P
Immerhin ist das hier meine Freizeit und die ist kostbar - klar bekommst 
du Hilfe, aber wir verstehen nicht wo dein Problem liegt. Sorry.
#6340657
Lesenswert?

Schau mal...

Die Funktion aus deinem Skript 4.3.3 und dann diese aber mit dem Inhalt 
der Funktion die ich dir geantwortet hatte...bissel anpassen, fertig.

Edit:
Ich glaub eher, du hast noch nicht den Zusammenhang zwischen den Bits 
einer Variable und den zu setzenden Bits(Pins) des Ports verstanden, 
kann das sein?
Gast #6340678
Lesenswert?

Okay ich will nicht deine Zeit verschwenden sorry. Ich hatte gerade ne 
Denkblockade. Genau richtig ich muss doch über den Pin des Portes mit 
high und low diesen als Ausgang oder Eingang definieren.
Gast #6340704
Lesenswert?

Dominik K. schrieb:
> Genau richtig ich muss doch über den Pin des Portes mit
> high und low diesen als Ausgang oder Eingang definieren.

Die Umschaltung zwischen Ausgang und Eingang macht man nicht über einen 
Pin, sondern über ein Register. Guck Dir meine STM32 Seite an, da habe 
ich die relevanten Register für drei STM32 Serien genannt.
#6340729
Lesenswert?

Dominik K. schrieb:
> Okay ich will nicht deine Zeit verschwenden sorry

Tust du nicht...
Aber die Lösung mit dem Skript ist so offensichtlich, das ich denken 
muss, du hast einfach die Sache ansich nicht verstanden.

Und da, solltest mal machen was Stefan dir sagt.

Was man lernt, kann man verlernen...
Aber was man versteht,
das kann man ja nicht "ververstehen" ?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren