OYのアイコン画像
OY 2026年03月04日作成 © CC0 1+
セットアップや使用方法 セットアップや使用方法 閲覧数 170
OY 2026年03月04日作成 © CC0 1+ セットアップや使用方法 セットアップや使用方法 閲覧数 170

STM32C011F4P6でNFCタグを読む(M5Stack Unit RFID2)

STM32C011F4P6でNFCタグを読む(M5Stack Unit RFID2)

はじめに

前回「STM32C011F4P6のLチカ(ST-LINK/V2, Nucleo開発ボードC031C6)」 の続きです。

今回は、STM32C011F4P6とM5Stack Unit RFID2を使って NTAG215の読み取り行います。
また電子工作初心者ですので、誤ったことを記載している可能性があります。
ご了承ください。

ブロック図

キャプションを入力できます

部品, 備品類

部品

AE-STM32C011F4P6-DIP(秋月電子キット)
Nucleo Board STM32C031C6
ブレッドボード(BB-801を使っています)
ジャンパーワイヤー オス-オス
ジャンパーワイヤー オス-メス
ピンヘッダ 2pcs
USB A-マイクロB(2.0) (Nucleoボード接続用)
M5Stack用WS1850S搭載 RFID 2ユニット, 型番:M5STACK-U031-B(スイッチサイエンス)
NTAG215(AmazonのYFFSFDC NFCタグ NTAG215 30枚)

備品, ソフト

パソコン(Windows11を使いました)
はんだごて、はんだ
STM32CubeMX
STM32CubeIDE
NFC Tools(iPhone版を使いました)

準備

Nucleoボードのはんだづけ

ジャンパワイヤー接続用のピンヘッダをはんだづけします。

1.(図の左上)UART通信用のTX, RXにピンヘッダをつけます。
2.(図の右上)JP2のジャンパーピンを外し、TX, RXにピンヘッダーを挿入します。
3.(図の中央左)小型のブレッドボードで固定し、基板を裏返します。
4.(図の中央右)TX, RXをはんだ付けします。
5.(図の左下)ブレッドボードを外したらはんだ付け完了です。
キャプションを入力できます

基板裏面のSB23ジャンパーチップを外していない場合、
前回 を確認して外してください。

NTAGの書き込み (NFC Tools)

iPhoneでの操作です。
「書く」→「レコードを追加」→「テキスト」→
キャプションを入力できます

「001」を入力 →「✓」→「書き込み/10バイト」→「スキャンの準備ができました」
→ スマートフォンにNTAG215を近づけて書き込み
キャプションを入力できます

必須ではありませんが余裕があれば、
同様に残り2枚のNTAGへ「002」, 「003」と書き込みます。
書き込んだNTAGは、「読む」をタップしてスキャンすることで、書き込んだ数字を確認できます。

Eclipse Terminalのインストール (STM32CubeIDEのシリアルモニター)

STM32CubeIDEを起動。
上部メニューの「help」→「Eclipse Marketplace」→「find」に下記を入力し「enter」→「install」
https://marketplace.eclipse.org/content/tm-terminal
キャプションを入力できます

「confirm」→「finish」
キャプションを入力できます

「restart now」IDEが再起動する
キャプションを入力できます

STM32CubeIDE 上部メニューの「Window」 → 「Show View」 → 「Other」
検索窓に「terminal」と入力。
→「terminal」を選択後 →「open」
キャプションを入力できます

IDE右下にTerminalが表示
キャプションを入力できます

Terminal内のメニューより、「Open a Terminal」アイコン →
表示ウインドウの「Choose terminal:Serial Terminal」を選択。
「Serial port」よりデバッガのCOM番号を選択を選択してください。
「OK」クリックでデバッガの情報がTerminalへ表示可能となります。
キャプションを入力できます

Windows11でのCOM番号の調べ方は下記です。
「Windowsスタートボタン」を右クリック → 「デバイスマネージャー」→
「ポート」のツリーを展開、デバッガのCOM番号をチェックしてください。
今回はCOM4です。
キャプションを入力できます

初期設定とプログラムのビルド

ピン設定等の初期設定、コード生成

STM32CubeMXを起動します。
File → New Project をクリック。
キャプションを入力できます

