NRF52832NFC读写

本文参考了nodic官网的问答。

nrf51822nrf52832都是nordic公司生产的低功耗ble芯片。nrf52832nrf51822的升级版,nrf52相比nrf51增加了nfc的功能。

但是官方给的固件中nfc的写功能被禁止了,也就是说如果使用官方给的库的话只能进行nfc的数据读取,而不能将数据写入的nrf52里面。这是个很大的限制,所以我下面将说明如何修改代码使nfc能进行写操作。

官方给的例程使用的是nfc_t2t_lib.h库文件,该库文件只留了一些接口给用户,所以使用起来还是比较麻烦的。在这里我使用的是hal_nfc_t2t.chal_nfc_t2t.h这两个文件。并且是在官方给的例程record_text的基础上进行修改的。

下面是具体的步骤:

步骤一:将使用nfc_t2t_lib.h库的函数代替成相应的hal_nfc_t2t.h库中的函数,首先在main文件中修改。

将:

err_code = nfc_t2t_setup(nfc_callback, NULL);

代换成:

err_code = hal_nfc_setup(nfc_callback, NULL);

相应的回调函数也要修改:

将:

static void nfc_callback(void * p_context, nfc_t2t_event_t event, const uint8_t *  p_data, size_t data_length);

修改成:

static void nfc_callback(void * p_context, hal_nfc_event_t event, const uint8_t * p_data, size_t data_length);

即修改了第二个参数。

修改前:


修改后:


接下来将这两行代码删除:



接下来将

err_code = nfc_t2t_emulation_start();

 代换为

err_code = hal_nfc_start();

修改前:


修改后为:



全部修改后main函数为:



步骤二:main.c文件中添加一个数组

static uint8_t Test_Memory_Type2[NFC_T2T_MAX_PAYLOAD_SIZE_RAW] = {
    0x5F, 0xF6, 0x4C, 0x6D, // Internal 0-3
    0x2F, 0xF4, 0xDA, 0x59, // Internal 4-7
    0x58, 0x03, 0x00, 0x00, // Internal 8-9 | Lock0-1       // <-- makes the card 
    0xE1, 0x10, 0x6D, 0x00, // CC0-3                        // <-- makes the 
    // page 4
    0x03, 0x16, 0xC1, 0x01, // TLV Tag field, Length field, Value field
    0x00, 0x00, 0x00, 0x0F, // NDEF Payload length 15
    0x54, 0x02, 0x65, 0x6E, // NDEF Message Type : Text UTF8, "Hello World!"
    0x48, 0x65, 0x6C, 0x6C, //
    // page 8
    0x6F, 0x20, 0x57, 0x6F,
    0x72, 0x6C, 0x64, 0x21, //
    0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00,
};


添加后为:



步骤三:修改回调函数

static void nfc_callback(void * p_context, hal_nfc_event_t event, const uint8_t * p_data, size_t data_length)
{
	  uint8_t BNo = p_data[1];
    (void)p_context;
    uint8_t location;
    switch (event)
    {
        case HAL_NFC_EVENT_FIELD_ON:
            FLASH_BUFF_READ(&Test_Memory_Type2[16],0,80);
            if(Test_Memory_Type2[16]==0x03)
            {
			          location=Test_Memory_Type2[17]+18-16;//¸ù¾ÝurlµÄ³¤¶È¼ÆËãIDËùÔÚµÄλÖÃ
							  memcpy(&Test_Memory_Type2[location],DEVICE_ID,16);
			      }
				    memcpy(&Test_Memory_Type2[10],cc0_3,6);//ÿ´Î¸´ÖÆÊÇΪÁ˱£Ö¤cc0_3²»»á±»¸Ä±ä£¬·ñÔò¶ÁNFC»á³ö´í
            break;
        case HAL_NFC_EVENT_FIELD_OFF:
            LEDS_OFF(BSP_LED_0_MASK);
            break;
				case HAL_NFC_EVENT_DATA_RECEIVED:
            if (BNo<252){ /* Max Block number */
                hal_nfc_send(&Test_Memory_Type2[BNo*4], 16);
						}
            else 
                /* hal_nfc_send(&Dymamic_Memory_Aera[0], 16); */
                hal_send_ack_nack(0x0); // NAck
            break;
				case HAL_NFC_EVENT_DATA_WRITE:
					  if (data_length==6){ //NFCÿ´ÎÖ»ÄÜдһ¸ö¿é£¬¼´4¸ö×Ö½Ú¡£
                uint8_t i, c;
                for (i=0;i<4;i++) {
                    c = p_data[2+i];
                    Test_Memory_Type2[BNo*4 + i] = c;
                }
								hal_send_ack_nack(0xA); // Ack for write command
								FLASH_BUFF_UPDATE(&Test_Memory_Type2[16],0,80);
            }
						else {
                hal_send_ack_nack(0x0); // NAck for write command : should be 0, 1, 4 or 5
            }
        default:
            break;
    }
}

