如何将 NXP NFC Reader Library 移植到 Keil

前言

NXP NFC Reader Library 是 NXP NFC 读卡器的官方库,里面包含了 NXP 针对不同卡片以及不同协议的实现代码。NXP 在提供读卡器库的同时,也提供了相应的应用层代码,实现了使用 MCU 调用 NFC 读卡器库的 API 从而操纵前端芯片检卡读卡写卡的功能。目前该文件可以在 NXP 官网上直接搜索 NFC Reader Library 免费下载。从功能上看,NXP NFC 的读卡器库确实很强大,但是 NXP 只提供了自己 IDE(MCUXpresso)的例程,而没有在其他常用 IDE(如 :Keil,IAR)上的参考例程。那么本文就来讲解,如何将 NXP NFC 的读卡器库,完美移植到 Keil 上。本文中使用的 MCU 为 LPC845。

一、准备工作

1、硬件准备

LPCXPresso845MAX 板 + NXP CLEV6630ARD 板或 BLE-NFC-V2 板

LPCXpresso845-MAX Board for LPC84x Microcontrollers (MCUs) | NXP Semiconductors



CLEV6630ARD: CLRC663 plus Arduino interface board | NXP Semiconductors

BLE-NFC-V2 板

直接将 CLEV6630ARD 或 BLE-NFC-V2 倒插在 LPCXPresso845MAX 板的 Arduino 接口上,即硬件准备就绪。如下图:

2、NFC Reader Library 下载

NFC Reader Library | NXP Semiconductors

建议下载 CLRC663 05.22.01 及其以前的版本。

3、Keil 5 下载

Keil Product Downloads

由于有 License 的限制,本文中使用的 Keil 版本为 Keil 5 V5.23.0.0

4、LPC845 SDK 下载

Select Board | MCUXpresso SDK Builder (nxp.com)

在 NXP 官网中,搜索 SDK Builder,登录后,在搜索栏输入 LPC845,然后点击右方的 Build MCUXpresso SDK 即可。

注意:由于 Keil 版本限制,最新的 SDK 不一定能够在旧版本的 Keil 上编译通过,所以可以选择之前的老 SDK 适配不同版本的 Keil。本文中使用的是 2.6.0 版本。

选择完之后,会出现如下的选项,需要选择对应的系统,对应的 IDE,以及 SDK 里包含的库。这里选择 Windows,arm KEIL,和 CMSIS DSP Library,最后点击 Download SDK。

二、 开始移植

1、打开一个工程

解压缩 SDK ,打开一个 Keil 的工程,这里直接打开 Hello World。

注意:这里第一次打开需要下载对应芯片的 DFP 文件。

点击导航栏上的 Pack Installer,如下图:

在搜索栏输入 LPC845,然后下载对应的 DFP 文件。

下载完成后,先编译 Hello World 工程,确保 SDK 和 IDE 均无问题。编译成功后,如下图:


2、复制文件到工程目录

复制前:

复制后:


3、添加路径

在 Keil 中的魔法棒 -> C/C++ -> Include Paths 中添加上一步复制的文件夹的路径变量


4、在工程中添加 .c .h 文件

先添加文件夹,然后在对应的文件夹中,将 .c .h 文件添加进来。

添加后如下:

注意:NxpNfcRdLib 中,文件较多,需要耐心的将所有文件都导入进来。


5、替换主函数 .c 文件

将原工程中的 hello_world.c 替换为 NfcrdlibEx1_BasicDiscoveryLoop.c 和 phApp_Init.c,并在工程中导入进来。

替换前:

替换后:


6、替换引脚配置

将原工程中 pin_mux.c 的 BOARD_InitPins(void) 函数替换为如下代码

void BOARD_InitPins(void)
{
/* Enables clock for IOCON.: enable */
CLOCK_EnableClock(kCLOCK_Iocon);
/* Enables clock for switch matrix.: enable */
CLOCK_EnableClock(kCLOCK_Swm);

const uint32_t IOCON_INDEX_PIO1_16_config = (/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Enable hysteresis */
IOCON_PIO_HYS_EN |
/* Input not invert */
IOCON_PIO_INV_DI |
/* Disables Open-drain function */
IOCON_PIO_OD_DI |
/* Bypass input filter */

IOCON_PIO_SMODE_BYPASS |
/* IOCONCLKDIV0 */
IOCON_PIO_CLKDIV0);
/* PORT1 PIN16 (coords: ) is configured as */
IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_16, IOCON_INDEX_PIO1_16_config);

