历史上的今天
返回首页

历史上的今天

今天是:2025年04月04日(星期五)

2020年04月04日 | MBED移植日记:gpio_api移植(基于STM32F107RC)

2020-04-04 来源:eefocus

本文是继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    }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        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(;;)


{


}


}

推荐阅读

史海拾趣

Chipcon AS公司的发展小趣事

Chipcon AS公司深知人才是企业发展的核心力量。因此,公司一直注重人才的引进和培养。通过与高校和研究机构建立合作关系,公司吸引了大量优秀的研发人才加入。同时,公司还建立了完善的培训体系,为员工提供了广阔的职业发展空间。这些措施使得Chipcon AS公司的研发实力不断增强,为公司的持续发展提供了有力保障。

安碁科技(AKER)公司的发展小趣事

1990年,安碁科技股份有限公司正式成立,标志着其进军石英振荡器领域的起点。公司初创时期,面临着激烈的市场竞争和技术挑战。然而,安碁科技凭借对技术的执着追求和对市场的敏锐洞察,逐步在行业中崭露头角。通过不断的技术研发和产品创新,公司逐渐建立了自己的品牌地位,为后续的发展奠定了坚实的基础。

FTCAP Fischer & Tausche Capacitor Group公司的发展小趣事

在电子行业快速发展的背景下,安碁科技始终坚持持续创新和客户导向的经营理念。公司不断投入研发资源,推出具有竞争力的新产品和解决方案,以满足客户不断变化的需求。同时,安碁科技也注重与客户的沟通和合作,深入了解客户的需求和反馈,不断优化产品和服务。这种以客户为中心的经营模式,使得安碁科技在市场上赢得了良好的声誉和口碑。

这五个故事只是安碁科技发展历程中的一部分,但它们充分展示了公司在电子行业中的崛起和发展。安碁科技凭借其卓越的技术实力、品质管理和创新能力,在激烈的市场竞争中脱颖而出,成为行业的佼佼者。未来,随着电子行业的不断发展和变化,安碁科技将继续保持创新和进取的精神,为客户和市场带来更多优质的产品和服务。

Facon公司的发展小趣事

在发展过程中,Facon遇到了许多技术难题。然而,他们从未放弃过对技术的追求和突破。经过数年的研究和实践,Facon成功研发出了一款具有划时代意义的低功耗芯片,该芯片在保持高性能的同时,大大降低了能耗,为电子产品的续航能力带来了革命性的提升。这一技术突破让Facon在行业中声名鹊起,吸引了众多合作伙伴的关注。

ATM [Advanced Technical Materials]公司的发展小趣事

然而,随着ATM的普及,安全问题也日益凸显。黑客攻击、恶意软件植入等事件时有发生,给ATM的安全运营带来了挑战。为了应对这些挑战,ATM行业加强了技术研发和安全防护,采用更加先进的加密技术和安全机制,确保用户的资金安全。

以上五个故事虽然不直接涉及ATM公司的具体发展,但展示了ATM技术在电子行业中的发展历程和重要事件。这些故事反映了ATM从诞生到广泛应用,再到技术创新和安全挑战的整个过程,也展示了电子行业在推动ATM发展中的重要作用。

厦门法拉(faratronic)公司的发展小趣事

在追求商业成功的同时,FMI公司也积极履行社会责任,致力于环保和可持续发展。公司制定了一系列环保计划和程序,以确保在所有业务运营中保持环保意识。FMI的产品从设计到生产都遵循环保原则,采用环保材料和工艺,减少对环境的影响。此外,公司还积极参与行业内的环保活动,推动整个电子行业的绿色发展。这种负责任的企业形象为FMI赢得了社会的广泛赞誉和尊重。

问答坊 | AI 解惑

1302实时时钟程序共享!

本帖最后由 paulhyde 于 2014-9-15 03:27 编辑 1302实时时钟程序共享!    …

查看全部问答>

想学专业音响吗?

加入专业音响技术QQ:91617962…

查看全部问答>

如何选择限流电阻数值,使三极管进入深度饱和状态

以共发射极电路为例,进入深饱和状态与基极、集电极电阻,三极管的电流放大系数和电源电压有关,基极偏压电阻越小、集电极负载电阻越大、三极管的放大系数越高、电源电压越低,越容易进入饱和状态。 基极开路时集电极电压等于电源电压,逐步减小基 ...…

查看全部问答>

单片机 stc isp 打不开

如题所述。我在安装isp运行或者 用绿色版运行之后都提示缺少一个文件 但是我的文件夹下有这个文件 而且我去网上下了新的解压替换了之后还是这样  。isp下了好几个了都是这样  。请高手指点一下。 注:我没有连接单片机 只是单 ...…

查看全部问答>

LCD1602显示问题?

可以完全显示,只是有点小问题,比如第一次显示的是3位数 类似234,要是第2次在同样位置显示个1位数 如6,现在LCD显示变成634,怎么清除后面2位啊?命令里还是别的问题?…

查看全部问答>

Vxworks网络编程提问

我在Vxworks下实现以太网通讯,采用UDP协议,在调试状态下,程序运行正常,用ping指令ping目标机和测试程序测试均正常,但将程序作成映像下载到DOC中运行时,却发现无法ping通目标机,不知怎么回事,请高手解释一下,另外,我在程序中开了三个任务 ...…

查看全部问答>

请教WinCE6.0开发中关于Emulator的问题(如何自制SDK,Emulator)

我刚刚接触WinCE,我需要做的事情是在一般WinCE设备上开发应用程序,我打算自己在PB6.0上导出一个一般的WinCE6.0的SDK并安装,然后在VS2005上写代码,通过WinCE6.0仿真器看到代码的效果。 现在我按照网上的文章“WinCE6.0安装顺序”依次安装了下列 ...…

查看全部问答>

verilog FPGA 中 状态转换程序中出现的问题

module contral(clk1hz,rst_n,hold,    led,num,flash);input clk1hz;input rst_n;input hold;  //incident happen//input INTI;  //红绿灯初始状态output [2:0] led; //红绿灯output [4:0] num; //显示的倒计时outp ...…

查看全部问答>

2010山东省大学生电子设计大赛优秀论文

本帖最后由 paulhyde 于 2014-9-15 09:25 编辑 2010山东省大学生电子设计大赛优秀论文  …

查看全部问答>