ZhaoSai 2 mesiacov pred
rodič
commit
39e0d9a4bb

+ 3 - 1
.vscode/settings.json

@@ -3,5 +3,7 @@
     "idf.openOcdConfigs": [
         "interface/ftdi/esp32_devkitj_v1.cfg",
         "target/esp32s3.cfg"
-    ]
+    ],
+    "trae.tab.enableRename": false,
+    "trae.tab.enableAutoImport": false
 }

+ 180 - 0
drv_periph/LoRa_Process.lua

@@ -0,0 +1,180 @@
+module(...,package.seeall)
+require "sx126x_reg"
+require "sx126x_driver"
+require "radio"
+local bit = require "bit"
+-- ---------------- 宏定义 ----------------
+local MASTER_ADDR = 0x00
+local MIN_SLAVE_ADDR = 0x01
+local MAX_SLAVE_ADDR = 0x05
+
+local FRAME_HEADER1 = 0x5A
+local FRAME_HEADER2 = 0xA5
+
+local FRAME_TYPE_QUERY = 0x03
+local FRAME_TYPE_DATA  = 0x02
+
+local QUERY_TIMEOUT_MS = 6   --6s
+
+-- CRC16-Modbus (与 C 中保持一致)
+local function Modbus_CRC16(data)
+    local crc = 0xFFFF
+    for i = 1, #data do
+        -- 用bit.bxor替代~,实现按位异或
+        crc = bit.bxor(crc, data:byte(i))
+        for _ = 1, 8 do
+            -- 用bit.band替代&,实现按位与
+            if bit.band(crc, 0x0001) ~= 0 then
+                -- 先右移1位(bit.rshift),再异或0xA001
+                crc = bit.bxor(bit.rshift(crc, 1), 0xA001)
+            else
+                -- 右移1位
+                crc = bit.rshift(crc, 1)
+            end
+        end
+    end
+    return crc
+end
+
+-- ---------------- 帧构造 ----------------
+local function build_query_frame(slave_addr)
+    local buf = string.char(
+        FRAME_HEADER1,
+        FRAME_HEADER2,
+        MASTER_ADDR,
+        slave_addr,
+        FRAME_TYPE_QUERY,
+        0x00, 0x00 -- reserved
+    )
+    local crc = Modbus_CRC16(buf)
+    -- 修复按位运算符:& → bit.band,>> → bit.rshift
+    buf = buf .. string.char(
+        bit.band(crc, 0xFF),  -- 取CRC低8位
+        bit.band(bit.rshift(crc, 8), 0xFF)  -- 取CRC高8位
+    )
+    return buf
+end
+
+-- ---------------- 发送查询 ----------------
+local function send_query_frame(slave_addr)
+    local frame = build_query_frame(slave_addr)
+    local hexStr = sx126x_driver.stringToHex(frame)
+    sx126x_driver.RadioSend(hexStr, string.format("%02X", #hexStr/2), "00")
+
+    log.info("send_query_frame", "addr=0x" .. string.format("%02X", slave_addr))
+end
+
+-- ---------------- 数据帧解析 ----------------
+local function parse_received_frame(hexStr)
+    log.info("parse_received_frame", "hexStr=" .. hexStr)
+    -- local raw = hex_to_string(hexStr)
+    -- local len = #raw
+    -- if len < 9 then return false end
+
+    -- local b = {raw:byte(1, len)}
+    -- if b[1] ~= FRAME_HEADER1 or b[2] ~= FRAME_HEADER2 then
+    --     log.error("parse_received_frame", "帧头不对")
+    --     return false
+    -- end
+
+    -- local src = b[3]
+    -- local dst = b[4]
+    -- local ftype = b[5]
+    -- local count = b[6]
+    -- local datalen = b[7]
+
+    -- local crc_recv = b[len-1] | (b[len] << 8)
+    -- local crc_calc = Modbus_CRC16(raw:sub(1, len-2))
+    -- if crc_recv ~= crc_calc then
+    --     log.error("parse_received_frame", "CRC错误")
+    --     return false
+    -- end
+
+    -- log.info("收到数据帧", string.format("src=0x%02X type=0x%02X count=%d", src, ftype, count))
+
+    -- local offset = 8
+    -- for i = 1, count do
+    --     if offset + 3 > len-2 then break end
+    --     local sid = b[offset]; offset=offset+1
+    --     local dtype = b[offset]; offset=offset+1
+    --     local dlen = b[offset]; offset=offset+1
+
+    --     local data = {}
+    --     for j=1,dlen do
+    --         table.insert(data, b[offset]); offset=offset+1
+    --     end
+
+    --     if dtype == 0x01 and dlen==2 then
+    --         local t = (data[1]<<8)|data[2]
+    --         log.info("温度", t/100 .. "℃")
+    --     elseif dtype == 0x02 and dlen==2 then
+    --         local h = (data[1]<<8)|data[2]
+    --         log.info("湿度", h/100 .. "%")
+    --     elseif dtype == 0x04 and dlen==1 then
+    --         log.info("烟雾浓度", data[1])
+    --     else
+    --         log.info("未知传感器", dtype, dlen)
+    --     end
+    -- end
+    -- return true
+end
+
+-- ---------------- 主循环 ----------------
+local function master_query_loop()
+    for addr = MIN_SLAVE_ADDR, MAX_SLAVE_ADDR do
+        log.info("[host]", string.format("查询从机 0x%02X...", addr))
+        send_query_frame(addr)
+        -- RadioRx() -- 开始接收
+
+        local start = os.time()  -- 标准 API,返回毫秒数
+        local response_received = false
+
+        while (os.time() - start) < QUERY_TIMEOUT_MS do
+            -- LoRa 中断回调里会触发数据读取
+            sys.wait(200) -- 轮询等待
+            -- if last_rx_hex ~= nil then
+            --     if parse_received_frame(last_rx_hex) then
+            --         response_received = true
+            --     end
+            --     last_rx_hex = nil
+            --     break
+            -- end
+        end
+
+        if not response_received then
+            log.info("[host]", string.format("从机 0x%02X 未响应", addr))
+        end
+        sys.wait(300) -- 查询间隔
+    end
+end
+
+-- ---------------- LoRa回调 ----------------
+last_rx_hex = nil
+sys.subscribe("LORA_CALL_BACK", function()
+    sx126x_driver.RadioClearIrqStatus()
+
+    local ret = sx126x_driver.SX126xReadCommand(sx126x_reg.RadioCommands.RADIO_GET_RXBUFFERSTATUS, 3)
+    local payloadLength = tonumber(ret:sub(3,4),16)
+    local hexStr = sx126x_driver.SX126xReadBuffer("00", payloadLength)
+    last_rx_hex = hexStr -- 缓存给主循环
+end)
+
+
+
+
+sys.taskInit(function()
+    sys.wait(5000)
+    log.info("master_query_loop", "查询开始")
+    radio.RadioInit()
+    radio.RadioStandby()
+    sx126x_driver.RadioSetTxConfig(sx126x_reg.RadioModems_t.MODEM_LORA,"22",0,1,7,"01","0c","00","01","00","00","00",3000)
+    sx126x_driver.RadioSetChannel(433000000)
+    log.info("master_query_loop111", "查询开始")
+    sys.wait(2000)
+    sx126x_driver.RadioRx(0)
+    while true do
+        -- master_query_loop()
+        sys.wait(1000)
+        log.info("master_query_loop", "查询完成")
+    end
+end)

+ 19 - 18
drv_periph/radio.lua

@@ -20,22 +20,23 @@ function RadioStandby()
 end
 
 
-sys.taskInit(function()
-    sys.wait(5000)
-    RadioInit()
-    RadioStandby()
-    sx126x_driver.RadioSetTxConfig(sx126x_reg.RadioModems_t.MODEM_LORA,"16",0,1,7,"01","0c","00","01","00","00","00",3000)
-    sx126x_driver.RadioSetChannel(433000000) 
-    sys.wait(2000)
-    sx126x_driver.RadioRx(0)
-    while true do
-        RadioStandby()
-        -- sx126x_driver.sentString("hello,My_name_is_XuXinyi\n")
-        log.info("Radio", "测试接收数据中。。。")
-        sx126x_driver.RadioRx(0)
-        sys.wait(4000)
-        -- sx126x_driver.RadioRx(0)
-    end
-end)
-
+-- sys.taskInit(function()
+--     sys.wait(5000)
+--     RadioInit()
+--     RadioStandby()
+--     sx126x_driver.RadioSetTxConfig(sx126x_reg.RadioModems_t.MODEM_LORA,"16",0,1,7,"01","0c","00","01","00","00","00",3000)
+--     sx126x_driver.RadioSetChannel(433000000) 
+--     sys.wait(2000)
+--     sx126x_driver.RadioRx(0)
+--     while true do
+--         -- RadioStandby()
+--         local string111  =  "12345678910111213141516171819202122232425262728!\n"
+--         sx126x_driver.sentString(string111)
+--         log.info("Radio", "测试接收数据中。。。")
+--         -- sx126x_driver.RadioRx(0)
+--         -- sx126x_driver.SX126xWakeup()
+--         sys.wait(1000)
+--         -- sx126x_driver.RadioRx(0)
+--     end
+-- end)
 

+ 79 - 21
drv_periph/sx126x_driver.lua

@@ -79,6 +79,7 @@ function gpio4IntFnc(msg)
     --上升沿中断
     if msg==cpu.INT_GPIO_POSEDGE then
         sys.publish("LORA_CALL_BACK")
+        -- log.info("我是中断")
     --下降沿中断
     else
     end
@@ -90,6 +91,8 @@ getGpio4Fnc = pins.setup(pio.P0_4,gpio4IntFnc)
 OperatingMode = sx126x_reg.RadioStandbyModes_t.STDBY_RC
 
 
+SX126xBusyGPIO = pins.setup(pio.P0_26, nil)  -- 第二个参数为nil表示输入模式
+
 function stringToHex(str)
     local hex = {}
     for i = 1, #str do
@@ -117,10 +120,21 @@ function SX126xReset()
     SX126xResetGPIO(1)
     sys.wait(10) 
 end
+-- 等待SX126x模块的忙信号(高电平表示忙)
+-- 当忙信号为低电平时退出循环
+function SX126xWaitOnBusy()
+    -- 循环检查BUSY引脚电平,高电平表示忙则继续等待
+    while SX126xBusyGPIO() == 1 do
+        -- 可添加短暂延迟避免CPU空转(根据实际需求调整)
+        sys.wait(1)  -- 等待1毫秒
+    end
+end
 
 function SX126xWakeup()
     local command = sx126x_reg.RadioCommands.RADIO_GET_STATUS .. "00"
-    local ret = Drv_spi.drv_spi_read_write_byte(command)
+    local ret = Drv_spi.drv_spi_read_write_byte(command,1)
+    sys.wait(1)
+
     log.info("SX126xWakeup",ret)
 end
 
@@ -523,50 +537,94 @@ end
 
 -- end 
 
+-- 十六进制字符串转原始字符串的函数
+local function hex_to_string(hex_str)
+    if type(hex_str) ~= "string" then
+        return ""
+    end
+    local str = ""
+    for i = 1, #hex_str, 2 do
+        local hex_byte = hex_str:sub(i, i+1)
+        local char = string.char(tonumber(hex_byte, 16))
+        str = str .. char
+    end
+    return str
+end
+
+
+
 function SX126xReadBuffer(offset,size)
     local command = sx126x_reg.RadioCommands.RADIO_READ_BUFFER .. offset .. "00"
-    -- Drv_spi.drv_spi_read_write_byte(sx126x_reg.RadioCommands.RADIO_READ_BUFFER)
 
     for i = 1, size do
         command = command .. "00"
     end
-    -- log.info("offset",offset)
-    -- log.info("SX126xReadBuffer",ret)
-    -- log.info("SX126xReadBuffer",command)
-    local ret = Drv_spi.drv_spi_read_write_byte(command,8)
+    local ret = Drv_spi.drv_spi_read_write_byte(command,size)
     log.info("SX126xReadBuffer",ret)
+    -- 测试示例
+    -- local hex_str = "617368696E696E67"  -- "ashining"的十六进制表示
+    local original_str = hex_to_string(ret)
+    
+    -- print("转换后的字符串: " .. original_str)  -- 输出: ashining
+    log.info("原始字符串: " .. original_str)
 end
 
 
 sys.subscribe("LORA_CALL_BACK", function()
+    -- log.info("我是携程")
     RadioClearIrqStatus()
-    RadioRx()
     log.info("清除中断")
+    SX126xSetStandby(sx126x_reg.RadioStandbyModes_t.STDBY_RC)
+    RadioRx()
     local ret = SX126xReadCommand( sx126x_reg.RadioCommands.RADIO_GET_RXBUFFERSTATUS, 3 )
     log.info("LORA_CALL_BACK",ret)
     -- 从第1个字符截取到第2个字符,得到"A4"
-    local rxStartBufferPointer = ret:sub(1, 2)
+    -- local rxStartBufferPointer = ret:sub(1, 2)
 
     -- 从第3个字符截取到第4个字符,得到"08"
     local payloadLength = ret:sub(3, 4)
 
     local num1 = tonumber(payloadLength, 16)  -- 第二个参数 16 表示按十六进制解析
-    local nmu2 = tonumber("FF", 16)
-
-    -- print(string.format("0x%02X", nmu2))  -- 输出 0x08(十六进制格式化显示)
-
-    if num1 >= nmu2 then
-        -- print(string.format("0x%02X", nmu1))  -- 输出 0x08(十六进制格式化显示)
-        return 1
+    -- local nmu2 = tonumber("FF", 16)
+
+    -- if num1 >= nmu2 then
+    --     return 1
+    -- end
+    -- log.info("payloadLength",num1)
+    -- 如果有数据需要读取
+    if num1 > 0 then
+        local fullData = ""
+        local currentOffset = 0
+        log.info("接收到的数据长度num1",num1)
+        
+        -- 循环读取所有数据,每次读取1字节(可根据需要调整每次读取的字节数)
+        while currentOffset < num1 do
+            -- 转换当前偏移量为两位十六进制字符串
+            local offsetHex = string.format("%02X", currentOffset)
+            
+            -- 读取1字节数据
+            local data = SX126xReadBuffer(offsetHex, 1)
+            if data then
+                fullData = fullData .. data
+            else
+                log.error("读取缓冲区失败,偏移量: " .. offsetHex)
+                break
+            end
+            
+            currentOffset = currentOffset + 1
+        end
+        
+        -- 转换为原始字符串并打印
+        if fullData ~= "" then
+            local original_str = hex_to_string(fullData)
+            log.info("完整接收数据: " .. fullData)
+            log.info("转换后的字符串: " .. original_str)
+        end
     end
 
-    log.info("payloadLength: "..payloadLength)
-    log.info("payloadLength: "..rxStartBufferPointer)
-    SX126xReadBuffer("00",8)
 
-    -- print(part1)  -- 输出 "A4"
-    -- print(part2)  -- 输出 "08"
-    -- SX126xReadRegister("0702")
+    
+    
 end)
 
 -- sys.taskInit(function ()

+ 6 - 0
drv_periph/sx126x_reg.lua

@@ -21,6 +21,12 @@ RadioStandbyModes_t = {
     STDBY_XOSC = "01",
 }
 
+-- 正确写法:添加等号(=),定义为表
+RadioRegulatorMode_t = {
+    USE_LDO = "00",  -- 使用LDO模式
+    USE_DCDC = "01"  -- 使用DCDC模式(推荐)
+}
+
 RadioModems_t = {
     MODEM_FSK = 0,
     MODEM_LORA = 1,

+ 2 - 2
main.lua

@@ -65,8 +65,8 @@ errDump.request("udp://dev_msg1.openluat.com:12425", nil, true)
 --update.request()
 
 -- require "Drv_spi"
-require "radio"
-
+-- require "radio"
+require "LoRa_Process"
 
 --启动系统框架
 sys.init(0, 0)