AirRC522_1000.lua 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. --[[
  2. @module AirRC522_1000
  3. @summary AirRC522_1000测试功能模块
  4. @version 1.0
  5. @date 2025.07.23
  6. @author 马亚丹
  7. @usage
  8. 本demo演示的功能为:使用Air8000核心板通过SPIl实现对RC522的操作,演示读写数据等操作。
  9. 以 Air8000核心板为例, 接线如下:
  10. Air8000 AirRC522_1000
  11. GND(任意) GND
  12. VDD_EXT 3.3V
  13. GPIO12/SPI1_CS SDA
  14. SPI1_SCLK SCK
  15. SPI1_MOSI MOSI
  16. SPI1_MISO MISO
  17. GPIO16(任意空闲的io) RST
  18. 核心逻辑:
  19. 1. 初始化并启用spi,如果初始化失败,退出程序
  20. 2. 初始化RC522模块,如果初始化失败,退出程序
  21. 3. 循环检测卡片。
  22. 4. 向卡片指定块号写入数据,并读取数据验证一致性
  23. 5. 读取卡片所有数据
  24. ]]
  25. rc522 = require "rc522"
  26. -- 硬件配置参数(Air8000适配)
  27. local RC522_CONFIG = {
  28. spi_id = 1, -- SPI通道
  29. cs_pin = 12, -- 片选引脚
  30. rst_pin = 16, -- 复位引脚
  31. spi_baud = 2 * 1000 * 1000, -- SPI波特率
  32. }
  33. -- 全局变量(模块内可见)
  34. local spi_dev = nil -- SPI设备对象
  35. -- 1. 初始化SPI接口
  36. local function init_spi()
  37. log.info("RC522", "初始化SPI接口")
  38. -- 配置SPI参数:模式0,8位数据,高位在前
  39. spi_dev = spi.setup(
  40. RC522_CONFIG.spi_id,
  41. RC522_CONFIG.cs_pin,
  42. 0, -- 极性0
  43. 0, -- 相位0
  44. 8, -- 数据位
  45. RC522_CONFIG.spi_baud,
  46. spi.MSB, -- 高位优先
  47. spi.master, --主模式
  48. spi.half --半双工
  49. )
  50. if not spi_dev then
  51. log.error("RC522", "SPI初始化失败")
  52. return false
  53. end
  54. log.info("RC522", "SPI初始化成功")
  55. return true
  56. end
  57. -- 2. 初始化RC522模块
  58. local function init_rc522()
  59. log.info("RC522", "初始化RC522传感器")
  60. -- 初始化RC522硬件(SPI ID、CS引脚、RST引脚)
  61. local init_ok = rc522.init(
  62. RC522_CONFIG.spi_id,
  63. RC522_CONFIG.cs_pin,
  64. RC522_CONFIG.rst_pin
  65. )
  66. if not init_ok then
  67. log.error("RC522", "传感器初始化失败")
  68. return false
  69. end
  70. log.info("RC522", "传感器初始化成功")
  71. return true
  72. end
  73. -- 3. 写数据
  74. local function write_ic_card(block, data)
  75. -- 步骤1:验证数据长度
  76. if #data > 16 then
  77. log.error("RC522", "数据过长(最大16字节)")
  78. return false
  79. end
  80. -- 步骤2:写入数据块
  81. local write_ok = rc522.write_datablock(block, data)
  82. if not write_ok then
  83. log.error("RC522", "数据写入失败,块号:", block)
  84. return false
  85. end
  86. log.info("RC522", "数据写入成功,块号:", block, "写入数据是:", string.char(table.unpack(data)):toHex())
  87. return true
  88. end
  89. -- 4. 检测并读取IC卡数据
  90. local function read_ic_card()
  91. -- 检测是否有卡片靠近
  92. local status, array_id = rc522.request(rc522.reqall)
  93. if not status then
  94. log.info("RC522", "未检测到卡片")
  95. return false
  96. end
  97. log.info("RC522", "检测到卡片,类型:", array_id:toHex())
  98. -- 防冲突检测,获取卡片唯一ID
  99. local status, card_uid = rc522.anticoll(array_id)
  100. if not status then
  101. log.error("RC522", "防冲突检测失败")
  102. return false
  103. end
  104. log.info("RC522", "卡片UID:", card_uid:toHex())
  105. -- -- 选择卡片,激活卡片进行后续操作
  106. local select_ok = rc522.select(card_uid)
  107. if not select_ok then
  108. log.error("RC522", "卡片选择失败")
  109. return false
  110. end
  111. -- 写数据测试
  112. local TEST_BLOCK = 9
  113. -- 待写入的数据
  114. local TEST_DATA = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
  115. if write_ic_card(TEST_BLOCK, TEST_DATA) then
  116. -- 读数据验证
  117. local read_ok, read_data = rc522.read_datablock(TEST_BLOCK)
  118. if read_ok and read_data == string.char(table.unpack(TEST_DATA)) then
  119. log.info("RC522", "写入验证成功,数据是:", read_data:toHex())
  120. else
  121. log.warn("RC522", "写入验证失败,实际读取的数据是:", read_data:toHex())
  122. end
  123. end
  124. -- 读取卡片数据块(0-63块)
  125. log.info("RC522", "开始读取卡片数据...")
  126. for block = 0, 63 do
  127. local read_ok, data = rc522.read_datablock(block)
  128. if read_ok and data then
  129. log.info(string.format("块[%d]", block), data:toHex())
  130. else
  131. log.warn(string.format("块[%d]读取失败", block))
  132. end
  133. --每读取完一个块等待20ms(时间可按需修改)
  134. sys.wait(20)
  135. end
  136. -- 停止卡片操作
  137. rc522.halt()
  138. return true
  139. end
  140. -- 5. 关闭SPI设备,成功返回0
  141. local function spi_close_func()
  142. log.info("关闭spi", spi.close(RC522_CONFIG.spi_id))
  143. end
  144. -- 6. 主测试任务
  145. local function rc522_main_test()
  146. -- 初始化硬件
  147. if not init_spi() then
  148. spi_close_func()
  149. return
  150. end
  151. if not init_rc522() then
  152. spi_close_func()
  153. return
  154. end
  155. -- 循环检测卡片
  156. log.info("RC522", "开始检测卡片")
  157. while true do
  158. read_ic_card()
  159. -- 循环检测间隔:2s
  160. sys.wait(2000)
  161. end
  162. end
  163. -- 启动主任务
  164. sys.taskInit(rc522_main_test)