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(;;)

{


}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值