Gast
#6340054
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); }
