【极海APM32F407 Tiny Board】2.NFC卡读写测试(干货)
[复制链接]
在物联网产品中,我们会经常用到NFC刷卡。为此,我特意做了一个NFC刷卡的测评,经过半天的调试测试,终于成功了!
测试数据:
本次测评使用的是 mt626刷卡模块:
铭特MT625系列非接触式读卡器是基于操作ISO14443与ISO7816标准卡片的读卡模块,配有两个SIM卡座,可灵
活配置PSAM卡和ESAM卡。该产品在多种领域中得到广泛的应用,包括电动汽车充电桩、自助终端机、加油机、加气机、
停车场系统、自助售票机、自动售货机及身份认证终端等。
此模块的主要参数如下:
首先,我们需要对刷卡模组进行初始化:因为是串口连接,我们对mcu进行uart初始化即可。
void Mt626_init(void)
{
USART2_Init(115200);
vTaskDelay(1000);
Mt626_Check_Existing();
}
因为内部具有版本号,我们通过读版本号的方式,确定刷卡模块在物理上是否连接正常:
/*此接口可用于产测检测板子是否安装*/
ErrStatus Mt626_Check_Existing(void)
{
uint8_t sendbuff[7] = {0x02, 0x00, 0x02, 0x31, 0x40, 0x03, 0x72};
memset(&Uart_NFC, 0, sizeof(stUART_RX));
UartX_Put_Array(TINY_COM2, sendbuff, 7);
vTaskDelay(15);// 等待board应答,实测3ms左右
if(Uart_NFC.uart_rx.idle_flg)
{
if(Uart_NFC.uart_rx.buf[0] == STX)
{
if((Uart_NFC.uart_rx.buf[1] == 0x00) && (Uart_NFC.uart_rx.buf[2] == 0x0E))
{
memcpy(mt626_info_t.version, Uart_NFC.uart_rx.buf+5, 12);
printf("NFC Check OK : %s\r\n",mt626_info_t.version);
mt626_info_t.board_exist = true;
}
}
Uart_NFC.uart_rx.idle_flg = false;
}
else
{
printf("mt626 nfc board not exist!!!\r\n");
}
return SUCCESS;
}
接下来,我们就需要不断的轮询寻卡操作了:
// 寻卡
ErrStatus Mt626_Seeking_card(void)
{
ErrStatus ret;
uint8_t sendbuff[7] = {0x02, 0x00, 0x02, 0x34, 0x30, 0x03, 0x07};
memset(&Uart_NFC, 0, sizeof(stUART_RX));
UartX_Put_Array(TINY_COM2, sendbuff, 7);
vTaskDelay(100);// 等待board应答
if(Uart_NFC.uart_rx.idle_flg)
{
if(Uart_NFC.uart_rx.buf[0] == STX)
{
if((Uart_NFC.uart_rx.buf[1] == 0x00) && (Uart_NFC.uart_rx.buf[2] == 0x03))
{
if(Uart_NFC.uart_rx.buf[5] == 'Y')
{
mt626_info_t.card_state = true;
printf("NFC seek card OK!!\r\n");
ret = SUCCESS;
}
else
{
ret = ERROR;
}
}
}
Uart_NFC.uart_rx.idle_flg = false;
}
mt626_info_t.card_verify = false; // 清空上次操作的标志位
return ret;
}
如果有卡靠近,则模块会立即检测到!
那么寻卡成功后,我们需要怎么做呢? 那就是匹配物理卡号,看看用户使用的是否是我预设的卡,这样才能判断卡是否有效。
我们再添加一个鉴权的函数:
// 获取卡号并验证
ErrStatus Mt626_get_card_phynum_verify(void)
{
ErrStatus ret;
uint8_t sendbuff[7] = {0x02, 0x00, 0x02, 0x34, 0x31, 0x03, 0x06};
uint8_t phy_num[4];
memset(&Uart_NFC, 0, sizeof(stUART_RX));
UartX_Put_Array(TINY_COM2, sendbuff, 7);
vTaskDelay(100);// 等待board应答
if(Uart_NFC.uart_rx.idle_flg)
{
if(Uart_NFC.uart_rx.buf[0] == STX)
{
if((Uart_NFC.uart_rx.buf[1] == 0x00) && (Uart_NFC.uart_rx.buf[2] == 0x07))
{
/*
P = 0x59 寻卡成功
P = 0x4E 寻卡失败
*/
if(Uart_NFC.uart_rx.buf[5] == 'Y')
{
memcpy(phy_num, Uart_NFC.uart_rx.buf + 6, 4);
if(SUCCESS == Card_PHYNum_compare(phy_num))
{
mt626_info_t.card_verify = true;
ret = SUCCESS;
}
else
{
printf("card phy num not correct!!\r\n");
printf("card phy num : %02x %02x %02x %02x",phy_num[0],phy_num[1],phy_num[2],phy_num[3]);
ret = ERROR;
}
}
}
}
Uart_NFC.uart_rx.idle_flg = false;
}
return ret;
}
最终,我们在一个Task中不断轮询即可:
/*!
* [url=home.php?mod=space&uid=159083]@brief[/url] Led toggle task
* @param pvParameters - passed into the task function as the function parameters
* @retval None
*/
void vTaskUsartTest(void *pvParameters)
{
Mt626_init();
while(1)
{
vTaskDelay(200);
APM_TINY_LEDToggle(LED3);
nfc_card_process();
}
}
最终实验结果,完美成功!
附件中是整个完整的工程,欢迎大家留言哦。
|