bq25895_test.lua 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. --[[
  2. 通过UART接收上位机命令,进行I2C读写操作,并将结果通过UART返回
  3. 命令格式:
  4. 写操作:uart_down_wr|0xSLAVE_ADDR|0xREG_ADDR|0xVALUE\n
  5. 读操作:uart_down_rd|0xSLAVE_ADDR|0xREG_ADDR|0XNUM\n
  6. 响应格式:
  7. 写操作响应:uart_up_wr|0xRESULT\n (RESULT: 0x01成功, 0x00失败)
  8. 读操作响应:uart_up_rd|0xRESULT|0xVALUE\n (RESULT: 0x01成功, 0x00失败; VALUE: 读取的值)
  9. --]]
  10. -- 定义I2C总线ID和I2C速度
  11. local i2c_id = 1
  12. i2c.setup(i2c_id, i2c.SLOW)
  13. local uart_id = 1 -- 根据实际设备选取不同的uart_id
  14. -- 初始化串口参数
  15. -- uart.setup(
  16. -- uart_id,--串口id
  17. -- 115200,--波特率
  18. -- 8,--数据位
  19. -- 1--停止位
  20. -- )
  21. -- 收取数据会触发回调, 这里的"receive" 是固定值
  22. uart.on(uart_id, "receive", function(id, len)
  23. -- 一次性读取所有串口缓存数据(避免循环冗余)
  24. local data = uart.read(uart_id, len)
  25. if not data or #data == 0 then
  26. log.info("uart", "No data received")
  27. return
  28. end
  29. log.info("uart", "Received raw data:", data)
  30. -- 检查是否包含目标指令关键词
  31. if string.find(data, "uart_down_wr") or string.find(data, "uart_down_rd") then
  32. -- 按换行符分割数据,处理每一行指令
  33. for line in string.gmatch(data, "([^\n]+)") do
  34. log.info("uart", "Processing line:", line)
  35. -- 分割指令各部分(去除首尾空格)
  36. local parts = {}
  37. for part in string.gmatch(line, "[^|]+") do
  38. -- 去除每个部分的首尾空格
  39. local trim_part = string.match(part, "^%s*(.-)%s*$")
  40. table.insert(parts, trim_part)
  41. end
  42. -- 处理写操作:uart_down_wr|0x22|0x0a|0x01
  43. if #parts >= 4 and parts[1] == "uart_down_wr" then
  44. -- 十六进制解析
  45. local slave_addr = tonumber(string.match(parts[2], "0x(%x+)"), 16) or 0
  46. local reg_addr = tonumber(string.match(parts[3], "0x(%x+)"), 16) or 0
  47. local value = tonumber(string.match(parts[4], "0x(%x+)"), 16) or 0
  48. log.info("i2c write", "slave_addr=0x"..string.format("%02X", slave_addr),
  49. "reg_addr=0x"..string.format("%02X", reg_addr),
  50. "value=0x"..string.format("%02X", value))
  51. -- 执行I2C写寄存器操作
  52. local ret = i2c.writeReg(i2c_id, slave_addr, reg_addr, value)
  53. local resp_code = ret and 0x01 or 0x00
  54. -- 返回响应
  55. uart.write(uart_id, string.format("uart_up_wr | 0x%02X\n", resp_code))
  56. -- 处理读操作:uart_down_rd|0x22|0x0a|0XNUM(NUM为读取字节数,支持十进制/十六进制)
  57. elseif #parts >= 4 and parts[1] == "uart_down_rd" then -- 修改:至少4个部分(新增NUM参数)
  58. -- 十六进制解析从机地址、寄存器地址
  59. local slave_addr = tonumber(string.match(parts[2], "0x(%x+)"), 16) or 0
  60. local reg_addr = tonumber(string.match(parts[3], "0x(%x+)"), 16) or 0
  61. -- 解析读取字节数(兼容0x开头十六进制/纯十进制,比如0x01或1都表示1字节)
  62. local read_len = nil
  63. local num_str = parts[4]
  64. -- 先尝试按十六进制解析(0x开头),否则按十进制解析
  65. if string.find(num_str, "^0x") then
  66. read_len = tonumber(string.match(num_str, "0x(%x+)"), 16) or 1 -- 默认1字节
  67. else
  68. read_len = tonumber(num_str) or 1 -- 默认1字节
  69. end
  70. log.info("i2c read", "slave_addr=0x"..string.format("%02X", slave_addr),
  71. "reg_addr=0x"..string.format("%02X", reg_addr),
  72. "read_len="..read_len)
  73. -- 执行I2C读寄存器操作(传入读取字节数参数)
  74. local ret_val = i2c.readReg(i2c_id, slave_addr, reg_addr, read_len) or 0x00
  75. -- 修复响应逻辑:ret_val可能是多字节,需统一转为十六进制字符串(兼容单/多字节)
  76. local resp_code = (ret_val ~= nil and ret_val ~= 0x00) and 0x01 or 0x00
  77. local ret_hex = ""
  78. -- 处理多字节读取结果(按字节转为十六进制,用空格分隔)
  79. if type(ret_val) == "string" then -- 多数I2C库多字节返回字符串
  80. for i = 1, #ret_val do
  81. ret_hex = ret_hex .. string.format("0x%02X ", string.byte(ret_val, i))
  82. end
  83. ret_hex = string.sub(ret_hex, 1, -2) -- 去掉最后一个空格
  84. else -- 单字节返回数值
  85. ret_hex = string.format("0x%02X", ret_val)
  86. end
  87. -- 返回响应(状态码+读取值)
  88. uart.write(uart_id, string.format("uart_up_rd | 0x%02X | %s\n", resp_code, ret_hex))
  89. end
  90. end
  91. end
  92. end)