自己写库:构建库函数雏形

描述

第8章 自己写库——构建库函数雏形

实际上,构建固件库是一件费时费力的事情,并且它对开发者对芯片的熟悉程度有一定的要求。甚至,当一个固件库的封装程度很高时,想要阅读并理解该固件库的底层代码也会变成一件有较高难度的事情。瑞萨RA系列单片机所使用的官方FSP库便是这样的一种封装程度很高的固件库。所幸的是,FSP库的意义在于为开发者封装硬件底层,因此一般而言,FSP库是带来方便的,开发者只需学会如何使用FSP库即可,而不用深入到FSP库的底层细节。

构建固件库一般是由芯片厂商来做,比如FSP库就是由瑞萨官方构建和维护的。为了让读者更加清晰地了解到固件库的作用,我们接下来将会说明一种构建一个封装程度较低的固件库的思路。值得注意的是,本章所构建的库函数雏形与实际上的FSP库有很大区别,但求这对读者理解和使用FSP库有所帮助。

8.1 硬件设计

野火启明6M5开发板的LED电路图如图所示。

瑞萨

野火启明4M2开发板的LED电路图下图所示。

瑞萨

野火启明2L1开发板的LED电路图下图所示。

瑞萨

8.2 软件设计

8.2.1 新建工程

对于e2 studio开发环境:拷贝一份我们之前新建的e2s工程模板“05_Template”,然后将工程文件夹重命名为“09_Register_MyLib”,最后再将它导入到我们的e2 studio工作空间中。

对于Keil开发环境:拷贝一份我们之前新建的Keil工程模板“06_Template”,然后将工程文件夹重命名为“09_Register_MyLib”,并进入该文件夹里面双击Keil工程文件,打开该工程。

工程新建好之后,在工程根目录的“src”文件夹下面新建“ioport”文件夹,再进入“ioport”文件夹里面新建ioport驱动的源文件和头文件:“ra_ioport.c”和“ra_ioport.h”。工程文件结构如下。

列表1:文件结构

左右滑动查看完整内容

 

09_Register_MyLib
├─ ......
└─ src
  ├─ ioport
  │ ├─ ra_ioport.c
  │ └─ ra_ioport.h
  └─ hal_entry.c

 

警告

注意:对于使用Keil开发环境的用户,将代码文件放到“src”文件夹下之后,Keil软件并不会自动将它们加入到工程,这时候需要打开RASC FSP配置界面,点击一次单击右上角的“Generate Project Content”按钮,从而“src”文件夹下的代码文件就会被自动加入进工程中。接着关闭FSP配置界面返回到Keil,然后进行一次编译后会弹出一个提示框提示工程结构发生了变化,点击确定即可。对于使用e2 studio的用户则不需要如此。

8.2.2 包含寄存器定义的头文件

在ra_ioport.h中通过包含“hal_data.h”头文件来间接包含寄存器定义头文件:R7FA6M5BH.hR7FA4M2AD.hR7FA2L1AB.h

列表2:代码清单8-1:ra_ioport.h

左右滑动查看完整内容

 

#include"hal_data.h"//间接包含了头文件 "R7FA6M5BH.h" / "R7FA4M2AD.h" /
→"R7FA2L1AB.h"

 

8.2.3 端口和引脚号的枚举类型定义

我们需要定义端口和引脚号的枚举类型,用来表示某个要操控的某个引脚。但是如果像:“BSP_IO_PORT_04_PIN_00”、“BSP_IO_PORT_04_PIN_03”和“BSP_IO_PORT_04_PIN_04”

这样定义端口和引脚号的枚举类型,会造成与FSP库中的枚举定义冲突,因此我们暂时把端口和引脚号分开出来单独定义。

列表3:代码清单8-2:ra_ioport.h文件

左右滑动查看完整内容

 

