本帖最后由 gao_hex 于 2021-3-24 23:46 编辑
一、简介
GPIO 做为单片机最基础的外设也是较关键的外设之一,常规端口的配置,如输入、输出、模拟输入(ADC),端口的上拉电阻,开漏输出,这颗片子独特之处在于一个端口可以配置两个功能,需要注意的是不能设置成两个输出功能
二、调试
1、硬件
在开发工具中找到压缩文件文件(EV-HC32F460-LQFP100设计文件)打开、找到开发板的电路图文件(EV-F460-LQ100-V14_SCH_20201215),在电路图中的第七页,找到GPIO 的连接(原理图的第一中的左上角有标注)
LED 的电路
LED 通过网络标号的形式连接到 MCU 上,我们还需要找到 MCU 部分的电路图(第三页),找到对应网络标号 LED0、LED1、LED2、LED3 所连接的 MCU 端口。
由原理图我们可以知道 LED 与之对应 GPIO 端口。
LED0--------PE6
LED1--------PA7
LED2--------PB5
LED3--------PB9
2、软件
库文件简介
在官网的开发工具中有一个帮助文件(hc32f46x_ddl_help_Rev1.3.0)该文件解压后为一个 HTML 的帮助文档,在该文档中可以找到库文件涉及的 数据结构和相应的 API 函数,此章以 GPIO 为例,简单介绍如何查找对应功能的 API 函数。
在目前文件(hc32f46x_ddl_Rev1.3.0)所使用的库文件版本做简单介绍,其中 GPIO 包含了如下图所示的 API 函数(在文件 hc32f46x_gpio.h 中)
在源文件中也可通过阅读代码了解到函数的功能,
此处大致介绍较为常用的 API 函数。
PORT_Init(en_port_t enPort, uint16_t u16Pin, const stc_port_init_t *pstcPortInit)
参数
参数1:en_port_t:为 GPIO的端口 PortA、PortB、PortC、PortD、PortE、PortH
参数2:en_pin_t:对应端口的引脚 0~15 & ALL
参数3:stc_port_init_t:端口的功能模式配置结构体,初始化方式与 ST 的类似。
对于该 API 函数稍作较细致分析,往后的篇幅中可能不会这么讲解,跳入初始化 API 函数中,如下图所示
在图中所示①处的操作是调试用到的,最里面的内容理解可以参照下面这篇文章理解,有兴趣的可以详细看看 __FILE__ 、__LINE__,这里暂不详细解释。
https://www.cnblogs.com/lixiaohui-ambition/archive/2012/08/21/2649052.html
在图中所示②处的操作与引脚的枚举变量有关,在文件 hc32f46x_gpio.h 中有如下图所示对 Pin 口的定义,结合这个地方的定义就能理解上述②处的循环操作。
个人觉得端口的定义可以直接定义为端口的数字,这样就会减少没必要的循环,只需要判断特殊的操作(对整个 PORT 操作)就可以避免对齐之一个端口操作带来的循环。毕竟对整个 PORT 操作没有对单独一个端口的操作常用。个人拙见,可以交流学习,细看源码能学习挺多的操作。
②处以下的操作是确定对应 PORT 和 Pin 口的 PCRxy、PFSRxy 寄存器基址,可以在用户手册的 9.4 寄存器说明找到如下所示的地址计算,和代码中相对应。
对于地址的计算可以详细看一下代码中的操作,理解联合体 union 、结构体 struct 的操作,就能理解②处以下的代码。
代码就大致讲这么多,关键在于对 union 和 struct 操作的理解,其他外设的地址也是如此对应的。
大致讲一下,不足之处还请指出
union 联合体也叫共用体 该用法与内存有关系
union 对内存的请求是按最大字节元素申请空间(而且与对齐有关系)
union
{
char a;
short b;
int c;
};
在上述的联合体中所占用的空间为 4byte
struct 的一个操作,如下所示的结构体所占用的内存为 16 Bit ,冒号后边的数字代表的是几个 Bit ,所以该结构占用 16 Bit
typedef struct
{
uint16_t :1;
uint16_t :2;
uint16_t :2;
uint16_t :4;
uint16_t :2;
uint16_t :2;
uint16_t :1;
uint16_t :1;
uint16_t :1;
}DR;
下面对例程 GPIO 代码的简介,应该会有人疑问时钟的初始化去哪了,时钟的初始化在 SystemInit 中被初始化,然后疑问又来了。SystemInit 在main函数中没找到,这个就要和单片机的启动有关系了,在 main 函数之前还有时钟初始化和 __main 函数的运行,这个我们要去启动文件中可以找到。Debug 时就可以看到运行的步骤,如下图所使
上述大致就是对GPIO的操作简述了,有兴趣想要深入了解的小伙伴,可以百度了解一下之前提到的一些。
点灯图
讲了这么多来张效果图吧
个人体会
相比较之下在国产中华大的库确实写的不错了,GD 、中微、用过对比一下就知道了。国外的话 ST 的库确实写的不错(毕竟玩的第一款 32 位 MCU),NXP 的库吧个人觉得宏定义太多,一个功能能宏定义三次或者更甚,目前没了解到这样做的原因,或许还没到境界吧 哈哈。接下来的测评文,对底层库的配置就不这么分析了,望大家理解。手抽了 半夜十一点多了,洗洗睡觉,明天还要搬砖。![](https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/sad.gif)
|