| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- --[[
- 通过UART接收上位机命令,进行I2C读写操作,并将结果通过UART返回
- 命令格式:
- 写操作:uart_down_wr|0xSLAVE_ADDR|0xREG_ADDR|0xVALUE\n
- 读操作:uart_down_rd|0xSLAVE_ADDR|0xREG_ADDR|0XNUM\n
- 响应格式:
- 写操作响应:uart_up_wr|0xRESULT\n (RESULT: 0x01成功, 0x00失败)
- 读操作响应:uart_up_rd|0xRESULT|0xVALUE\n (RESULT: 0x01成功, 0x00失败; VALUE: 读取的值)
- --]]
- -- 定义I2C总线ID和I2C速度
- local i2c_id = 1
- i2c.setup(i2c_id, i2c.SLOW)
- local uart_id = 1 -- 根据实际设备选取不同的uart_id
- -- 初始化串口参数
- -- uart.setup(
- -- uart_id,--串口id
- -- 115200,--波特率
- -- 8,--数据位
- -- 1--停止位
- -- )
- -- 收取数据会触发回调, 这里的"receive" 是固定值
- uart.on(uart_id, "receive", function(id, len)
- -- 一次性读取所有串口缓存数据(避免循环冗余)
- local data = uart.read(uart_id, len)
- if not data or #data == 0 then
- log.info("uart", "No data received")
- return
- end
- log.info("uart", "Received raw data:", data)
- -- 检查是否包含目标指令关键词
- if string.find(data, "uart_down_wr") or string.find(data, "uart_down_rd") then
- -- 按换行符分割数据,处理每一行指令
- for line in string.gmatch(data, "([^\n]+)") do
- log.info("uart", "Processing line:", line)
- -- 分割指令各部分(去除首尾空格)
- local parts = {}
- for part in string.gmatch(line, "[^|]+") do
- -- 去除每个部分的首尾空格
- local trim_part = string.match(part, "^%s*(.-)%s*$")
- table.insert(parts, trim_part)
- end
- -- 处理写操作:uart_down_wr|0x22|0x0a|0x01
- if #parts >= 4 and parts[1] == "uart_down_wr" then
- -- 十六进制解析
- local slave_addr = tonumber(string.match(parts[2], "0x(%x+)"), 16) or 0
- local reg_addr = tonumber(string.match(parts[3], "0x(%x+)"), 16) or 0
- local value = tonumber(string.match(parts[4], "0x(%x+)"), 16) or 0
- log.info("i2c write", "slave_addr=0x"..string.format("%02X", slave_addr),
- "reg_addr=0x"..string.format("%02X", reg_addr),
- "value=0x"..string.format("%02X", value))
- -- 执行I2C写寄存器操作
- local ret = i2c.writeReg(i2c_id, slave_addr, reg_addr, value)
- local resp_code = ret and 0x01 or 0x00
- -- 返回响应
- uart.write(uart_id, string.format("uart_up_wr | 0x%02X\n", resp_code))
- -- 处理读操作:uart_down_rd|0x22|0x0a|0XNUM(NUM为读取字节数,支持十进制/十六进制)
- elseif #parts >= 4 and parts[1] == "uart_down_rd" then -- 修改:至少4个部分(新增NUM参数)
- -- 十六进制解析从机地址、寄存器地址
- local slave_addr = tonumber(string.match(parts[2], "0x(%x+)"), 16) or 0
- local reg_addr = tonumber(string.match(parts[3], "0x(%x+)"), 16) or 0
- -- 解析读取字节数(兼容0x开头十六进制/纯十进制,比如0x01或1都表示1字节)
- local read_len = nil
- local num_str = parts[4]
- -- 先尝试按十六进制解析(0x开头),否则按十进制解析
- if string.find(num_str, "^0x") then
- read_len = tonumber(string.match(num_str, "0x(%x+)"), 16) or 1 -- 默认1字节
- else
- read_len = tonumber(num_str) or 1 -- 默认1字节
- end
- log.info("i2c read", "slave_addr=0x"..string.format("%02X", slave_addr),
- "reg_addr=0x"..string.format("%02X", reg_addr),
- "read_len="..read_len)
- -- 执行I2C读寄存器操作(传入读取字节数参数)
- local ret_val = i2c.readReg(i2c_id, slave_addr, reg_addr, read_len) or 0x00
- -- 修复响应逻辑:ret_val可能是多字节,需统一转为十六进制字符串(兼容单/多字节)
- local resp_code = (ret_val ~= nil and ret_val ~= 0x00) and 0x01 or 0x00
- local ret_hex = ""
- -- 处理多字节读取结果(按字节转为十六进制,用空格分隔)
- if type(ret_val) == "string" then -- 多数I2C库多字节返回字符串
- for i = 1, #ret_val do
- ret_hex = ret_hex .. string.format("0x%02X ", string.byte(ret_val, i))
- end
- ret_hex = string.sub(ret_hex, 1, -2) -- 去掉最后一个空格
- else -- 单字节返回数值
- ret_hex = string.format("0x%02X", ret_val)
- end
- -- 返回响应(状态码+读取值)
- uart.write(uart_id, string.format("uart_up_rd | 0x%02X | %s\n", resp_code, ret_hex))
- end
- end
- end
- end)
|