ウインドウが表示されますので使用するマイコンを「Commercial Part Number」に入力します。(今回はSTM32C011F4P6)
MCUs/MCUs Listから選択 → Start Project をクリック。
キャプションを入力できます

ピンの設定画面が表示されますので、ピン設定を行います。
 PB7:I2C1_SCL
 PC14:I2C1_SDA
 PA0:USART1_TX
 PA1:USART1_RX
キャプションを入力できます

左メニューの「Connectivity」→「I2C1」→Modeを「I2C」へ変更します。
キャプションを入力できます

左メニューの「Connectivity」→「USART1」→Modeを「Asynchronous」へ変更します。
キャプションを入力できます

「Project Manager」タブを押し、
「Project Name」にファイル名を記入
「Project Location」にて保存場所を選択
「Toolchain /IDE」をSTM32CubeIDEを選択

「GENERATE CODE」を押し、コード生成

※プロジェクトネームに"()"を使うと、ビルド時にエラーが発生するため使わないでください。
※プロジェクトロケーションは「CubeMX」直下としてください。
 「CubeMX\プロジェクトネーム」とした場合、CubeIDEでエラーが発生します。
キャプションを入力できます
※画像は前回のものです。

コード生成後のウィンドウで、「Open Project」をクリックすると
自動でSTM32CubeIDEが起動し、インポートしてくれます。
キャプションを入力できます
※画像は前回のものです。

コード入力、ビルド

STMCubeIDEのインポートしたプロジェクト内「Core」 → 「Src」 → 「main.c」にコードを記入します。

コードは下記範囲内にコピペしてください。
/* USER CODE BEGIN Header /
 コードのコピペ
/
USER CODE END 3 */

NTAG215

