STM32 C++编程 002 GPIO类

使用 C++ 语言给 STM32 编写一个 Gpio

我使用的STM32芯片:STM32F103ZET6
我们使用的STM32库版本:V3.5.0



注意:

  • 想学习本套 STM32 C++编程 的专栏是有点门槛的。你需要有一点点 STM32 基础 和 一点点 C++ 语言基础。

  • 完整的STM32 C++工程模板 的下载地址可以在本篇博客的最下面找到。


Gpio.h

//Gpio.h
//#pragma once   //编译一次
#ifndef __AOBO_stm3210x_Gpio_H_
#define     __AOBO_stm3210x_Gpio_H_

#include "stm32f10x.h"

/*--------------------Gpio--------------------------------------*/
// //eg:
//  Gpio  key1(RCC_APB2Periph_GPIOC,GPIOC,GPIO_Pin_1,GM_IN_FLOATING);
//  Gpio  pins(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,GPIOC,GPIO_Pin_1|GPIO_Pin_10);
//  Gpio  EnTk(PA,0);
//   特别注意:
//   1.当你使用PB3,4 PA13,14,15 时一定要加上这2句:
//          RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//      GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);  // 同时关闭 JLink 和 STlink
//   2.PD0,1 是不能被用做I/O口使用的 . 他们是接外部进制的

namespace stm32f10x
{


typedef struct   tagGPIO_PIN
{
    uint32_t            periph;//eg:RCC_APB2Periph_GPIOF
    GPIO_TypeDef*           port;    //eg:GPIOF
    uint16_t            pin;     //eg:GPIO_Pin_10
    GPIOMode_TypeDef    mode;    //eg.GPIO_Mode_IN_FLOATING;
    GPIOSpeed_TypeDef   speed;   //eg.GPIO_Speed_50MHz
}GPIO_PIN;

enum PORT_INDEX
{
    PA=0,PB,PC,PD,PE,PF,PG 
};

typedef struct _periph_PORT
{
    uint32_t        p_periph;
    GPIO_TypeDef*       p_port;
}periph_PORT;


#define GM_AIN            GPIO_Mode_AIN            
#define GM_IN_FLOATING      GPIO_Mode_IN_FLOATING   
#define GM_IPD          GPIO_Mode_IPD        
#define GM_IPU          GPIO_Mode_IPU        
#define GM_OUT_OD           GPIO_Mode_Out_OD       
#define GM_OUT_PP           GPIO_Mode_Out_PP      
#define GM_AFOD             GPIO_Mode_AF_OD            
#define GM_AFPP             GPIO_Mode_AF_PP         


class Gpio
{
private:
    GPIO_PIN m_gpio;
public:
    ~Gpio()
    {

    }
    Gpio()
    {

    }

    Gpio(PORT_INDEX     indexPort,
        uint16_t              indexPin, //???0~15??GPIO_Pin_0~GPIO_Pin_15
        GPIOMode_TypeDef        p_mode=GM_OUT_PP,
        GPIOSpeed_TypeDef       p_speed=GPIO_Speed_50MHz );   
    Gpio( uint32_t      p_periph,
        GPIO_TypeDef*       p_port,
        uint16_t            p_pins,    //???????
        GPIOMode_TypeDef        p_mode=GPIO_Mode_Out_PP,
        GPIOSpeed_TypeDef       p_speed=GPIO_Speed_50MHz );

    void initialize( GPIOMode_TypeDef   p_mode=GPIO_Mode_Out_PP );

    void initialize( uint32_t           p_periph,
            GPIO_TypeDef*           p_port,
            uint16_t            p_pins,    //???????,???RAM?????
            GPIOMode_TypeDef    p_mode=GPIO_Mode_Out_PP,
            GPIOSpeed_TypeDef   p_speed=GPIO_Speed_50MHz );

    inline  bool get(void){
        if( ishigh() ){
            return true;
        }
        else{
            return false;
        }
    }

    inline void set(bool bs){
        if(bs){
            high();//GPIO_SetBits(m_gpio.port, m_gpio.pin);
        }
        else{
            low();//GPIO_ResetBits(m_gpio.port, m_gpio.pin);
        }
    }

    inline void invert(void){
        if ( ishigh() ){
            low();//GPIO_ResetBits(m_gpio.port, m_gpio.pin);
        }
        else{
            high();//GPIO_SetBits(m_gpio.port, m_gpio.pin);
        }
    }

    inline void high(void){     
        //GPIO_SetBits(m_gpio.port, m_gpio.pin);
        m_gpio.port->BSRR = m_gpio.pin;
    }

    inline void low(void){      
    //GPIO_ResetBits(m_gpio.port, m_gpio.pin);
    m_gpio.port->BRR = m_gpio.pin;
    }