修改后为:



即增加了读和写分支。


同时需要在hal_nfc_t2t.h中的枚举类型hal_nfc_event_t中增加HAL_NFC_EVENT_DATA_WRITE变量。




步骤四:hal_nfc_t2t.c中增加函数ret_code_t hal_send_ack_nack(uint8_t ack_nack_code)

ret_code_t hal_send_ack_nack(uint8_t ack_nack_code) {
        static uint8_t Ack;
        Ack = ack_nack_code;

        nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);

    NRF_NFCT->PACKETPTR     = (uint32_t)(&Ack);
    NRF_NFCT->TXD.AMOUNT    =  4;

    uint32_t reg = 0;
    /* reg |= (NFCT_TXD_FRAMECONFIG_PARITY_Parity << NFCT_TXD_FRAMECONFIG_PARITY_Pos); */
    reg |= (NFCT_TXD_FRAMECONFIG_SOF_SoF << NFCT_TXD_FRAMECONFIG_SOF_Pos);
    NRF_NFCT->TXD.FRAMECONFIG  = reg;
    NRF_NFCT->INTENSET      = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos);
    NRF_NFCT->TASKS_STARTTX = 1;

    return NRF_SUCCESS;
}

增加后为:



步骤五:hal_nfc_t2t.c中的函数hal_nfc_send修改为:

ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length)
{
	    if (data_length == 0)
    {
        return NRF_ERROR_DATA_SIZE;
    }
    /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */
    nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);

    NRF_NFCT->PACKETPTR     = (uint32_t)(p_data);
    NRF_NFCT->TXD.AMOUNT    = (data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & NFCT_TXD_AMOUNT_TXDATABYTES_Msk;

    uint32_t reg = 0;
    reg |= (NFCT_TXD_FRAMECONFIG_PARITY_Parity << NFCT_TXD_FRAMECONFIG_PARITY_Pos);
    reg |= (NFCT_TXD_FRAMECONFIG_DISCARDMODE_DiscardStart << NFCT_TXD_FRAMECONFIG_DISCARDMODE_Pos);
    reg |= (NFCT_TXD_FRAMECONFIG_SOF_SoF << NFCT_TXD_FRAMECONFIG_SOF_Pos);
    reg |= (NFCT_TXD_FRAMECONFIG_CRCMODETX_CRC16TX << NFCT_TXD_FRAMECONFIG_CRCMODETX_Pos);
    NRF_NFCT->TXD.FRAMECONFIG  = reg;

    NRF_NFCT->INTENSET      = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos);
    NRF_NFCT->TASKS_STARTTX = 1;

//    LOG_HAL_NFC("[NFC_HAL]: send");
    uint8_t i;
    for (i=0;i<data_length;i++) {
//            NRF_LOG_PRINTF(" %02X", *(data+i));
        }

//        NRF_LOG_PRINTF("\n");
        return NRF_SUCCESS;
}

为:



步骤六:最后在hal_nfc_t2t.c中修改NFCT_IRQHandler(void)函数。

else if(m_nfc_rx_buffer[0] == T2T_WRITE_CMD)
				{
				    if(m_nfc_lib_callback != NULL)
            {
                /* This callback should trigger transmission of READ Response */
                m_nfc_lib_callback(m_nfc_lib_context,
                                   HAL_NFC_EVENT_DATA_WRITE,
                                   (void*)m_nfc_rx_buffer,
                                   rx_data_size);
            }
				}


添加后为:



好啦,修改到这里就能实现nfc的数据读写了,具体需要实现什么可以根据自己的需求进行修改。

其中数组est_Memory_Type2是模拟nfc的内存,具体代表什么需要查看nfc方面的知识。


能力有限,欢迎纠错!




  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值