打印
[蓝牙芯片]

【CH585M测评】NFC阅读器初体验

[复制链接]
88|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
最近收到了沁恒的CH585M开发板,其实我对这个开发板是非常期待的,本身我就是做射频方面的应用,看到沁恒有这款MCU+NFC的方案我是非常愿意尝试一下的,这不就心随人愿,有幸的申请到了开发板嘛,接下来我们就来看看这个开发板。
图1 CH585M开发板
通过图1可以看出,开发板确实十分的简洁,板载一个MCU,该MCU支持蓝牙与NFC,所以有2个天线,但是布局很有考究,两个天线方向和距离都很远,所以干扰的情况会大大降低;接下来是板载两个USB接口,用的是Type-c接口,这两个分别是HS和FS,FS是可以做USB烧录口来使用;接下来是板载两个按键,一个是复位按键一个是boot按键,也就是烧录时候会用到,下来就是一些必备的阻容件和晶振等等元件了。其实可以看出,沁恒很为客户来考虑,就非常少的元器件就可以实现一个核心板的功能,这样不仅仅可以降低成本,也可以减少电路设计时容易出现的错误。
接下来就来玩耍一下NFC吧,其实CH585M是支持NFC模拟卡和读卡器两种功能的,也就是说该芯片十分的强大,本次就来体验一下读卡器的功能吧,利用程序实现读卡功能,利用串口1实现数据的输出,并且添加了一点串**互,利用串口发送命令实现对卡的读取等等;
首先去官网下载好开发资料,然后找到对应的工程,本次利用MifareClassic的工程为模板,来学习读卡器功能。

图2 工程示例
打开工程之后找到主函数,一般阅读程序都是要从主函数来阅读的。根据程序可以看出,驱动NFC功能非常简单,主要是配置一下nfca_pcd_init();具体代码如下:
void nfca_pcd_init(void)
{
    nfca_pcd_config_t cfg;

    /* NFC引脚初始化为模拟输入模式 */
    GPIOB_ModeCfg(GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_16 | GPIO_Pin_17, GPIO_ModeIN_Floating);

    /* 关闭GPIO数字输入功能 */
    R32_PIN_IN_DIS |= ((GPIO_Pin_8 | GPIO_Pin_9) << 16);        /* 关闭GPIOB中GPIO_Pin_8和GPIO_Pin_9的数字输入功能 */
    R16_PIN_CONFIG |= ((GPIO_Pin_16 | GPIO_Pin_17) >> 8);       /* 关闭GPIOB中GPIO_Pin_16和GPIO_Pin_17的数字输入功能 */

    /* CH584F和CH585F内部PA9和PB9短接,需要将PA9也设置为模拟输入并关闭数字功能,M封装注释下面的两句代码,F封装取消注释 */
//    GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeIN_Floating);
//    R32_PIN_IN_DIS |= GPIO_Pin_9;

    cfg.data_buf = gs_nfca_pcd_data_buf;
    cfg.data_buf_size = NFCA_PCD_DATA_BUF_SIZE;

    cfg.send_buf = g_nfca_pcd_send_buf;
    cfg.send_buf_size = NFCA_PCD_MAX_SEND_NUM;

    cfg.recv_buf = g_nfca_pcd_recv_buf;
    cfg.recv_buf_size = NFCA_PCD_MAX_RECV_NUM;

    cfg.parity_buf = g_nfca_pcd_parity_buf;
    cfg.parity_buf_size = NFCA_PCD_MAX_PARITY_NUM;

    /* 将数据区指针传入给NFC库内BUFFER指针 */
    nfca_pcd_lib_init(&cfg);

#if NFCA_PCD_USE_NFC_CTR_PIN
    nfca_pcd_ctr_init();
#endif

}