    inline bool ishigh()
    {   
        // if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)  GPIO_ReadInputDataBit(m_gpio.port, m_gpio.pin)==Bit_SET
        if( m_gpio.port->IDR & m_gpio.pin){
            return true;
        }
        else{
           return false;
        }
    }

    inline bool islow(){          
        // if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)  GPIO_ReadInputDataBit(m_gpio.port, m_gpio.pin)==Bit_SET
        if( m_gpio.port->IDR & m_gpio.pin){
            return false; 
        }
        else{
            return true;
        }
    }

    void toggle(uint32_t t=1000,bool bLoop=true) {
        while(bLoop){
            high();
            for(int i=0;i<t;i++);
            low();
            for(int i=0;i<t;i++);
        }
    }
};

}
#endif

Gpio.cpp

#include "Gpio.h"

using namespace stm32f10x;

periph_PORT PERIPH_PORT[]=
{
    RCC_APB2Periph_GPIOA,GPIOA,
    RCC_APB2Periph_GPIOB,GPIOB,
    RCC_APB2Periph_GPIOC,GPIOC,
    RCC_APB2Periph_GPIOD,GPIOD,
    RCC_APB2Periph_GPIOE,GPIOE,
    RCC_APB2Periph_GPIOF,GPIOF,
    RCC_APB2Periph_GPIOG,GPIOG,
};

Gpio::Gpio(PORT_INDEX   indexPort,
        uint16_t              indexPin, //???0~15??GPIO_Pin_0~GPIO_Pin_15
        GPIOMode_TypeDef        p_mode,
        GPIOSpeed_TypeDef       p_speed){        

        initialize(PERIPH_PORT[indexPort].p_periph,
            PERIPH_PORT[indexPort].p_port,
            (uint16_t)1<<indexPin,//??GPIO_Pin_x????
            p_mode,
            p_speed 
             );
}

Gpio::Gpio( uint32_t        p_periph,
        GPIO_TypeDef*       p_port,
        uint16_t            p_pins,    //???????
        GPIOMode_TypeDef        p_mode,
        GPIOSpeed_TypeDef       p_speed){

        initialize(p_periph,
            p_port,
            p_pins,    //???????
            p_mode,
            p_speed 
             );
}

void Gpio::initialize( GPIOMode_TypeDef   p_mode){
    if(m_gpio.mode==p_mode)return;
    initialize(m_gpio.periph,
        m_gpio.port,
        m_gpio.pin,    //???????
        p_mode,
        m_gpio.speed 
        );
    m_gpio.mode=p_mode;
}

void Gpio::initialize( uint32_t         p_periph,
            GPIO_TypeDef*           p_port,
            uint16_t            p_pins,    //???????,???RAM?????
            GPIOMode_TypeDef    p_mode,
            GPIOSpeed_TypeDef   p_speed){
    m_gpio.periph = p_periph;
    m_gpio.port = p_port;
    m_gpio.pin = p_pins;
    m_gpio.mode=p_mode;
    m_gpio.speed=p_speed;

    GPIO_InitTypeDef tmp_InitType;//????
    tmp_InitType.GPIO_Pin= m_gpio.pin ;
    tmp_InitType.GPIO_Mode=m_gpio.mode;
    tmp_InitType.GPIO_Speed=m_gpio.speed;

    RCC_APB2PeriphClockCmd( m_gpio.periph, ENABLE );

    GPIO_Init( m_gpio.port ,&tmp_InitType);
}

使用 Gpio 的例子程序:4个LED流水点亮。

main.cpp

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "Gpio.h"

using namespace stm32f10x;
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */

int main(void)
{
    Gpio DS1_N(PG,8);
    Gpio DS2_N(PG,15);
    Gpio DS3_N(PA,5);
    Gpio DS4_N(PA,6);

    uint8_t i=0;
    while(true)
    {
         i++;
         i & 0x01 ? DS1_N.low():DS1_N.high();
         i & 0x02 ? DS2_N.low():DS2_N.high();
         i & 0x04 ? DS3_N.low():DS3_N.high();
         i & 0x08 ? DS4_N.low():DS4_N.high();
         for(uint32_t i=0;i<3000000;i++);
    }

}

搞定


你可以到这里下载我已经做好的 STM32 C++工程模板
百度云 链接:http://pan.baidu.com/s/1bpbZ2MV 密码:esam
也可以在CSDN里面下载:http://download.csdn.net/detail/github_35160620/9621141



小结:
下一讲,我们来使用 C++ 语言,创建一个 STM32Usart 类。

原文地址:https://www.cnblogs.com/aobosir/p/5928575.html