| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416 |
- --[[
- @module uart1_adc
- @summary UART1接收MCU发送的ADC数据(对齐新C结构体协议)
- @usage 处理粘包分包、协议解析、CRC校验
- ]]
- local uartid = 1
- local uart_send = {}
- local rdbuf = ""
- -- ===================== 【新版协议常量】 =====================
- local FRAME_HEAD = "\xFE\xFE"
- local FRAME_HEAD_LEN = 12 -- 帧头长度不变
- local CHECK_FIELD_LEN = 2 -- CRC 2字节
- local DEVICE_TYPE = 0x9102
- -- 【关键】ADC 数据长度:500点 uint16 = 1000字节
- local ADC_POINT_CNT = 500
- local ADC_DATA_LEN = ADC_POINT_CNT * 2 -- 1000 字节
- -- 【关键】完整 adc_data_up_t 结构体总长度(必须和C语言一致)
- local ADC_STRUCT_LEN = 2 + 4 + 4 + 4 + 2 + 2 + 2 + 1 + 2 + (ADC_POINT_CNT * 2)
- -- 计算结果 = 1023 字节
- -- ===================== 帧头解析(完全不变) =====================
- local function head_paser(data)
- local netHeader = {pro_ver=0,msg_id=0,msg_type1=0,msg_type2=0,msg_len=0}
- local nextpos = 1
- if #data < FRAME_HEAD_LEN then
- return false,nil
- end
- nextpos, netHeader.head = pack.unpack(data, "<H", nextpos)
- if netHeader.head ~= 0xFEFE then
- log.warn("uart1","帧头错误")
- return false,nil
- end
- nextpos, netHeader.pro_ver = pack.unpack(data, "b", nextpos)
- nextpos, netHeader.msg_id = pack.unpack(data, "<I", nextpos)
- nextpos, netHeader.msg_type1 = pack.unpack(data, "b", nextpos)
- nextpos, netHeader.msg_type2 = pack.unpack(data, "<H", nextpos)
- nextpos, netHeader.msg_len = pack.unpack(data, "<H", nextpos)
- return true, netHeader
- end
- -- ===================== 【核心】完整帧解析 =====================
- local function parse(data)
- if not data or #data == 0 then
- return false, data, nil
- end
- local head_pos = string.find(data, FRAME_HEAD, 1, true)
- if not head_pos then
- return false, data, nil
- end
- local remain_buf = string.sub(data, head_pos)
- if #remain_buf < FRAME_HEAD_LEN then
- return false, remain_buf, nil
- end
- local head_ok, netHeader = head_paser(remain_buf)
- if not head_ok then
- return true, string.sub(remain_buf, 2), nil
- end
- -- 【关键】msg_len = adc结构体长度 + 2字节CRC
- local frame_total_len = FRAME_HEAD_LEN + netHeader.msg_len
- -- 长度校验:必须等于 ADC结构体长度 + 2
- if netHeader.msg_len ~= (ADC_STRUCT_LEN + CHECK_FIELD_LEN) then
- log.error("uart1","长度错误,期望:", ADC_STRUCT_LEN + CHECK_FIELD_LEN, "实际:", netHeader.msg_len)
- return true, string.sub(remain_buf, 2), nil
- end
- if #remain_buf < frame_total_len then
- return false, remain_buf, nil
- end
- local full_frame = string.sub(remain_buf, 1, frame_total_len)
- local unproc_buf = string.sub(remain_buf, frame_total_len + 1)
- return true, unproc_buf, full_frame
- end
- -- ===================== 接收拼接(不变) =====================
- local function proc(data)
- if not data or #data == 0 then return end
- rdbuf = rdbuf .. data
- local result, unproc_buf, full_frame
- unproc_buf = rdbuf
- while true do
- result, unproc_buf, full_frame = parse(unproc_buf)
- if full_frame then
- sys.publish("UART1_ADC_RECIVE", full_frame)
- end
- if not result or not unproc_buf or unproc_buf == "" then
- break
- end
- end
- rdbuf = unproc_buf or ""
- end
- -- ===================== 串口回调(不变) =====================
- local function uart_cb(id, len)
- local data = ""
- repeat
- data = uart.read(id, 1050)
- if not data or #data == 0 then break end
- proc(data)
- --log.info("uart", "receive", id, #data)
- until data == ""
- end
- -- local rxbuff = zbuff.create(1050)
- -- local function uart_cb(id, len)
- -- local rx_len = uart.rx(id, rxbuff) -- 只读一次
- -- if rx_len > 0 then
- -- local data_str = rxbuff:toStr(1, rx_len)
- -- proc(data_str)
- -- log.info("uart", "receive", rx_len)
- -- end
- -- end
- -- 全局偏移量(不变)
- _G.Y_FULL_SCALE = 5
- _G.x_offset = 0
- _G.y_offset = 0
- -- ===================== 【核心:新版结构体数据解析】 =====================
- sys.subscribe("UART1_ADC_RECIVE", function(full_frame)
- if not full_frame or #full_frame == 0 then return end
- local head_ok, netHeader = head_paser(full_frame)
- if not head_ok then return end
- -- 1. 拆分:帧头 + 结构体数据(info) + CRC
- local total_frame_len = FRAME_HEAD_LEN + netHeader.msg_len
- local struct_data = string.sub(full_frame, FRAME_HEAD_LEN + 1, FRAME_HEAD_LEN + ADC_STRUCT_LEN)
- local recv_crc_str = string.sub(full_frame, total_frame_len - 1, total_frame_len)
- local crc_calc_data = string.sub(full_frame, 1, total_frame_len - CHECK_FIELD_LEN)
- -- 2. CRC 校验
- local _, recv_crc = pack.unpack(recv_crc_str, "<H", 1)
- local calc_crc = crypto.crc16("IBM", crc_calc_data)
- --log.info("uart1","CRC校验:接收=",string.format("%04X",recv_crc),"计算=",string.format("%04X",calc_crc))
- if recv_crc ~= calc_crc then
- log.error("uart1","CRC校验失败")
- return
- end
- --log.info("uart1","CRC校验成功")
- -- ===================== 【关键】解析 adc_data_up_t 结构体 =====================
- local pos = 1
- local adc_struct = {}
- _, adc_struct.device_type = pack.unpack(struct_data, "<H", pos) pos = pos + 2
- _, adc_struct.device_sn = pack.unpack(struct_data, "<I", pos) pos = pos + 4
- _, adc_struct.reserve = pack.unpack(struct_data, "<I", pos) pos = pos + 4
- _, adc_struct.frequency = pack.unpack(struct_data, "<I", pos) pos = pos + 4
- _, adc_struct.max_vol = pack.unpack(struct_data, "<H", pos) pos = pos + 2
- _, adc_struct.min_vol = pack.unpack(struct_data, "<H", pos) pos = pos + 2
- _, adc_struct.x_offset = pack.unpack(struct_data, "<H", pos) pos = pos + 2
- _, adc_struct.compress_type = pack.unpack(struct_data, "b", pos) pos = pos + 1
- _, adc_struct.data_len = pack.unpack(struct_data, "<H", pos) pos = pos + 2
- -- 提取真正的 500 点 ADC 数据
- local adc_raw_data = string.sub(struct_data, pos, pos + ADC_DATA_LEN - 1)
- log.info("uart1","触发位置:", adc_struct.x_offset, "ADC点数:", adc_struct.data_len)
- -- 打印频率、电压最大值和电压最小值
- -- log.info("uart1", "频率: " .. adc_struct.frequency .. " Hz")
- -- log.info("uart1", "电压最大值: " .. adc_struct.max_vol .. " mV")
- -- log.info("uart1", "电压最小值: " .. adc_struct.min_vol .. " mV")
-
- -- 发布事件,通知UI更新
- sys.publish("ADC_DATA_UPDATE", {
- frequency = adc_struct.frequency,
- max_vol = adc_struct.max_vol,
- min_vol = adc_struct.min_vol,
- x_offset = adc_struct.x_offset
- })
- -- ===================== 500点波形转换 =====================
- local wave_data = {}
- local raw_wave = {}
- pos = 1
- for i = 1, ADC_POINT_CNT do
- local adc_val = 0
- if pos <= #adc_raw_data then
- _, adc_val = pack.unpack(adc_raw_data, "<H", pos)
- pos = pos + 2
- end
- -- 电压计算(和你原来一样)
- local V_adc = adc_val * 3.3 / 4095.0
- -- if V_adc < 0.2 then V_adc = 0.2 end
- -- local V_real = (V_adc - 0.2) * 10.0
- local V_real = V_adc * 5.0
- local display_val = V_real / _G.Y_FULL_SCALE * 100.0
- display_val = math.floor(display_val + 0.5)
- display_val = math.max(0, display_val)
- raw_wave[i] = display_val
- end
- -- 偏移处理
- for i = 1, ADC_POINT_CNT do
- local val = raw_wave[i]
- val = val + _G.y_offset
- val = math.max(0, val)
- table.insert(wave_data, val)
- end
- -- 发布 500 点波形
- sys.publish("ADC_WAVE_DATA", wave_data)
- --log.info("uart1","500点波形解析完成")
- end)
- -- ===================== 串口初始化(不变) =====================
- uart.setup(uartid, 921600,8,1,uart.NONE,uart.LSB)
- uart.on(uartid, "receive", uart_cb)
- local function uart_send_cb(id)
- log.info("uart", id , "发送完成")
- end
- uart.on(uartid, "sent", uart_send_cb)
- local msg_id = 0
- -- ADC配置参数下发
- function uart_send.send_adc_config(config)
- if not config then
- log.error("uart1", "发送ADC配置失败:参数为空")
- return
- end
-
- log.info("uart1", "发送ADC配置数据:")
- log.info("uart1", "垂直档位: " .. config.vertical_gear .. " mV")
- log.info("uart1", "时间档位: " .. config.time_gear .. " us")
- log.info("uart1", "水平偏移: " .. config.x_offset)
- log.info("uart1", "垂直偏移: " .. config.y_offset)
- log.info("uart1", "触发阈值: " .. config.trigger_threshold .. " mV")
- log.info("uart1", "触发类型: " .. config.trigger_type)
- log.info("uart1", "触发脉宽: " .. config.trigger_width .. " us")
-
-
- local ADC_CONFIG_SIZE = 25
- local MSG_LEN = ADC_CONFIG_SIZE + CHECK_FIELD_LEN
-
- local frame_header = pack.pack("<H", 0xFEFE)
- local proto_ver = pack.pack("b", 0x03)
- local msg_id_pack = pack.pack("<I", msg_id)
- local first_type = pack.pack("b", 0x01)
- local second_type = pack.pack("<H", 0x1001)
- local msg_len_pack = pack.pack("<H", MSG_LEN)
-
- local device_type = pack.pack("<H", DEVICE_TYPE)
- local device_sn = pack.pack("<I", 0x00000001)
- local reserve = pack.pack("<I", 0)
- local vertical_gear = pack.pack("<H", config.vertical_gear)
- local time_gear = pack.pack("<I", config.time_gear)
- local x_offset = pack.pack("b", config.x_offset)
- local y_offset = pack.pack("b", config.y_offset)
- local trigger_threshold = pack.pack("<H", config.trigger_threshold)
- local trigger_type = pack.pack("b", config.trigger_type)
- local trigger_width = pack.pack("<I", config.trigger_width)
-
- local frame_data = frame_header .. proto_ver .. msg_id_pack .. first_type .. second_type .. msg_len_pack ..
- device_type .. device_sn .. reserve ..
- vertical_gear .. time_gear .. x_offset .. y_offset ..
- trigger_threshold .. trigger_type .. trigger_width
-
- local crc = crypto.crc16("IBM", frame_data)
- local crc_pack = pack.pack("<H", crc)
-
- local full_frame = frame_data .. crc_pack
- local hex_str = string.toHex(full_frame, " ")
- log.info("uart1", "完整帧 Hex: ", hex_str)
- log.info("uart1", "完整帧长度: ", #full_frame)
- uart.write(uartid, full_frame, #full_frame)
- log.info("uart1", "发送ADC配置指令成功,消息ID:", msg_id)
-
- msg_id = (msg_id + 1) & 0xFFFFFFFF
- end
- -- ADC动态操作下发
- function uart_send.send_adc_operate(config)
- if not config then
- log.error("uart1", "发送ADC动态操作失败:参数为空")
- return
- end
- log.info("uart1", "发送ADC动态操作数据:")
- log.info("uart1", "触发方式: " .. config.trigger_method)
- log.info("uart1", "运行控制: " .. config.run_control)
- log.info("uart1", "复位: " .. config.reset)
-
- local ADC_CONFIG_SIZE = 13
- local MSG_LEN = ADC_CONFIG_SIZE + CHECK_FIELD_LEN
-
- local frame_header = pack.pack("<H", 0xFEFE)
- local proto_ver = pack.pack("b", 0x03)
- local msg_id_pack = pack.pack("<I", msg_id)
- local first_type = pack.pack("b", 0x01)
- local second_type = pack.pack("<H", 0x1002)
- local msg_len_pack = pack.pack("<H", MSG_LEN)
- local device_type = pack.pack("<H", DEVICE_TYPE)
- local device_sn = pack.pack("<I", 0x00000001)
- local reserve = pack.pack("<I", 0)
- local reset = pack.pack("b", config.reset)
- local run_control = pack.pack("b", config.run_control)
- local trigger_method = pack.pack("b", config.trigger_method)
-
- local frame_data = frame_header .. proto_ver .. msg_id_pack .. first_type .. second_type .. msg_len_pack ..
- device_type .. device_sn .. reserve ..
- reset .. run_control .. trigger_method
-
- local crc = crypto.crc16("IBM", frame_data)
- local crc_pack = pack.pack("<H", crc)
-
- local full_frame = frame_data .. crc_pack
- local hex_str = string.toHex(full_frame, " ")
- log.info("uart1", "完整帧 Hex: ", hex_str)
- log.info("uart1", "完整帧长度: ", #full_frame)
- uart.write(uartid, full_frame, #full_frame)
- log.info("uart1", "发送ADC配置指令成功,消息ID:", msg_id)
-
- msg_id = (msg_id + 1) & 0xFFFFFFFF
- end
- -- DAC配置参数下发
- function uart_send.send_dac_config(config)
- if not config then
- log.error("uart1", "发送DAC配置失败:参数为空")
- return
- end
- log.info("uart1", "发送DAC配置数据:")
- log.info("uart1", "运行控制: " .. config.run_control)
- log.info("uart1", "波形类型: " .. config.wave_type)
- log.info("uart1", "最大电压: " .. config.max_vol)
- log.info("uart1", "最小电压: " .. config.min_vol)
- log.info("uart1", "频率: " .. config.frequency)
- log.info("uart1", "占空比: " .. config.duty_cycle)
-
- local DAC_CONFIG_SIZE = 21
- local MSG_LEN = DAC_CONFIG_SIZE + CHECK_FIELD_LEN
-
- local frame_header = pack.pack("<H", 0xFEFE)
- local proto_ver = pack.pack("b", 0x03)
- local msg_id_pack = pack.pack("<I", msg_id)
- local first_type = pack.pack("b", 0x01)
- local second_type = pack.pack("<H", 0x1003)
- local msg_len_pack = pack.pack("<H", MSG_LEN)
- local device_type = pack.pack("<H", DEVICE_TYPE)
- local device_sn = pack.pack("<I", 0x00000001)
- local reserve = pack.pack("<I", 0)
- local run_control = pack.pack("b", config.run_control)
- local wave_type = pack.pack("b", config.wave_type)
- local max_vol = pack.pack("<H", config.max_vol)
- local min_vol = pack.pack("<H", config.min_vol)
- local frequency = pack.pack("<I", config.frequency)
- local duty_cycle = pack.pack("<b", config.duty_cycle)
-
- local frame_data = frame_header .. proto_ver .. msg_id_pack .. first_type .. second_type .. msg_len_pack ..
- device_type .. device_sn .. reserve ..
- run_control .. wave_type .. max_vol .. min_vol .. frequency .. duty_cycle
-
- local crc = crypto.crc16("IBM", frame_data)
- local crc_pack = pack.pack("<H", crc)
-
- local full_frame = frame_data .. crc_pack
- local hex_str = string.toHex(full_frame, " ")
- log.info("uart1", "完整帧 Hex: ", hex_str)
- log.info("uart1", "完整帧长度: ", #full_frame)
- uart.write(uartid, full_frame, #full_frame)
- log.info("uart1", "发送DAC配置指令成功,消息ID:", msg_id)
-
- msg_id = (msg_id + 1) & 0xFFFFFFFF
- end
- -- 上电初始化发送函数(发送20个 55 AA 组合)
- local function send_init_data()
- -- 构建20个 55 AA 的数据
- local init_data = ""
- for i = 1, 20 do
- init_data = init_data .. "\x55\xAA"
- end
-
- -- 发送数据
- uart.write(uartid, init_data, #init_data)
- log.info("uart1", "上电初始化数据发送完成,长度:", #init_data)
-
- -- 打印发送的数据(十六进制)
- local hex_str = string.toHex(init_data, " ")
- log.info("uart1", "初始化数据 Hex:", hex_str)
- end
- -- 一次性定时器:上电后1秒发送初始化数据
- sys.timerStart(send_init_data, 1000)
- return uart_send
|