接下来就是针对天线的低功耗检卡ADC值校准,虽然不知道干啥的,但是照做就对了,至此,NFC部分就初始化成功了,接下来初始化串口,串口的话官方都有提供完整的例子,我就不提了,再接下来就是设想IC读卡器的功能,本来是想用USB和蓝牙实现的,奈何沁恒的蓝牙部分我还不熟悉,所以就先拿串口来模拟实现吧,主要是有数据交互,也就是串口接收到指令,会实现对卡的一些操作,比如读卡的UID,指定卡扇区,读卡里内容,或者增加卡密钥等等,本次就先做个简单的发送指令读取UID吧,代码如下:
int main(void)
{
    UINT16 x;
    uint8_t len;
    uint8_t res;
    char buf[100] = {'\0'};
    PWR_DCDCCfg(ENABLE);
    SetSysClock(CLK_SOURCE_HSE_PLL_62_4MHz);

#ifdef DEBUG
    GPIOA_SetBits(GPIO_Pin_14);
    GPIOPinRemap(ENABLE, RB_PIN_UART0);
    GPIOA_ModeCfg(GPIO_Pin_14, GPIO_ModeOut_PP_5mA);
    UART0_DefInit();
#endif
    /* 配置串口1:先配置IO口模式,再配置串口 */
    GPIOA_SetBits(GPIO_Pin_9);
    GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);      // RXD-配置上拉输入
    GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出,注意先让IO口输出高电平
    UART1_DefInit();

    PRINT("NFCA PCD START\n");

    nfca_pcd_init();

    nfca_pcd_lpcd_calibration();    /* 低功耗检卡ADC值校准,和天线等相关,可在生产时进行检测。 */

//    nfca_pcd_test();

#if 1 // 测试串口发送字符串
    UART1_SendString(TxBuff, sizeof(TxBuff));

#endif

    while(1)
    {
        len = UART1_RecvString(RxBuff);
        if(len)
        {
            switch (RxBuff[0])
            {
            case 1:
                nfca_pcd_start();
                mDelaymS(1);   /* 手机等模拟卡设备需要长时间的连续波唤醒其卡功能,普通实体卡 1 ms 即可 */

                #if NFCA_PCD_USE_NFC_CTR_PIN
                        nfca_pcd_ctr_handle();  /* 对天线信号进行检测,使用NFC CTR引脚控制幅度 */
                #endif

                        res = PcdRequest(PICC_REQALL);
                        if(res == 0x0004)
                        {
                            res = PcdAnticoll(PICC_ANTICOLL1);
                            if (res == PCD_NO_ERROR)
                            {
                                picc_uid[0] = g_nfca_pcd_recv_buf[0];
                                picc_uid[1] = g_nfca_pcd_recv_buf[1];
                                picc_uid[2] = g_nfca_pcd_recv_buf[2];
                                picc_uid[3] = g_nfca_pcd_recv_buf[3];
                                PRINTF("uid: %02x %02x %02x %02x\n", picc_uid[0], picc_uid[1], picc_uid[2], picc_uid[3]);
                                sprintf(buf,"uid: %02x %02x %02x %02x\n", picc_uid[0], picc_uid[1], picc_uid[2], picc_uid[3]);
                                UART1_SendString(buf, strlen(buf));
//                                res = PcdSelect(PICC_ANTICOLL1, picc_uid);
//                                if (res == PCD_NO_ERROR)
//                                {
//                                    PRINTF("\nselect OK, SAK:%02x\n", g_nfca_pcd_recv_buf[0]);
//                                }
                            }
                        }
                break;
            case 2:
                UART1_SendString(RxBuff, len);
                break;

            }
        }
    }

//    while(1);
}
代码较为简单,就是给MCU发送个01,然后读取卡的UID,并且返回给串口,直接给大家看效果吧。
图3 测试结果
图4 用手机读取到的卡的UID与串口返回的一致
可以看出uid是一致的,说明读取的是正确的,总的来说还是比较简单的,主要是一些具体的功能我还没来得及添加,后续会完善的,点评一下CH585M就是这个芯片确实讨喜,这么小的封装,有这这么高端的功能,而且芯片价格还不贵,不过在体验的时候发现射频读卡距离还是有优化的空间的,一般是可以通过调整RF的增益来实现,不知道沁恒是否支持这种功能,还是只能通过优化硬件电路来实现呢,留个悬念吧,不过感觉做IC阅读器确实是个不错的选择,后续再完善完善,随时与大家分享,敬请期待吧~

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:嵌入式技术专家
简介:擅长电路设计、物联网产品开发、射频产品开发,喜欢打篮球,技术交流,欢迎各位来聊~

686

主题

2875

帖子

6

粉丝