MBED移植日記:gpio_api移植(基於STM32F107RC)

本文是繼MBED串口API移植的又一篇系列文章,前陣子忙着趕項目,移植完了卻沒來得及寫成文章來分享,今天來補上,一來可以溫故知新,二來也可以獻出自己的一點微薄之力。寫的不好,移植的也不一定好,請大家多多指教。本文的gpio_api模塊與mbed官方的會有一些不同,原因是加入了我個人理解的一些東西。


一、關聯文件

1、ierror.h


/*
 **************************************************************
 file:  ierror.c
 date:  2016-8-15
 ver :  1.00.00
 **************************************************************
 */


#include 
#include 
#include "device.h"
#include "toolchain.h"
#include "ierror.h"
#if DEVICE_STDIO_MESSAGES
#include 
#endif

WEAK void error(const char* format, ...) {
#if DEVICE_STDIO_MESSAGES
    va_list arg;
    va_start(arg, format);
    vfprintf(stderr, format, arg);      /* 打印到屏幕輸出 */
    va_end(arg);
#endif
    exit(1);
}

2、ierror.c

/*
 **************************************************************
 file:  ierror.c
 date:  2016-8-15
 ver :  1.00.00
 **************************************************************
 */


#include 
#include 
#include "device.h"
#include "toolchain.h"
#include "ierror.h"
#if DEVICE_STDIO_MESSAGES
#include 
#endif

WEAK void error(const char* format, ...) {
#if DEVICE_STDIO_MESSAGES
    va_list arg;
    va_start(arg, format);
    vfprintf(stderr, format, arg);      /* 打印到屏幕輸出 */
    va_end(arg);
#endif
    exit(1);
}

3、iassert.h

/*
 **************************************************************
 file:  iassert.h
 date:  2016-8-15
 ver :  1.00.00
 **************************************************************
 */


#ifndef _I_ASSERT_H
#define _I_ASSERT_H



void iassert_internal(const char *expr, const char *file, int line);


#ifdef  I_NDEBUG
#define I_ASSERT(expr) ((void)0)

#else
#define I_ASSERT(expr)                                \
do {                                                     \
    if (!(expr)) {                                       \
        iassert_internal(#expr, __FILE__, __LINE__); \
    }                                                    \
} while (0)
#endif



#endif

4、iassert.c

/*

 */


#include "iassert.h"
#include "ierror.h"


void iassert_internal(const char *expr, const char *file, int line)
{
    error("mbed assertation failed: %s, file: %s, line %d \n", expr, file, line);
}

5、portnames.h


/* 
 *******************************************************************************

 *******************************************************************************
 */
#ifndef _PORT_NAMES_H
#define _PORT_NAMES_H

#ifdef __cplusplus
extern "C" {
#endif

typedef enum {
    PORTA = 0,
    PORTB = 1,
    PORTC = 2,
    PORTD = 3,
    PORTE = 4,
    PORTF = 5,
    PORTG = 6,
    PORTH = 7
} PORTNAME;

#ifdef __cplusplus
}
#endif
#endif

6、stm32f1xx.h


二、gpio_api.h

/**
  ******************************************************************************
  * File Name          : gpio_api.h
  * Description        : 
  ******************************************************************************
  */
#include "pinnames.h"




/* extern prototype *************************/

void     gpio_init(uint32_t pin);        /* 初始化引腳,使能引腳時鐘 */           
void     gpio_format(uint32_t pin,uint32_t mode,uint32_t pupd);
void     gpio_dir(uint32_t pin,PIN_DIRECTION dir);
void     gpio_mode(uint32_t pin,uint32_t mode);
void     find_port(uint32_t pin,GPIO_TypeDef **port);
void     gpio_write(uint32_t pin,uint32_t value);
uint32_t gpio_read(uint32_t pin);


/* gpio in ***********************************/
void gpio_init_in(uint32_t pin);                    /* 初始化引腳爲輸入模式 */
void gpio_init_in_ex(uint32_t pin,uint32_t value);


/* gpio out **********************************/
void gpio_init_out(uint32_t pin);                   /* 初始化引腳爲輸出模式 */
void gpio_init_out_ex(uint32_t pin,uint32_t value);

三、gpio_api.c

/**
  ******************************************************************************
  * File Name          : gpio_api.c
  * Description        : 
  ******************************************************************************
  */

#include "iassert.h"
#include "ierror.h"

#include "stm32f1xx.h"
#include "gpio_api.h"
#include "portnames.h"




/* private prototype *****************************************/
static void _gpio_init_out(uint32_t pin,uint32_t pin_mode,uint32_t value);
static void _gpio_init_in(uint32_t pin,uint32_t mode);




/* genrate api **********************************************************/

/**
  * 描述:初始化GPIO引腳,使能GPIO時鐘
  * pin :引腳名稱,必須爲 PIN_NAME 枚舉中的一個
  */
void gpio_init(uint32_t pin)
{
    if(pin == (uint32_t)NC)
        return;
    
    uint32_t port = STM_PORT(pin);
    
    switch(port)
    {
    case PORTA:
        __HAL_RCC_GPIOA_CLK_ENABLE();
        break;
    case PORTB:
        __HAL_RCC_GPIOB_CLK_ENABLE();
        break;
    case PORTC:
        __HAL_RCC_GPIOC_CLK_ENABLE();
        break;
    case PORTD:
        __HAL_RCC_GPIOD_CLK_ENABLE();
        break;
    case PORTE:
        __HAL_RCC_GPIOE_CLK_ENABLE();
        break;
    default:
        error("Pinmap error: wrong port number.");
        break;
    }
}

/**
  * 描述:   按指定參數格式化引腳
  * pin :   引腳名稱,必須爲 PIN_NAME 枚舉中的一個
  * mode:   與HAL庫中的gpio_mode一致
  * pupd:   與HAL庫一致
  */
void gpio_format(uint32_t pin,uint32_t mode,uint32_t pupd)
{
    I_ASSERT(pin != NC);
    
    GPIO_InitTypeDef gpio_initstruct;
    GPIO_TypeDef     *port    = NULL;
    uint32_t         gpio_pin = 1<BSRR = gpio_pin;
    }else{
        port->BSRR = (uint32_t)gpio_pin<<16;
    }
}

