历史上的今天
今天是: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 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 }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(;;) { } }
史海拾趣
|
以共发射极电路为例,进入深饱和状态与基极、集电极电阻,三极管的电流放大系数和电源电压有关,基极偏压电阻越小、集电极负载电阻越大、三极管的放大系数越高、电源电压越低,越容易进入饱和状态。 基极开路时集电极电压等于电源电压,逐步减小基 ...… 查看全部问答> |
|
如题所述。我在安装isp运行或者 用绿色版运行之后都提示缺少一个文件 但是我的文件夹下有这个文件 而且我去网上下了新的解压替换了之后还是这样 。isp下了好几个了都是这样 。请高手指点一下。 注:我没有连接单片机 只是单 ...… 查看全部问答> |
|
可以完全显示,只是有点小问题,比如第一次显示的是3位数 类似234,要是第2次在同样位置显示个1位数 如6,现在LCD显示变成634,怎么清除后面2位啊?命令里还是别的问题?… 查看全部问答> |
|
我在Vxworks下实现以太网通讯,采用UDP协议,在调试状态下,程序运行正常,用ping指令ping目标机和测试程序测试均正常,但将程序作成映像下载到DOC中运行时,却发现无法ping通目标机,不知怎么回事,请高手解释一下,另外,我在程序中开了三个任务 ...… 查看全部问答> |
|
请教WinCE6.0开发中关于Emulator的问题(如何自制SDK,Emulator) 我刚刚接触WinCE,我需要做的事情是在一般WinCE设备上开发应用程序,我打算自己在PB6.0上导出一个一般的WinCE6.0的SDK并安装,然后在VS2005上写代码,通过WinCE6.0仿真器看到代码的效果。 现在我按照网上的文章“WinCE6.0安装顺序”依次安装了下列 ...… 查看全部问答> |
|
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 ...… 查看全部问答> |