const uint32_t IOCON_INDEX_PIO1_17_config = (/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Enable hysteresis */
IOCON_PIO_HYS_EN |
/* Input not invert */
IOCON_PIO_INV_DI |
/* Disables Open-drain function */
IOCON_PIO_OD_DI |
/* Bypass input filter */
IOCON_PIO_SMODE_BYPASS |
/* IOCONCLKDIV0 */
IOCON_PIO_CLKDIV0);
/* PORT1 PIN17 (coords: ) is configured as */
IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_17, IOCON_INDEX_PIO1_17_config);

/* Init LPCXpresso845MAX Board LED - D3 */
const uint32_t IOCON_INDEX_PIO0_12_config = (/* Selects pull-up function */
IOCON_PIO_MODE_PULLUP |
/* Enable hysteresis */
IOCON_PIO_HYS_EN |
/* Input not invert */
IOCON_PIO_INV_DI |
/* Disables Open-drain function */
IOCON_PIO_OD_DI |
/* Bypass input filter */
IOCON_PIO_SMODE_BYPASS |
/* IOCONCLKDIV0 */
IOCON_PIO_CLKDIV0);
/* PORT0 PIN12 (coords: ) is configured as */
IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_12, IOCON_INDEX_PIO0_12_config);

IOCON->PIO[52] = ((IOCON->PIO[52] &
/* Mask bits to zero which are setting */
(~(IOCON_PIO_MODE_MASK | IOCON_PIO_OD_MASK)))

/* Selects function mode (on-chip pull-up/pull-down resistor control).: Pull-down. Pull-down
* resistor enabled. */
| IOCON_PIO_MODE(PIO1_20_MODE_PULL_DOWN)

/* Open-drain mode.: Open-drain mode enabled. Remark: This is not a true open-drain mode. */
| IOCON_PIO_OD(PIO1_20_OD_ENABLED));

IOCON->PIO[53] = ((IOCON->PIO[53] &
/* Mask bits to zero which are setting */
(~(IOCON_PIO_OD_MASK)))

/* Open-drain mode.: Open-drain mode enabled. Remark: This is not a true open-drain mode. */
| IOCON_PIO_OD(PIO1_21_OD_ENABLED));

/* Init LPCXpresso845MAX Board LED - D3 */
GPIO->DIR[0] = ((GPIO->DIR[0] &
/* Mask bits to zero which are setting */
(~(GPIO_DIR_DIRP_MASK)))

/* Selects pin direction for pin PIOm_n (bit 0 = PIOn_0, bit 1 = PIOn_1, etc.). Supported pins
* depends on the specific device and package. 0 = input. 1 = output.: 0x1000u */
| GPIO_DIR_DIRP(0x1000u));

/* USART0_TXD connect to P1_17 */
SWM_SetMovablePinSelect(SWM0, kSWM_USART0_TXD, kSWM_PortPin_P1_17);

/* USART0_RXD connect to P1_16 */
SWM_SetMovablePinSelect(SWM0, kSWM_USART0_RXD, kSWM_PortPin_P1_16);

/* SPI0_SCK connect to P0_6 */
SWM_SetMovablePinSelect(SWM0, kSWM_SPI0_SCK, kSWM_PortPin_P0_6);

/* SPI0_MOSI connect to P1_19 */
SWM_SetMovablePinSelect(SWM0, kSWM_SPI0_MOSI, kSWM_PortPin_P1_19);

/* SPI0_MISO connect to P0_7 */
SWM_SetMovablePinSelect(SWM0, kSWM_SPI0_MISO, kSWM_PortPin_P0_7);

/* Disable clock for switch matrix. */
CLOCK_DisableClock(kCLOCK_Swm);
}


7、宏定义配置

在 Keil 中的魔法棒 -> C/C++ -> Define 中添加宏定义

CPU_LPC845M301JBD64,PH_OSAL_NULLOS,NXPBUILD_CUSTOMER_HEADER_INCLUDED,PHDRIVER_LPC845RC663_BOARD

注意:中间的间隔符为英文的逗号


8、编译

可以将工程名更改为LPC845_CLRC663_BasicDiscLoop_SPI,编译通过后如下:

三、Demo 测试

编译通过之后,就可以进行 Demo 测试了,先按下 845 板子上的 ISP 键,然后 Reset,使板子进入 ISP 模式,然后使用 Keil 进行下载。

下载完成后,打开串口助手,波特率设置为 9600,Reset 板子,出现打印字样,如下:

刷 Type 2 Tag ,打印如下:


至此,移植工程全部完毕,移植成功~

技术文档

类型标题档案
软件SDK

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论