/* IOPORT 端口定义 */
typedefenumio_port
{
IO_PORT_00 = 0x0000, ///< IO port 0
IO_PORT_01 = 0x0100, ///< IO port 1
IO_PORT_02 = 0x0200, ///< IO port 2
IO_PORT_03 = 0x0300, ///< IO port 3
IO_PORT_04 = 0x0400, ///< IO port 4
IO_PORT_05 = 0x0500, ///< IO port 5
IO_PORT_06 = 0x0600, ///< IO port 6
IO_PORT_07 = 0x0700, ///< IO port 7
IO_PORT_08 = 0x0800, ///< IO port 8
IO_PORT_09 = 0x0900, ///< IO port 9
IO_PORT_10 = 0x0A00, ///< IO port 10
IO_PORT_11 = 0x0B00, ///< IO port 11
IO_PORT_12 = 0x0C00, ///< IO port 12
IO_PORT_13 = 0x0D00, ///< IO port 13
IO_PORT_14 = 0x0E00, ///< IO port 14
} IO_Port_t;


/* IOPORT 引脚定义 */
typedefenumio_pin
{
IO_PIN_00 = 0x0000, ///< IO port 0 pin 0
IO_PIN_01 = 0x0001, ///< IO port 0 pin 1
IO_PIN_02 = 0x0002, ///< IO port 0 pin 2
IO_PIN_03 = 0x0003, ///< IO port 0 pin 3
IO_PIN_04 = 0x0004, ///< IO port 0 pin 4
IO_PIN_05 = 0x0005, ///< IO port 0 pin 5
IO_PIN_06 = 0x0006, ///< IO port 0 pin 6
IO_PIN_07 = 0x0007, ///< IO port 0 pin 7
IO_PIN_08 = 0x0008, ///< IO port 0 pin 8
IO_PIN_09 = 0x0009, ///< IO port 0 pin 9
IO_PIN_10 = 0x000A, ///< IO port 0 pin 10
IO_PIN_11 = 0x000B, ///< IO port 0 pin 11
IO_PIN_12 = 0x000C, ///< IO port 0 pin 12
IO_PIN_13 = 0x000D, ///< IO port 0 pin 13
IO_PIN_14 = 0x000E, ///< IO port 0 pin 14
IO_PIN_15 = 0x000F, ///< IO port 0 pin 15
} IO_Pin_t;

 

8.2.4 IOPORT相关功能的枚举类型定义

接着定义IOPORT相关功能的枚举类型,这里的每一个枚举类型都对应着IOPORT的其中一项功能配置。

列表4:代码清单8-3:ra_ioport.h文件

左右滑动查看完整内容

 

/* IO 引脚模式 */
typedefenum
{
IO_MODE_GPIO = 0, /* 普通 GPIO 功能 */
IO_MODE_AF = 1, /* 复用功能 */
IO_MODE_AN = 2/* 模拟输入输出功能 */
} IO_Mode_t;
/* IO 引脚方向 */
typedefenum
{
IO_DIR_INPUT = 0, // 引脚用作 GPIO 输入功能
IO_DIR_OUTPUT = 1// 引脚用作 GPIO 输出功能
} IO_Dir_t;
/* IO 引脚输出类型 */
typedefenum
{
IO_OTYPE_PP = 0x00, /* 推挽模式 */
IO_OTYPE_OD = 0x01/* 开漏模式 */
} IO_OType_t;
/* IO 引脚输出能力 */
typedefenum
{
IO_DRIVE_LOW = 0, // Low drive
IO_DRIVE_MIDDLE = 1, // Middle drive
IO_DRIVE_HSHD = 2, // High-speed high-drive
IO_DRIVE_HIGH = 3// High drive
} IO_DriveCapability_t;
/* IO 引脚输出电平 */
typedefenumio_level
{
IO_LEVEL_LOW = 0, // Low
IO_LEVEL_HIGH // High
} IO_Level_t;
/* IO 引脚输入上下拉 */
typedefenum
{
IO_NO_PULL = 0x00u, /* 浮空输入 */
IO_PULL_UP = 0x01u, /* 上拉输入 */
//IO_PULL_DOWN = 0x02u /* RA6M5/RA4M2/RA2L1 引脚没有下拉功能 */
} IO_Pull_t;

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分