射频识别(RFID)技术

ST25DV64K 开发

译者:陈广 日期:2020-6-21


前段时间在逛 B 站搜 NFC 资料时,意外看到意法半导体公司出的一套介绍 ST25 系列芯片的视频,网址如下:

ST25系列芯片介绍视频

看完这系列视频后,发现意法半导体出了一款 ST25DV 芯片,此芯片除了可作为 NFC 标签芯片外,还具备 I2C 接口,可通过单片机对内部数据进行访问。更为强大的是,手机可通过此芯片直接与单片机进行通信。由于一直在写 RFID 的书,对于 NFC 部分怎么写一直有疑惑,内容太多,举棋不定。看到这个视频,我已经知道,这就是我要讲的东西,而且应该作为 RFID 课程的重点。

说干就干,STM 官方出的系列开发板太贵,一块 ST25DV 评估板要 160 多,一个读卡器开发板要 400 多,摸摸干瘪的荷包,算了,还是自己做吧。呵呵,其实自己做花钱多多了。STM 官方的开发板,都会给出电路原理图,虽然我不会设计,但抄还是可以的。当然,为保险起见,还是从最简单的画起。单片机选用我最熟悉的 STM32F103RCT6,之前做键盘时有过成功使用的经验,外接一个 RGB 灯作为输出,然后使用 I2C 连接一个 ST25DV64K 芯片完事。基本就是一个最小系统加一块 ST25DV64K。电路原理图如下图所示:

图 1:电路原理图

注意,各位要学习这一块内容,只能对着这个原理图自己绘制并制作开发板了。ST25DV64K 在立创 EDA 中没有封装,只能自己画。现在有现成封装了,因为我画上去了(大家可搜索ST25DV64K)。原理图画完后,就要买原器件了,其它的都好说,就是 ST25DV64K 芯片太难买了,需要从国外购买,得等一个星期。而且价格较贵,10 来块钱。看来用此芯片的人并不多,价格是一个重要因素。不过我还是看好它的前景的,将来智能化社会,很多场景下还是有需求的。购买网址如下,买之前最好先跟店家联系:

https://item.taobao.com/item.htm?spm=a1z10.5-c.w4002-9367661473.10.66533558ls5Qwd&id=599541026813

不幸的是,板子回来后,焊 ST25DV64K 时才发现封装画反了,杯具了。原因是画原理图的时候手上没有现成芯片,另外就是马虎大意了。没办法,只能重新打板了,好在从这块板开始,我不再贴片了(实在烧不起钱贴片了),全手工焊接,损失不大,就是又多花了三天时间。上图留念,左边黑色的是翻车的板子,右边是第二次打的板子。为了焊接这些小元件,另外购买了一个热风枪焊台,解决了焊接的美观问题。板子焊完后发现能用,激动啊!可以开工写一系列文章了!

图 2:ST25DV64K 验证板

下面放一张 ST25DV64K 芯片的图像,自行脑补这芯片有多小,只能用热风枪焊接,焊接难度大。

图 3:ST25DV64K 芯片

有了开发板后,就可以开始写程序了。

配置 STM32CubeMX

这块开发板,配置了 USB 口,没有配置 UART 口,首先参照《自定义 HID 设备》这篇文章在 STM32CubeMX 中配置好 HID,先不要生成代码,等所有内容配置完成后再回来继续根据这篇文章生定向printf函数。

配置 PWM

开发板使用了一个 RGB 灯作为输出,由于本开发板最主要的功能是验证电路,我不想使用数码管液晶屏这类较为复杂的元件。普通的灯珠只能有一种颜色,RGB 灯可以变换不同的颜色,使用简单,价格便宜,观赏性强,作为本开发板的输出元件最合适不过,顺便还可以学习 PWM。关于 PWM 的基础知识,B 站上可以搜到很多,大家自行学习,我这里用自己的理解大概讲一下,帮大家入门。对于灯来说,可以使用高频闪烁让其点亮,而闪烁分为亮和灭两部分,可以控制亮和灭的时间,在高频的情况下,亮的时间越长,那么灯就越亮,如果灭的时间为 0,则灯达到最亮;灭的时间越长,则灯就越暗,如果亮的时间为 0,则灯就全灭了。也就是说可以通过控制亮和灭的时间比来控制灯的亮度,这个就是 PWM 中的占空比。

RGB 灯内部有三盏灯,红灯、绿灯、蓝灯,通过 PWM 控制三盏灯的亮度,可以混合出不同的颜色。一盏 RGB 灯需要连接三个配置为 PWM 功能的 GPIO 口。