/* USER CODE BEGIN Header */ /* * STM32 Port of M5Stack RFID2 / MFRC522_I2C functionality * * This code is released under the Creative Commons Public Domain Dedication * version 1.0 or later (CC0 1+). * To the extent possible under law, the author has waived all copyright * and related or neighboring rights to this work. * You may copy, modify, distribute and perform the work, even for commercial * purposes, all without asking permission. * * ------------------------------------------------------------------------- * Third-party components and licenses * ------------------------------------------------------------------------- * * MFRC522_I2C Library (arozcan) * - Public Domain * - https://github.com/arozcan/MFRC522-I2C-Library * * M5Unified (M5Stack) * - MIT License * - Copyright (c) M5Stack * - https://github.com/m5stack/M5Unified * * M5Stack Unit RFID / RFID2 documentation * - No explicit license noted in documentation * - Uses official M5Stack libraries (MIT License) * - https://docs.m5stack.com/ja/arduino/projects/unit/unit_rfid * * MIT License portions are used in accordance with their terms. * */ /** ****************************************************************************** * @file : main.c * @brief : NTAG215 テキスト(3桁数字) 読み取り * STM32C011F4P6 + M5Stack RFID2 Unit (WS1850S) * * 配線: * RFID2 SCL → PB7 (I2C1_SCL) * RFID2 SDA → PC14 (I2C1_SDA) * RFID2 VCC → 3.3V / GND → GND * ST-LINK → PA0(USART1_TX) / PA1(USART1_RX) ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* USER CODE BEGIN Includes */ /* stdio.h / string.h 不使用 */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ typedef enum { MFRC_OK = 0, MFRC_ERROR = 1, MFRC_TIMEOUT = 2 } MFRC_Status; /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* I2C アドレス (7bit=0x28 → HAL用8bit) */ #define RFID2_ADDR (0x28 << 1) /* ---- WS1850S (MFRC522互換) レジスタ ---- */ #define REG_CommandReg 0x01 #define REG_ComIrqReg 0x04 #define REG_ErrorReg 0x06 #define REG_FIFODataReg 0x09 #define REG_FIFOLevelReg 0x0A #define REG_BitFramingReg 0x0D #define REG_CollReg 0x0E #define REG_ModeReg 0x11 #define REG_TxControlReg 0x14 #define REG_TxASKReg 0x15 #define REG_RFCfgReg 0x26 #define REG_CRCResultRegH 0x21 #define REG_CRCResultRegL 0x22 #define REG_TModeReg 0x2A #define REG_TPrescalerReg 0x2B #define REG_TReloadRegH 0x2C #define REG_TReloadRegL 0x2D #define REG_VersionReg 0x37 /* ---- コマンド ---- */ #define CMD_Idle 0x00 #define CMD_CalcCRC 0x03 #define CMD_Transceive 0x0C #define CMD_SoftReset 0x0F /* ---- NFC コマンド ---- */ #define PICC_REQA 0x26 #define PICC_CT 0x88 /* Cascade Tag (7バイトUID用) */ #define PICC_SEL_CL1 0x93 /* Cascade Level 1 */ #define PICC_SEL_CL2 0x95 /* Cascade Level 2 (NTAG215必須) */ #define PICC_HLTA 0x50 #define NTAG_READ 0x30 /* ErrorReg マスク * CollErr(bit3)はAntiColl時に正常で立つため除外 * bit0=ProtocolErr / bit1=ParityErr / bit4=BufferOvfl のみ判定 */ #define ERR_MASK_STRICT 0x13 #define ERR_MASK_ANTICOLL 0x13 /* HAL_Delay 固定待機時間 (ms) * IRQポーリング廃止・待機中はI2C通信なし → WS1850SがNFCに専念 */ #define WAIT_MS_REQA 15u #define WAIT_MS_ANTICOLL 25u #define WAIT_MS_SELECT 30u #define WAIT_MS_READ 30u #define WAIT_MS_CRC 5u /* デバッグ出力切り替え * 0 = 本番モード: 結果のみ出力 (STM32C011F4P6 FLASH節約) * 1 = デバッグモード: v9相当の詳細ログ出力 */ #define RFID_DEBUG 0 /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* デバッグ出力マクロ * RFID_DEBUG=0 のとき空文に展開されFLASHを消費しない */ #if RFID_DEBUG #define DBG_STR(s) uart_str(s) #define DBG_HEX8(v) uart_hex8(v) #define DBG_CRLF() uart_crlf() #else #define DBG_STR(s) ((void)0) #define DBG_HEX8(v) ((void)0) #define DBG_CRLF() ((void)0) #endif /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart1; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_I2C1_Init(void); static void MX_USART1_UART_Init(void); /* USER CODE BEGIN PFP */ static void uart_str(const char *s); static void uart_hex8(uint8_t v); static void uart_crlf(void); static void mfrc_write(uint8_t reg, uint8_t val); static uint8_t mfrc_read(uint8_t reg); static void mfrc_read_burst(uint8_t reg, uint8_t *buf, uint8_t len); static void mfrc_set_bits(uint8_t reg, uint8_t mask); static void mfrc_clear_bits(uint8_t reg, uint8_t mask); static void mfrc_fifo_flush(void); static void mfrc_init(void); static MFRC_Status mfrc_transceive(uint8_t *tx, uint8_t txLen, uint8_t *rx, uint8_t *rxLen, uint8_t errMask, uint32_t waitMs); static MFRC_Status mfrc_calc_crc(uint8_t *data, uint8_t len, uint8_t *crcLow, uint8_t *crcHigh); static MFRC_Status ntag_request(void); static MFRC_Status ntag_select_7byte(uint8_t *uid7); static MFRC_Status ntag_read_page(uint8_t page, uint8_t *data16); static uint8_t extract_3digit(uint8_t *raw, uint8_t len, char *out3); static void rfid_task(void); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* ================================================================ * UARTユーティリティ (stdio.h不使用) * ================================================================ */ static void uart_str(const char *s) { while (*s) HAL_UART_Transmit(&huart1, (uint8_t *)s++, 1, 100); } static void uart_hex8(uint8_t v) { const char h[] = "0123456789ABCDEF"; uint8_t buf[2]; buf[0] = (uint8_t)h[(v >> 4) & 0x0F]; buf[1] = (uint8_t)h[v & 0x0F]; HAL_UART_Transmit(&huart1, buf, 2, 100); } static void uart_crlf(void) { uart_str("\r\n"); } /* ================================================================ * WS1850S I2Cドライバ * ================================================================ */ static void mfrc_write(uint8_t reg, uint8_t val) { uint8_t buf[2] = { reg, val }; HAL_I2C_Master_Transmit(&hi2c1, RFID2_ADDR, buf, 2, 100); } static uint8_t mfrc_read(uint8_t reg) { uint8_t val = 0; HAL_I2C_Master_Transmit(&hi2c1, RFID2_ADDR, &reg, 1, 100); HAL_I2C_Master_Receive (&hi2c1, RFID2_ADDR, &val, 1, 100); return val; } static void mfrc_read_burst(uint8_t reg, uint8_t *buf, uint8_t len) { HAL_I2C_Master_Transmit(&hi2c1, RFID2_ADDR, &reg, 1, 100); HAL_I2C_Master_Receive (&hi2c1, RFID2_ADDR, buf, len, 100); } static void mfrc_set_bits(uint8_t reg, uint8_t mask) { mfrc_write(reg, mfrc_read(reg) | mask); } static void mfrc_clear_bits(uint8_t reg, uint8_t mask) { mfrc_write(reg, mfrc_read(reg) & ~mask); } /* FIFOを確実にクリアする */ static void mfrc_fifo_flush(void) { mfrc_write(REG_FIFOLevelReg, 0x80); HAL_Delay(1); } static void mfrc_init(void) { mfrc_write(REG_CommandReg, CMD_SoftReset); HAL_Delay(100); mfrc_write(REG_TModeReg, 0x80); mfrc_write(REG_TPrescalerReg, 0xA9); mfrc_write(REG_TReloadRegH, 0x03); mfrc_write(REG_TReloadRegL, 0xE8); mfrc_write(REG_TxASKReg, 0x40); mfrc_write(REG_ModeReg, 0x3D); mfrc_set_bits(REG_RFCfgReg, 0x70); /* アンテナゲイン最大 */ mfrc_set_bits(REG_TxControlReg, 0x03); /* アンテナON */ mfrc_write(REG_BitFramingReg, 0x00); /* BitFraming初期化 */ } /* ================================================================ * mfrc_transceive() * 【重要】送信シーケンスの正しい順序 : * ① CommandReg = CMD_Transceive (先にコマンドをセット) * ② BitFramingReg = 0x80 (後からStartSendをセット) * この順序でないとWS1850SがFIFO内容を正しく送信しない * ================================================================ */ static MFRC_Status mfrc_transceive(uint8_t *tx, uint8_t txLen, uint8_t *rx, uint8_t *rxLen, uint8_t errMask, uint32_t waitMs) { uint8_t i, n, err, irq; mfrc_fifo_flush(); mfrc_write(REG_ComIrqReg, 0x7F); mfrc_write(REG_CommandReg, CMD_Idle); mfrc_write(REG_BitFramingReg, 0x00); for (i = 0; i < txLen; i++) mfrc_write(REG_FIFODataReg, tx[i]); mfrc_write(REG_CommandReg, CMD_Transceive); /* ①コマンド先 */ mfrc_write(REG_BitFramingReg, 0x80); /* ②StartSend後 */ HAL_Delay(waitMs); mfrc_write(REG_BitFramingReg, 0x00); irq = mfrc_read(REG_ComIrqReg); err = mfrc_read(REG_ErrorReg); n = mfrc_read(REG_FIFOLevelReg); DBG_STR(" I=0x"); DBG_HEX8(irq); DBG_STR(" E=0x"); DBG_HEX8(err); DBG_STR(" F="); DBG_HEX8(n); DBG_CRLF(); if (err & errMask) return MFRC_ERROR; if (n == 0) return MFRC_TIMEOUT; if (rx && rxLen) { uint8_t lim = (*rxLen < n) ? *rxLen : n; mfrc_read_burst(REG_FIFODataReg, rx, lim); *rxLen = lim; DBG_STR(" RX["); DBG_HEX8(lim); DBG_STR("]:"); for (i = 0; i < lim; i++) { DBG_STR(" "); DBG_HEX8(rx[i]); } DBG_CRLF(); } return MFRC_OK; } /* ================================================================ * mfrc_calc_crc() : ハードウェアCRC_A計算 * ================================================================ */ static MFRC_Status mfrc_calc_crc(uint8_t *data, uint8_t len, uint8_t *crcLow, uint8_t *crcHigh) { uint8_t i; mfrc_write(REG_CommandReg, CMD_Idle); mfrc_write(REG_ComIrqReg, 0x04); mfrc_fifo_flush(); for (i = 0; i < len; i++) mfrc_write(REG_FIFODataReg, data[i]); mfrc_write(REG_CommandReg, CMD_CalcCRC); HAL_Delay(WAIT_MS_CRC); mfrc_write(REG_CommandReg, CMD_Idle); if (!(mfrc_read(REG_ComIrqReg) & 0x04)) return MFRC_TIMEOUT; *crcLow = mfrc_read(REG_CRCResultRegL); *crcHigh = mfrc_read(REG_CRCResultRegH); return MFRC_OK; } /* ================================================================ * ntag_request() : REQA 7bit送信 (専用実装) * 【重要】送信シーケンスの正しい順序: * ① CommandReg = CMD_Transceive * ② BitFramingReg = 0x87 (StartSend=bit7 + TxLastBits=7) * 送信後 BitFramingReg を必ず 0x00 にリセットする * * NTAG215のATQA正常値: 44 00 * ================================================================ */ static MFRC_Status ntag_request(void) { uint8_t cmd = PICC_REQA; uint8_t rx[2]; uint8_t n, err; mfrc_fifo_flush(); mfrc_write(REG_ComIrqReg, 0x7F); mfrc_write(REG_CommandReg, CMD_Idle); mfrc_write(REG_BitFramingReg, 0x00); mfrc_write(REG_FIFODataReg, cmd); mfrc_write(REG_CommandReg, CMD_Transceive); /* ①コマンド先 */ mfrc_write(REG_BitFramingReg, 0x87); /* ②StartSend+7bit後 */ HAL_Delay(WAIT_MS_REQA); mfrc_write(REG_BitFramingReg, 0x00); /* 必ずリセット */ err = mfrc_read(REG_ErrorReg); n = mfrc_read(REG_FIFOLevelReg); if (err & ERR_MASK_ANTICOLL) return MFRC_ERROR; if (n == 0) return MFRC_TIMEOUT; /* ATQAを読み捨て (カード存在確認のみ) */ mfrc_read_burst(REG_FIFODataReg, rx, (n > 2) ? 2 : n); return MFRC_OK; } /* ================================================================ * ntag_select_7byte() * ISO14443A Cascade Level 1+2 でNTAG215の7バイトUIDを取得 * * Cascade Level 1: * AntiColl (93 20) → rx=[CT(0x88) uid0 uid1 uid2 BCC] * Select (93 70 CT uid0 uid1 uid2 BCC CRC_L CRC_H) → SAK=0x04 * * Cascade Level 2: * AntiColl (95 20) → rx=[uid3 uid4 uid5 uid6 BCC] * Select (95 70 uid3 uid4 uid5 uid6 BCC CRC_L CRC_H) → SAK=0x00 * ================================================================ */ static MFRC_Status ntag_select_7byte(uint8_t *uid7) { uint8_t rx[5]; uint8_t rxLen; uint8_t tx[9]; uint8_t bcc; uint8_t crcL, crcH; MFRC_Status st; /* ---- Cascade Level 1 ---- */ mfrc_clear_bits(REG_CollReg, 0x80); /* ValuesAfterColl クリア */ /* CL1 AntiColl */ DBG_STR("CL1AC"); tx[0] = PICC_SEL_CL1; tx[1] = 0x20; rxLen = sizeof(rx); st = mfrc_transceive(tx, 2, rx, &rxLen, ERR_MASK_ANTICOLL, WAIT_MS_ANTICOLL); if (st != MFRC_OK || rxLen < 5 || rx[0] != PICC_CT) return MFRC_ERROR; bcc = rx[0] ^ rx[1] ^ rx[2] ^ rx[3]; /* BCC再計算 */ /* CL1 Select */ DBG_STR("CL1SEL"); tx[0] = PICC_SEL_CL1; tx[1] = 0x70; tx[2] = rx[0]; tx[3] = rx[1]; tx[4] = rx[2]; tx[5] = rx[3]; tx[6] = bcc; if (mfrc_calc_crc(tx, 7, &crcL, &crcH) != MFRC_OK) return MFRC_ERROR; tx[7] = crcL; tx[8] = crcH; rxLen = 3; st = mfrc_transceive(tx, 9, rx, &rxLen, ERR_MASK_STRICT, WAIT_MS_SELECT); if (st != MFRC_OK) return MFRC_ERROR; /* SAK=0x04 → Level2へ続く */ uid7[0] = tx[3]; uid7[1] = tx[4]; uid7[2] = tx[5]; /* ---- Cascade Level 2 ---- */ mfrc_clear_bits(REG_CollReg, 0x80); /* CL2 AntiColl */ DBG_STR("CL2AC"); tx[0] = PICC_SEL_CL2; tx[1] = 0x20; rxLen = sizeof(rx); st = mfrc_transceive(tx, 2, rx, &rxLen, ERR_MASK_ANTICOLL, WAIT_MS_ANTICOLL); if (st != MFRC_OK || rxLen < 5) return MFRC_ERROR; bcc = rx[0] ^ rx[1] ^ rx[2] ^ rx[3]; /* BCC再計算 */ /* CL2 Select */ DBG_STR("CL2SEL"); tx[0] = PICC_SEL_CL2; tx[1] = 0x70; tx[2] = rx[0]; tx[3] = rx[1]; tx[4] = rx[2]; tx[5] = rx[3]; tx[6] = bcc; if (mfrc_calc_crc(tx, 7, &crcL, &crcH) != MFRC_OK) return MFRC_ERROR; tx[7] = crcL; tx[8] = crcH; rxLen = 3; st = mfrc_transceive(tx, 9, rx, &rxLen, ERR_MASK_STRICT, WAIT_MS_SELECT); if (st != MFRC_OK) return MFRC_ERROR; /* SAK=0x00 → 選択完了 */ uid7[3] = tx[2]; uid7[4] = tx[3]; uid7[5] = tx[4]; uid7[6] = tx[5]; return MFRC_OK; } /* ================================================================ * ntag_read_page() : NTAGページ読み取り (4ページ=16byte返却) * ================================================================ */ static MFRC_Status ntag_read_page(uint8_t page, uint8_t *data16) { uint8_t tx[4]; uint8_t buf[18]; /* [v10修正] 16データ + CRC2バイト = 18バイト受信 */ uint8_t rxLen = sizeof(buf); uint8_t crcL, crcH; uint8_t i; MFRC_Status st; tx[0] = NTAG_READ; tx[1] = page; if (mfrc_calc_crc(tx, 2, &crcL, &crcH) != MFRC_OK) return MFRC_ERROR; tx[2] = crcL; tx[3] = crcH; st = mfrc_transceive(tx, 4, buf, &rxLen, ERR_MASK_STRICT, WAIT_MS_READ); if (st != MFRC_OK) return st; /* 先頭16バイトのみ呼び出し側へコピー (末尾2バイトはCRC) */ for (i = 0; i < 16 && i < rxLen; i++) data16[i] = buf[i]; return MFRC_OK; } /* ================================================================ * extract_3digit() : raw[len]からASCII数字3連続を検索 * ================================================================ */ static uint8_t extract_3digit(uint8_t *raw, uint8_t len, char *out3) { uint8_t i; for (i = 0; i + 2 < len; i++) { if (raw[i] >= '0' && raw[i] <= '9' && raw[i+1] >= '0' && raw[i+1] <= '9' && raw[i+2] >= '0' && raw[i+2] <= '9') { out3[0] = (char)raw[i]; out3[1] = (char)raw[i+1]; out3[2] = (char)raw[i+2]; out3[3] = '\0'; return 1; } } return 0; } /* ================================================================ * rfid_task() : メインループから定期呼び出し * * NTAG215 メモリマップ: * page0-1: UID(7byte) * page3 : Capability Container (0xE1 0x10 0x6D 0x00) * page4〜: NDEF TLV (03 [len] D1 01 ...) ← テキストデータ * ================================================================ */ static void rfid_task(void) { uint8_t uid[7], page_data[16], raw[48]; char digit3[4]; uint8_t p, b; /* カード検出 */ if (ntag_request() != MFRC_OK) return; /* 7バイトUID取得 (Cascade Level 1+2) */ if (ntag_select_7byte(uid) != MFRC_OK) { uart_str("SEL NG\r\n"); return; } /* UID表示 */ uart_str("UID:"); for (b = 0; b < 7; b++) { uart_hex8(uid[b]); uart_str(" "); } uart_crlf(); /* page4〜6 読み取り (3ページ × 16byte = 48byte) */ for (p = 0; p < 3; p++) { if (ntag_read_page(4 + p, page_data) != MFRC_OK) { uart_str("RD NG\r\n"); goto halt_card; } for (b = 0; b < 16; b++) raw[p * 16 + b] = page_data[b]; } /* 3桁数字抽出・表示 */ if (extract_3digit(raw, 48, digit3)) { uart_str(">>>"); uart_str(digit3); uart_str("<<<\r\n"); } else { uart_str("NO 3DIGIT\r\n"); } halt_card: /* HALT送信 */ { uint8_t halt_tx[4], dummy[2]; uint8_t dLen = 2, crcL, crcH; halt_tx[0] = PICC_HLTA; halt_tx[1] = 0x00; mfrc_calc_crc(halt_tx, 2, &crcL, &crcH); halt_tx[2] = crcL; halt_tx[3] = crcH; mfrc_transceive(halt_tx, 4, dummy, &dLen, ERR_MASK_ANTICOLL, WAIT_MS_SELECT); } HAL_Delay(1000); } /* USER CODE END 0 */ /* ================================================================ * main() * ================================================================ */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ MX_GPIO_Init(); MX_I2C1_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ HAL_Delay(500); uart_str("RFID v10\r\n"); mfrc_init(); uart_str("Ready\r\n"); /* USER CODE END 2 */ /* USER CODE BEGIN WHILE */ while (1) { rfid_task(); HAL_Delay(300); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */

