Wie Sie wissen, bietet CMSIS Zugriff auf die Register des Mikrocontrollers. Das ist gut, aber nicht sehr praktisch. Dieser Artikel konzentriert sich auf die Konfiguration von GPIO. E / A-Ports sind recht einfach konfiguriert. Wenn es sich um einen oder zwei Pins handelt, können Sie die Register direkt verwenden. Wenn Sie jedoch mehrere Pins konfigurieren und die Konfiguration noch dynamischer ändern müssen (dies kann beispielsweise erforderlich sein, um die Dichtheit der Leitungen zum Plus zu überprüfen, wenn Sie die Arbeit mit I2C implementieren, und dann zur Arbeit mit Hardware I2C zu wechseln), ist es viel einfacher, die gesamte Arbeit zu verpacken registriert sich in der Klasse und verwendet Methoden wie setPin / resetPin.
Da die Klasse mit GPIO funktioniert, habe ich beschlossen, sie so zu nennen. Es verfügt über einen GPIO-Konstruktor (GPIO_TypeDef * -Port), der eine Portreferenz akzeptiert. Es gibt auch Methoden in der Klasse:
void pinConf (uint8_ t pin_ nomber, uint8_ t pin_ mode); // Pin-Betriebsmodus
void setPin (uint8_ t pin_ nomber); // Set 1
void resetPin (uint8_ t pin_ nomber); // Pin zurücksetzen
int getPin (uint8_ t pin_ nomber); // lese den Zustand des Pins (reg. IDR)
Das Klassenmodul besteht aus zwei Dateien - gpio.h und gpio.cpp.
GPIO.H
#ifndef USER_LIB_GPIO_GPIO_H_
#define USER_LIB_GPIO_GPIO_H_
#include "stm32f103xb.h"
//---------------inputs-------------------------------------------------
#define INPUT_FLOATING 0x4 //
#define INPUT_PULL_UP 0x7F //
#define INPUT_PULL_DOWN 0xFF // ""
#define INPUT_ANALOG 0x0 //
//--------------outputs--------------------------------------------------
#define OUTPUT_OPEN_DRAIN 0x7 //
#define OUTPUT_PUSH_PULL 0x3 // -
//--------------altarnate function---------------------------------------
#define AF_PUSH_PULL 0xB // - -
#define AF_OPEN_DRAIN 0xF //
. GPIOx_CRL ( 0 7 ) GPIOx_CRH ( 8 15 ). 4 , . , , . .
class GPIO {
public:
GPIO( GPIO_TypeDef *port );
void pinConf ( uint8_t pin_nomber, uint8_t pin_mode ); //
void setPin( uint8_t pin_nomber ); // 1
void resetPin( uint8_t pin_nomber ); //
int getPin ( uint8_t pin_nomber ); // (reg. IDR)
private:
GPIO_TypeDef *GPIOx;
int pin_m;
};
#endif /* USER_LIB_GPIO_GPIO_H_ */
GPIO. (GPIOA, GPIOB ..) GPIOx. , , .
, .
pinConf ( uint8_t pin_nomber, uint8_t pin_mode ) , .
setPin( uint8_t pin_nomber ) 1. .
resetPin( uint8_t pin_nomber ) . .
getPin ( uint8_t pin_nomber ) ( IDR)
GPIO.CPP
#define INPUT_PULL_UP_DOWN 0x8 //
#define GPIO_BITS_MASK 0xF //
GPIO::GPIO(GPIO_TypeDef *port){
this->GPIOx = port;
// APB1
if ( port == GPIOA){
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
return;
}
if ( port == GPIOB ){
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
return;
}
if ( port == GPIOC ){
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
return;
}
if ( port == GPIOD ){
RCC->APB2ENR |= RCC_APB2ENR_IOPDEN;
return;
}
if ( port == GPIOE ){
RCC->APB2ENR |= RCC_APB2ENR_IOPEEN;
return;
}
return;
}
.
void GPIO::pinConf ( uint8_t pin_nomber, uint8_t pin_mode ){
this->pin_m = pin_mode; // set/reset Pin -
uint8_t offset; //
uint8_t mode;
// pin_mode
if ( ( pin_mode == INPUT_PULL_UP ) || ( pin_mode == INPUT_PULL_DOWN ) ){
mode = INPUT_PULL_UP_DOWN;
}//if
if ( pin_nomber < 8 ){
offset = pin_nomber * 4;
this->GPIOx->CRL &= ~( GPIO_BITS_MASK << offset );
this->GPIOx->CRL |= ( mode << offset );
} // if
else if ( pin_nomber > 7 ){
offset = ( pin_nomber - 8 ) * 4;
this->GPIOx->CRH &= ~( GPIO_BITS_MASK << offset );
this->GPIOx->CRH |= ( mode << offset );
} // else
// - ODR 1
if ( pin_mode == INPUT_PULL_UP ){
GPIOx->ODR |= ( 1 << pin_nomber );
}
/* . . INPUT_PULL_DOWN 0
* , INPUT_PULL_UP
* - INPUT_PULL_DOWN.
* ODR 1 INPUT_PULL_UP
*/
if ( pin_mode == INPUT_PULL_DOWN ){
GPIOx->ODR &= ~( 1 << pin_nomber );
}
return;
} //pinConf
pin_m. , setPin()/resetPin() , .
. pin_mode , ODR 1 0.
if ( pin_nomber < 8 ) if ( pin_nomber > 7 ) CRL CRH , , 4 , offset. GPIO BIT MASK, .
if ( pin_mode == INPUT_PULL_UP ) - , , ODR . , .
void GPIO::setPin( uint8_t pin_nomber ){
// -
// .. -
if ( ( this->pin_m == AF_PUSH_PULL) || ( this->pin_m == AF_OPEN_DRAIN ) ){
return;
}// if
this->GPIOx->BSRR = ( 1 << pin_nomber );
return;
}
setPin() . , . BSSR 1 .
void GPIO::resetPin( uint8_t pin_nomber ){
// -
// .. -
if ( ( this->pin_m == AF_PUSH_PULL) || ( this->pin_m == AF_OPEN_DRAIN ) ){
return;
}// if
this->GPIOx->BRR = ( 1 << pin_nomber );
return;
}
resetPin() , , BRR .
int GPIO::getPin ( uint8_t pin_nomber ){
uint16_t mask;
mask = ( 1<< pin_nomber);
if ( (this->GPIOx->IDR) & mask) return 1;
else return 0;
}
getPin() , IDR . - 1, 0.
:
GPIO *port = new GPIO( GPIOC ); // , GPIOC
port->pinConf( 13, OUTPUT_PUSH_PULL ); // -
port->setPin (13); // 1
port->resetPin (13); //
int value;
value = port->getPin (13); //
. - , . , -. , , , GPIO. .