NRF52832NFC讀寫 NRF52832NFC讀寫

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文件中修改。

將:

  1. <code class="language-cpp"><span style="font-size:14px;">err_code = nfc_t2t_setup(nfc_callback, NULL);</span></code>  

代換成:

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文件中添加一個數組

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


添加後爲:



步驟三:修改回調函數

  1. static void nfc_callback(void * p_context, hal_nfc_event_t event, const uint8_t * p_data, size_t data_length)
  2. {
  3. uint8_t BNo = p_data[1];
  4. (void)p_context;
  5. uint8_t location;
  6. switch (event)
  7. {
  8. case HAL_NFC_EVENT_FIELD_ON:
  9. FLASH_BUFF_READ(&Test_Memory_Type2[16],0,80);
  10. if(Test_Memory_Type2[16]==0x03)
  11. {
  12. location=Test_Memory_Type2[17]+18-16;//¸ù¾ÝurlµÄ³¤¶È¼ÆËãIDËùÔÚµÄλÖÃ
  13. memcpy(&Test_Memory_Type2[location],DEVICE_ID,16);
  14. }
  15. memcpy(&Test_Memory_Type2[10],cc0_3,6);//ÿ´Î¸´ÖÆÊÇΪÁ˱£Ö¤cc0_3²»»á±»¸Ä±ä£¬·ñÔò¶ÁNFC»á³ö´í
  16. break;
  17. case HAL_NFC_EVENT_FIELD_OFF:
  18. LEDS_OFF(BSP_LED_0_MASK);
  19. break;
  20. case HAL_NFC_EVENT_DATA_RECEIVED:
  21. if (BNo<252){ /* Max Block number */
  22. hal_nfc_send(&Test_Memory_Type2[BNo*4], 16);
  23. }
  24. else
  25. /* hal_nfc_send(&Dymamic_Memory_Aera[0], 16); */
  26. hal_send_ack_nack(0x0); // NAck
  27. break;
  28. case HAL_NFC_EVENT_DATA_WRITE:
  29. if (data_length==6){ //NFCÿ´ÎÖ»ÄÜдһ¸ö¿é£¬¼´4¸ö×Ö½Ú¡£
  30. uint8_t i, c;
  31. for (i=0;i<4;i++) {
  32. c = p_data[2+i];
  33. Test_Memory_Type2[BNo*4 + i] = c;
  34. }
  35. hal_send_ack_nack(0xA); // Ack for write command
  36. FLASH_BUFF_UPDATE(&Test_Memory_Type2[16],0,80);
  37. }
  38. else {
  39. hal_send_ack_nack(0x0); // NAck for write command : should be 0, 1, 4 or 5
  40. }
  41. default:
  42. break;
  43. }
  44. }

修改後爲:



即增加了讀和寫分支。


同時需要在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)

  1. ret_code_t hal_send_ack_nack(uint8_t ack_nack_code) {
  2. static uint8_t Ack;
  3. Ack = ack_nack_code;
  4. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);
  5. NRF_NFCT->PACKETPTR = (uint32_t)(&Ack);
  6. NRF_NFCT->TXD.AMOUNT = 4;
  7. uint32_t reg = 0;
  8. /* reg |= (NFCT_TXD_FRAMECONFIG_PARITY_Parity << NFCT_TXD_FRAMECONFIG_PARITY_Pos); */
  9. reg |= (NFCT_TXD_FRAMECONFIG_SOF_SoF << NFCT_TXD_FRAMECONFIG_SOF_Pos);
  10. NRF_NFCT->TXD.FRAMECONFIG = reg;
  11. NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos);
  12. NRF_NFCT->TASKS_STARTTX = 1;
  13. return NRF_SUCCESS;
  14. }

增加後爲:



步驟五:hal_nfc_t2t.c中的函數hal_nfc_send修改爲:

  1. ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length)
  2. {
  3. if (data_length == 0)
  4. {
  5. return NRF_ERROR_DATA_SIZE;
  6. }
  7. /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */
  8. nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);
  9. NRF_NFCT->PACKETPTR = (uint32_t)(p_data);
  10. NRF_NFCT->TXD.AMOUNT = (data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & NFCT_TXD_AMOUNT_TXDATABYTES_Msk;
  11. uint32_t reg = 0;
  12. reg |= (NFCT_TXD_FRAMECONFIG_PARITY_Parity << NFCT_TXD_FRAMECONFIG_PARITY_Pos);
  13. reg |= (NFCT_TXD_FRAMECONFIG_DISCARDMODE_DiscardStart << NFCT_TXD_FRAMECONFIG_DISCARDMODE_Pos);
  14. reg |= (NFCT_TXD_FRAMECONFIG_SOF_SoF << NFCT_TXD_FRAMECONFIG_SOF_Pos);
  15. reg |= (NFCT_TXD_FRAMECONFIG_CRCMODETX_CRC16TX << NFCT_TXD_FRAMECONFIG_CRCMODETX_Pos);
  16. NRF_NFCT->TXD.FRAMECONFIG = reg;
  17. NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos);
  18. NRF_NFCT->TASKS_STARTTX = 1;
  19. // LOG_HAL_NFC("[NFC_HAL]: send");
  20. uint8_t i;
  21. for (i=0;i<data_length;i++) {
  22. // NRF_LOG_PRINTF(" %02X", *(data+i));
  23. }
  24. // NRF_LOG_PRINTF("\n");
  25. return NRF_SUCCESS;
  26. }

爲:



步驟六:最後在hal_nfc_t2t.c中修改NFCT_IRQHandler(void)函數。

  1. else if(m_nfc_rx_buffer[0] == T2T_WRITE_CMD)
  2. {
  3. if(m_nfc_lib_callback != NULL)
  4. {
  5. /* This callback should trigger transmission of READ Response */
  6. m_nfc_lib_callback(m_nfc_lib_context,
  7. HAL_NFC_EVENT_DATA_WRITE,
  8. (void*)m_nfc_rx_buffer,
  9. rx_data_size);
  10. }
  11. }


添加後爲:



好啦,修改到這裏就能實現nfc的數據讀寫了,具體需要實現什麼可以根據自己的需求進行修改。

其中數組est_Memory_Type2是模擬nfc的內存,具體代表什麼需要查看nfc方面的知識。


能力有限,歡迎糾錯!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章