Seperti yang Anda ketahui, CMSIS menyediakan akses ke register mikrokontroler. Ini bagus, tapi tidak terlalu nyaman. Artikel ini akan fokus pada konfigurasi GPIO. Port I / O dikonfigurasi dengan cukup sederhana dan jika kita berbicara tentang satu atau dua pin, Anda dapat menggunakan register secara langsung. Tetapi jika Anda perlu mengkonfigurasi beberapa pin, dan terlebih lagi secara dinamis mengubah konfigurasi (ini mungkin diperlukan, misalnya, untuk memeriksa kekencangan garis ke plus saat menerapkan pekerjaan dengan I2C, dan kemudian beralih ke bekerja dengan perangkat keras I2C), maka akan lebih mudah untuk membungkus semua pekerjaan dengan mendaftar ke kelas, dan menggunakan metode seperti setPin / resetPin.
Karena kelas dengan GPIO berfungsi, saya memutuskan untuk menyebutnya begitu. Ini memiliki konstruktor GPIO (GPIO_TypeDef * port) yang menerima referensi port. Ada juga metode di kelas:
batal pinConf (uint8_ t pin_ nomber, uint8_ t pin_ mode); // mode operasi pin
void setPin (uint8_ t pin_ nomber); // set 1
batal resetPin (uint8_ t pin_ nomber); // setel ulang pin
int getPin (uint8_ t pin_ nomber); // baca status pin (reg. IDR)
Modul kelas terdiri dari dua file - gpio.h dan 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. .