接下来在 STM32CubeMX 中配置 PWM。在左侧面板中选中【Timers】项,选中其中的【TIM2】,按下图所示进行配置:

图 4:配置 PWM

需要注意的是 Prescaler 的计算公式为:频率/(255*255),即:72000000/(255*255)=1107,最终的 Prescaler 值需减 1。

这里先配置好,用到的时候再写代码,可能要等好久。

配置 I2C

由于 ST25DV64K 使用 I2C与单片机进行通信,所以需要配置 I2C。展开左侧面板的【Connectivity】项,选中【I2C1】项,按下图所示进行配置:

图 5:配置 I2C

配置 GPIO

ST25DV64K 有两个引脚 LPD 和 GPO,用于低功耗和信号输出,暂时还用不上,但电路上得画,查看电路原理图可看到连接这两个引脚的是 PC8 和 PC9 引脚。另外,开发板上有一个普通 LED 灯,连接的是 PD2 引脚。在 STM32CubeMX 右侧面板中对这三个引脚按下图所示进行配置:

图 6:配置 GPIO

配置 NFC

STM32CubeMx 居然还可以配置外部设备,实在是太强大了。单击屏幕上方【Additional software】选项卡。

图 7:Additional software 选项卡

在弹出的窗口中找到【STMicroetectronics.X-CUBE-NFC4】并展开,按照下图所示进行配置:

图 7:添加 NFC 支持

完成后单击【OK】按钮关闭此窗口。在主窗体左侧展开【Additional Software】项,选中其中的【STMicroetectronics.X-CUBE-NFC4.1.5.2】,按下图所示进行配置:

图 8:NFC 配置

STM32CubeMX 这块算是配置完成了,外部代码就这样写完了,实在是太爽!接下来写代码看看芯片是否可用。

代码编写

首先参照《自定义 HID 设备》这篇文章将printf重定向至 HID。

展开左侧【Application/User/NFC】,NFC 相关代码全在这里。

在 main.c 中添加头文件:

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "custom_nfc04a1_nfctag.h"
#include <stdio.h>
/* USER CODE END Includes */

main()函数中添加如下代码:

while( CUSTOM_NFCTAG_Init(CUSTOM_NFCTAG_INSTANCE) != NFCTAG_OK );
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);

插入位置如下图所示:

图 9:标签初始化

将程序烧进开发板,如果灯亮,说明没问题了!可以庆祝一下!

读取标签参数

接下来做点更复杂的事情,读取who am I、容量及 UID。

首先在 main.c 文件的/* USER CODE BEGIN PD */下方定义一个宏:

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define CUSTOM_NFCTAG_INSTANCE         (0)
/* USER CODE END PD */

接下来在main()函数中的while(1)循环处添加如下代码:

/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
    uint8_t wai;
/* USER CODE BEGIN 3 */
    //读取ST25DV64K的I2C地址(Who am I)
    if(CUSTOM_NFCTAG_ReadID(CUSTOM_NFCTAG_INSTANCE, &wai)==NFCTAG_OK)
    {
        printf("Address = %d\r\n", wai);
    }
    else
    {
        printf("Who am I read error!");
    }
    HAL_Delay(2000);
    //读取标签容量
    uint32_t size = CUSTOM_NFCTAG_GetByteSize(CUSTOM_NFCTAG_INSTANCE);
    printf("Memory Size = %d\r\n", size);
    HAL_Delay(2000);
    //读取标签 UID
    ST25DV_UID uid;
    if(CUSTOM_NFCTAG_ReadUID( CUSTOM_NFCTAG_INSTANCE, &uid )==NFCTAG_OK)
    {
        printf("uid = ");
        uint8_t *ptr = NULL;
        int i;
        ptr = (uint8_t *)&(uid.LsbUid);
        for(i=0;i<4;i++)
        {
            printf("%02X ", *ptr);
            ptr++;
        }
        ptr = (uint8_t *)&(uid.MsbUid);
        for(i=0;i<4;i++)
        {
            printf("%02X ", *ptr);
            ptr++;
        }
        printf("\r\n");
    }
    else
    {
        printf("UID read error!\r\n");
    }
    HAL_Delay(2000);
    printf("\r\n");
}
/* USER CODE END 3 */

运行程序,并打开单片机多功能调试助手,上位机接收到的数据如下图所示:

图 10:程序运行效果

可以看到,ST25DV64K 的 EEPROM 容量为 8K 字节,正好 64KBit。UID 的显示代码有些复杂,主要是为了依照我手头的读卡器读 15693 UID的格式来显示。

;

© 2018 - IOT小分队文章发布系统 v0.3