uint32_t gpio_read(uint32_t pin)
{
    I_ASSERT(pin != NC);
    
    uint32_t pinbit;
    GPIO_TypeDef *port = NULL;
    uint32_t pin_idx = STM_PIN(pin);
    uint32_t gpio_pin = 1<IDR & gpio_pin) != (uint32_t)0){
        pinbit = 1;
    }else{
        pinbit = 0;
    }
    
    return pinbit;
}





/* digital in ***********************************************************/
void gpio_init_in(uint32_t pin)
{
    gpio_init_in_ex(pin,GPIO_MODE_INPUT);
}

void gpio_init_in_ex(uint32_t pin,uint32_t mode)
{
    _gpio_init_in(pin,mode);
}

static void _gpio_init_in(uint32_t pin,uint32_t mode)
{
    gpio_init(pin);
    
    if(pin != NC){
        gpio_dir(pin,PIN_INPUT);
        gpio_mode(pin,mode);
    }
}

                    
                    
                    
                    
/* digital out *********************************************************/
void gpio_init_out(uint32_t pin)
{
    gpio_init_out_ex(pin,0);        /* 默認輸出低電平 */
}

/**
  * value   -- value = 0(level low) or 1(level high)
  */
void gpio_init_out_ex(uint32_t pin,uint32_t value)
{
    _gpio_init_out(pin,GPIO_MODE_OUTPUT_PP,value);  
}                   
                    
                    
/**
  * value   -- value = 0(level low) or 1(level high)
  */
static void _gpio_init_out(uint32_t pin,uint32_t pin_mode,uint32_t value)
{
    gpio_init(pin);
    
    if(pin != NC){
        gpio_write(pin,value);
        gpio_dir(pin,PIN_OUTPUT);
        gpio_mode(pin,pin_mode);
    }
}

四、使用舉例

例如:把 PA_14腳配置爲輸出模式,初始爲高電平;把PA_15配置成輸入;

#include "gpio_api.h"


void main(void)

{

gpio_init_out(PA_14);/* 按缺省參數初始化引腳 */

gpio_write(PA_14,1);/* 初始化爲高電平 */

uint8_t  pin_value = gpio_read(PA_14);/* 讀引腳狀態 */


gpio_init_in(PA_15);


for(;;)

{


}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章