Como sabe, CMSIS proporciona acceso a los registros del microcontrolador. Esto es bueno, pero no muy conveniente. Este artículo se centrará en la configuración de GPIO. Los puertos de E / S están configurados de manera bastante simple y si estamos hablando de uno o dos pines, puede usar los registros directamente. Pero si necesita configurar varios pines, y aún más cambiar dinámicamente la configuración (esto puede ser necesario, por ejemplo, para verificar la estanqueidad de las líneas a más al implementar el trabajo con I2C, y luego cambiar para trabajar con hardware I2C), entonces es mucho más fácil envolver todo el trabajo con se registra en la clase y usa métodos como setPin / resetPin.
Dado que la clase con GPIO funciona, decidí llamarla así. Tiene un constructor GPIO (puerto GPIO_TypeDef *) que acepta una referencia de puerto. También hay métodos en la clase:
void pinConf (uint8_ t pin_ nomber, uint8_ t pin_ mode); // modo de operación de pin
void setPin (uint8_ t pin_ nomber); // serie 1
void resetPin (uint8_ t pin_ nomber); // restablecer pin
int getPin (uint8_ t pin_ nomber); // lee el estado del pin (reg. IDR)
El módulo de clase consta de dos archivos: gpio.hy 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. .