コードはClaude Sonnet4.6に書いてもらいました。

メニューの「Project」 → 「 Build All」 を押しコンパイル&ビルドします。
キャプションを入力できます

問題がなければ、下部のコンソール画面に「0errors, 0warnings」と表示されます。
キャプションを入力できます
※前回の画像です。

配線、NTAG読み取り動作(デバッグ)

マイコン等の配線

CN3
 pin1(VDD検知) - pin4(VDD)
 pin2(SWCLK) - pin19(PA14 SWCLK)
 pin3(GND) - pin5(VSS)
 pin4(SWDIO) - pin18(PA13 SWDIO)
 pin5(NRST) - pin6(NRST)
 TX - pin8(PA1 RX)
 RX - pin7(PA0 TX)

CN6
 3V3(3.3V給電) - pin4(VDD)

M5StackRFID2 - マイコン(STM32C011F4P6)

GND - pin5(VSS)
 SDA - pin1(PB7)
 SCL - pin2(PC14)

M5StackRFID2 - STLINK
 5V - 5V(5V給電)

分かりづらいのですが、参考図が下記です。
TXとRXは入れ替えて接続します。(デバッガTX - マイコンRX)
キャプションを入力できます
キャプションを入力できます

NTAG読み取り動作(デバッグ)

NucleoボードとパソコンをUSBで接続します。(接続中の場合はそのまま)
「Run」 → 「Debug」をクリック

デバッグ画面に切り替えを提案されるため、
「Switch」を押して了承する。
▶」Resumeボタンをクリック

NTAGをRFID2にかざします。
キャプションを入力できます

ターミナルに下図表示がでます。
 NTAG:001をかざすと001
 NTAG:002をかざすと002
キャプションを入力できます
次回以降はUSBを刺すだけで同様の動作となります。(マイコンにプログラムが書き込まれるため)

※IDEを再起動すると、ターミナルが切断されます。
 その場合は下記を実施してください。
  Open a Terminal
  Serial Terminalを選択
  デバッガのCOM番号を選択
  OK

参考リンク

M5StackRFID2 Arduinoコード

M5STACK, Unit RFID / RFID2 Arduino 使用チュートリアル
https://docs.m5stack.com/ja/arduino/projects/unit/unit_rfid
GitHub, m5stack/M5Unified
https://github.com/m5stack/M5Unified
GitHub, MFRC522-I2C-Library/MFRC522_I2C.h
https://github.com/arozcan/MFRC522-I2C-Library/blob/master/MFRC522_I2C.h

1
  • OY さんが 前の水曜日の19:10 に 編集 をしました。 (メッセージ: 初版)
ログインしてコメントを投稿する