我们今天将和大家一起实战操作基于立功科技的AMetal平台的MM32 MCU的LED灯控制程序。
在github上下载的源码已经为用户提供了工程模板,如果用户不打算重新新建工程,可以直接在工程模板上进行开发,如果用户需要使用自己的程序框架,用户可以参考灵动微电子官网(www.mm32mcu.com)应用说明栏的《AN0001 MDK5.18安装指南》或立功科技的《面向AMetal框架和接口的C编程》的1.2 搭建开发环境章节,在这里就不做过多的赘述。
在 AMetal 软件包中,目前已经支持的硬件平台,官方提供了对应的模板工程,位于 board/{board_name}目录中,通过board目录下的各个文件夹的命名,也可以知道 AMetal 当前支持了哪些 board。获取到 AMetal 软件包后,即可基于AMetal 快速开发应用程序。
为便于用户快速熟悉 AMetal,本节将以一个简单的示例——LED 闪烁来展示运行一个应用程序需要经历的一些基础步骤。
工程模板
首先, 需要打开手中硬件平台对应的模板工程。
工程模板目录为:
ametal/board/{board_name}/project_template
例如:硬件板Miniboard对应的工程模板为:
board\mm32l073_core\project_template\project_keil5
里面有 Keil 版工程,打开 project_template 工程文件夹。
在AMetal的官网都有介绍IAR、MDK和GCC的新建工程流程说明,大家如果有兴趣了解使用IAR和GCC工程可以上立功科技官网参考对应的指导文档,今天我们主要讲解基于MDK的工程构架。
工程框架
图1 工程框架
图1中的工程框架,在前一章节都有介绍。ARM 目录下存放着系统定时和中断控制;drives 目录下包含了该开发板支持的驱动源文件及实现;libc 目录下是 AMetal 开发平台相关的库文件;service 目录下面为用户提供的一些标准服务接口;soc 目录下是与芯片底层相关的一些功能实现;startup 目录下是系统启动文件;user_config 目录下为配置文件;user_code 目录下面为用户添加开发的文件。
在工程窗口中,目录user_code是存放用户程序的地方,点击user_code前面的“+”号可以显示该结点下所有的文件,默认只有一个文件main.c,双击main.c 便会出现main.c 的代码编辑窗口,如图1所示。
可以看到,main.c有一个am_main()函数,在 AMetal 中,用户程序的入口是 am_main() ,类似于 C 程序开发时的 main(), 用户的应用程序将从这里开始执行。程序的主体为一个永久循环, 循环中的第 1 行代码即 41 行代码是一个 am_led_toggle()接口, 是 AMetal 的通用标准接口,用于实现 led 状态翻转的功能;第二行调用了一个 am_mdelay()接口,同样是 AMetal 的通用标准接口,用于毫秒级的延时,两个接口在一个永久循环中交替执行,实现了 LED 闪烁的功能。
观察程序的第 41 行,可以发现接口 am_led_toggle()传入了一个参数 LED0,该参数实际上是一个宏,用以指定翻转的 LED, 宏 LED0 定义在 user_config 目录下的 am_board.h 文件中。
LED的宏定义
图2 LED的宏定义
宏 LED0 表示的是数字 0,看起来与 LED 并无关系,实际上,这里的数字 0 表示的是设备的 ID 号, AMetal 通过设备的 ID 号来区分硬件平台上不同的同类设备,因为示例中硬件平台上共有两个 LED,所以此处定义了两个宏,LED0 和 LED1, ID 号分别为 0 和 1。而实际物理层面上LED0 连接的引脚可以在user_config目录下的 am_hwconf_led_gpio.c 文件中找到。
LED的配置文件
图3 LED的配置文件
从图中可以看到, LED 设备的引脚信息被存放在文件 am_hwconf_led_gpio.c 文件中。在文件中的第 37 行定义了一个数组__g_led_pins, 存放了eMiniboard硬件平台上的两个 LED 对应的引脚编号,数组的第 0 号元素 PIOB_1 即为 LED0 对应的引脚编号, 第 1 号元素对应LED1,以此类推。当用户需要在其他平台上运行 AMetal 时,可通过修改这里的引脚编号,将程序中的 LED0 位于硬件平台上的 LED 设备对应起来,若实际硬件平台上的 LED 数量不是两个,可在__g_led_pins 数组中增加或减少元素并修改程序中第 43 行的 LED 结束编号。
实际上,在使用该工程的配套的硬件平台时,用户可完全不必关心这些信息,可直接在硬件平台上通过标号找到对应的 LED。
在 AMetal 中将这类命名以 am_hwconf 开头的文件称为用户配置文件,统一存放于user_config 目录下。am是 AMetal 缩写,表示该文件用于 AMetal 平台;hwconf 是 hardwareconfig 的缩写,意为硬件配置;led 表明该文件存放的是 LED 设备的硬件配置;后面的 gpio则是对 LED 的补充说明,表明该文件是存放的是通过 gpio 控制的 LED 设备的硬件配置。这些用户配置文件主要用于存放各设备的硬件相关信息,例如对应的引脚编号。
LED控制函数接口
图4 LED控制函数接口
在 AMetal 中,所有通用接口均以“am_” 开头,紧接着是操作对象的名字。此处对于LED 控制接口来说,所有接口都应该以“am_led_” 为前缀。
在LED的控制中,AMetal 提供了操作 GPIO 的标准接口函数,所有 GPIO 的标准接口函数原型位于ametal\inteRFace\am_gpio.h 文件中,其中包括一些 GPIO 相关的宏定义以及通用 GPIO 接口的声明。
AMetal提供了:
int am_led_set (int led_id, am_bool_t state)
int am_led_toggle (int led_id)
int am_led_on (int led_id)
int am_led_off (int led_id)
共4个函数
在 AMetal 中,通用接口的第一个参数表示要操作的具体对象。显然,一个系统可能有多个 LED,为了确定操作的 LED,最简单的方法是为每个 LED 分配一个唯一编号,即 ID 号,然后通过 ID 号确定需要操作的 LED。ID 号是一个从 0 开始的整数,其类型为 int,基于此,所有接口的第一个参数定义为 int 类型的 led_id。对于 am_led_set 接口来说,除使用 led_id 确定需要控制的 LED 外,还需要使用一个参数区分是点亮 LED 还是熄灭 LED。由于是二选一的操作,因此该参数的类型使用布尔类型:am_bool_t。当值为真(AM_TRUE)时,则点亮 LED;当值为假(AM_FALSE)时,则熄灭 LED。
基于此,包含参数的 am_led_set 接口函数原型为(还未定义返回值):
am_led_set(int led_id, am_bool_tstate)
对于am_led_on、am_led_off和 am_led_toggle 接口来说, 它们的职责单一, 仅仅需要指定控制的 LED, 即可完成点亮、熄灭或翻转操作,无需额外的其它参数。因此对于这类接口,参数仅仅只需要 led_id。
对于用户来说,调用通用接口后,应该可以获取本次执行的结果,成功还是失败,或一些其它的有用信息。比如,当调用接口时,如果指定的 led_id 超过有效范围时,由于没有与 led_id 对应的 LED 设备,操作必定会失败,此时必须返回错误,告知用户操作失败,且失败的原因是 led_id 不在有效范围内,无与之对应的 LED 设备。
在 AMetal 中,通过返回值返回接口执行的结果,其类型为 int,返回值的含义为:若返回值为 AM_OK,则表示操作成功;若返回值为负数,则表示操作失败,失败原因可根据返回值,查找 am_errno.h 文件中定义的宏,根据宏的含义确定失败的原因;若返回值为正数,其含义与具体接口相关,由具体接口定义,无特殊说明时,表明不会返回正数。
运行
至此,控制 LED 闪烁的应用程序介绍完毕,下一步即可对该程序进行编译并下载到硬件平台中运行了。
eMiniboard板载MM32-LINK OB,用户只需插上一根USB即可对MCU进行仿真调试,也可以提供供电,用户操作方便快捷,免去熟悉各种接口的困扰。
图5 下载程序
程序正确下载完成后,复位MCU,看到 LED0 灯不停地闪烁,说明程序下载成功。同时如果我们有接上UART模块,在MCU复位后可以看到输出字符串“Start up successful!\r\n”,表示复位执行程序正常。
|