STM32 abstrait des registres CMSIS lors de la configuration de GPIO

Comme vous le savez, CMSIS permet d'accéder aux registres du microcontrôleur. C'est bien, mais pas très pratique. Cet article se concentrera sur la configuration de GPIO. Les ports d'E / S sont configurés assez simplement et si nous parlons d'une ou deux broches, vous pouvez utiliser les registres directement. Mais si vous avez besoin de configurer plusieurs broches, et encore plus de modifier dynamiquement la configuration (cela peut être nécessaire, par exemple, pour vérifier l'étanchéité des lignes à plus lors de la mise en œuvre du travail avec I2C, puis pour passer au travail avec le matériel I2C), alors il est beaucoup plus facile d'envelopper tout le travail avec s'inscrit dans la classe et utilise des méthodes telles que setPin / resetPin.





Puisque la classe avec GPIO fonctionne, j'ai décidé de l'appeler ainsi. Il possède un constructeur GPIO (port GPIO_TypeDef *) qui accepte une référence de port. Il existe également des méthodes dans la classe:





  • void pinConf (uint8_ t pin_ nomber, uint8_ t pin_ mode); // mode de fonctionnement des broches





  • vide setPin (uint8_ t pin_ nomber); // définir 1





  • vide resetPin (uint8_ t pin_ nomber); // réinitialiser la broche





  • int getPin (uint8_ t pin_ nomber); // lire l'état de la broche (reg. IDR)





Le module de classe se compose de deux fichiers - gpio.h et 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. .








All Articles