Luatos Air700 改变BL0942串口波特率

LuatOs 改变模块串口波特率思路参照

luatos 改变AIR530串口波特率

BL0942默认串口波特率可以通过SCLK_BPS引脚接3.3V电源设置到9600bps

但如果调整到38400bps需要修改0x19寄存器

bl0942 v1.06版的特殊寄存器说明,注意早期版本特殊寄存器说明存在错误

完整代码

main.lua

Lua 复制代码
-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "EMQX_Plug"
VERSION = "1.0.1"

--[[
本demo需要mqtt库, 大部分能联网的设备都具有这个库
mqtt也是内置库, 无需require
]]

-- sys库是标配
_G.sys = require("sys")
--[[特别注意, 使用mqtt库需要下列语句]]
_G.sysplus = require("sysplus")

-- 自动低功耗, 轻休眠模式
-- Air780E支持uart唤醒和网络数据下发唤醒, 但需要断开USB,或者pm.power(pm.USB, false) 但这样也看不到日志了
-- pm.request(pm.LIGHT)

-- 串口ID,串口读缓冲区
local bl0942 = require "bl0942"
local UART_ID1, UART1receQueue = 1, {}
local uartimeout, UART1recvReady = 25,"UART_RECV_ID1"


local RD_SPECIAL_REGISTER_FLAG=0
local RD_DATA_REGISTER_FLAG=0 
local BAUD_CHANGED_FLAG=0                                                                                                                   
local LED   = gpio.setup(31, 1, gpio.PULLUP)
local RELAY = gpio.setup(9, 1, gpio.PULLUP)
LED(1)


if wdt then
    --添加硬狗防止程序卡死,在支持的设备上启用这个功能
    wdt.init(9000)--初始化watchdog设置为9s
    sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
end



-- 最常用115200 8N1
local result1 = uart.setup(
    UART_ID1,--串口id
    9600,--波特率
    8,--数据位
    1--停止位
)
print(_VERSION)

sys.taskInit(function()
        log.info("初始化","bl0942软件复位")
        BL0942_Write(UART_ID1,bl0942.SOFT_RESET,0x5A,0x5A,0x5A)
        sys.wait(100) 
        -- 以下代码设置防潜动阈值寄存器,保证电度数据不会累计噪声形成负值
        BL0942_Write(UART_ID1,bl0942.USR_WRPROT,0x55,0x00,0x00)
        BL0942_Write(UART_ID1,bl0942.WA_CREEP,0x33,0x00,0x00)
                
       --以下改变串口波特率
        BL0942_Write(UART_ID1,bl0942.MODE,0x87,0x03,0x00)
        BSP_FLAG=1
        uart.write(UART_ID1,"     ")--触发uart.on的sent事件--触发uart.on的sent事件
        print("已改变GPS串口波特率")
end)


  uart.on(UART_ID1, "sent", function(uid)
      if BSP_FLAG==1 then 
          -- uart.close(UART_ID1)--此代码注释掉也能实现波特率更改
          result1 = uart.setup(
                   UART_ID1,--串口id
                   38400,--波特率
                   8,--数据位
                   1--停止位
            )
         print("已改变Air700 UART1串口波特率")    
         BL0942_Write(UART_ID1,bl0942.USR_WRPROT,0xff,0x00,0x00)
        sys.publish("38400")
        BSP_FLAG=0
        BAUD_CHANGED_FLAG=1
    end  
end)    

sys.subscribe("38400",function()
     uart.on(UART_ID1, "receive", function(uid, length)
       local s
       while true do--保证读完不能丢包
         s = uart.read(uid, length)
         if #s == 0 then break end
           table.insert(UART1receQueue, s)
         end
      sys.timerStart(sys.publish, uartimeout, UART1recvReady)
    end)
end) 

sys.subscribe(UART1recvReady, function()
       
    if (RD_SPECIAL_REGISTER_FLAG==1) then 
        local m={}
        local strRe = table.concat(UART1receQueue)
        if (#strRe)>4 then --可能会有全电参数数据包的23个字节混入,必须剔除
            return         --读单个寄存器一般返回3个字节
        end 
        -- log.info("特殊寄存器",#strRe)
        UART1receQueue = {}
        RD_SPECIAL_REGISTER_FLAG=0
        m[1]=string.byte(strRe,1)
        m[2]=string.byte(strRe,2)
        m[3]=string.byte(strRe,3)
        -- print(m[1],m[2],m[3])
        local m_temp  =  string.char(m[1],m[2],m[3])
        local mode=string.unpack("i3", m_temp)
        print(string.format("MODE=%d",mode))
  end

  if (RD_DATA_REGISTER_FLAG==1) then
    local v,c,e={},{},{}
    local vol,cur,engerywat
    -- local w,f={},{}
    -- local freq,engery
    local strDA = table.concat(UART1receQueue)
    if (#strDA)<23 then --避免解析读寄存器数据
        return 
    end 
    UART1receQueue = {}
    RD_DATA_REGISTER_FLAG=0
    
    c[1]=string.byte(strDA,2)
    c[2]=string.byte(strDA,3)
    c[3]=string.byte(strDA,4)

    v[1]=string.byte(strDA,5)
    v[2]=string.byte(strDA,6)
    v[3]=string.byte(strDA,7)

    e[1]=string.byte(strDA,14)
    e[2]=string.byte(strDA,15)
    e[3]=string.byte(strDA,16)
    
    local cur_temp  =  string.char(c[1],c[2],c[3])
    local vol_temp  =  string.char(v[1],v[2],v[3])  
    local ene_temp  =  string.char(e[1],e[2],e[3])
    -- local wat_temp  =  string.char(w[1],w[2],w[3]) 
    -- local freq_temp =  string.char(f[1],f[2],f[3]) 
    
    local cur   = string.unpack("i3", cur_temp)
    local vol   = string.unpack("i3", vol_temp)
    local energy= string.unpack("i3", ene_temp)
    -- print(string.format("energy=%d",energy))
    -- local wat   = string.unpack("i3", wat_temp)
    -- local freq  = string.unpack("i3",freq_temp)

     pub_vol=(vol*V_CONSTANT)/V_DENO
     pub_cur=(cur*VREF/I_DENO)*1000  
     pub_energy=(energy*E_PER_PLUSE)
        
     print(string.format("电流=%.1fmA 电压=%.1fV 电度=%0.2f度 ",pub_cur,pub_vol,pub_energy))
    -- print(string.format("电流=%0.2fA 电压=%.1fV 功率=%0.1fW 电度=%0.2f度 频率=%0.1fHz",Current,Voltage,Energy,Wat,Freq))
   end      
end)
local cnt = 0

sys.timerLoopStart(function()
      if BAUD_CHANGED_FLAG==1 then
        uartimeout=25
        BL0942_Read(UART_ID1,0xAA)--V_RMS  0xAA bl0942.V_RMS 读取全电参数数据包
        RD_DATA_REGISTER_FLAG=1 
        RD_SPECIAL_REGISTER_FLAG=0
    end 
end, 1000)

sys.timerLoopStart(function()
    if BAUD_CHANGED_FLAG==1 then
      uartimeout=5
      BL0942_Read(UART_ID1,bl0942.MODE) --读0x19用户模式选择寄存器
      RD_SPECIAL_REGISTER_FLAG=1
      RD_DATA_REGISTER_FLAG=0
    end 
end, 2400)

-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

bl0942.lua

Lua 复制代码
local sys = require "sys"

 VREF      = 1.218
 V_DENO    =1842052.2
 V_CONSTANT=121.8
 I_DENO    =504863.7      --305978*(3.3*1000)/2000
 DOUBLE_FS  =1000000.0
 POWER_COEFF=148.3524     --1.218*1.218*20*5
 P_DENO     =145317.645   --3537*(3.3*1000/2000)*0.0249*1000
 E_PER_PLUSE=0.000118942

 bl0942= setmetatable({}, {
    __index = {
        WRITE_HEAD   =      0xA8,  
        READ_HEAD    =      0x58,
        I_WAVE       =      0x01,    --电流波形寄存器,有符号
        V_WAVE       =      0x02,    --电压波形寄存器,有符号
        I_RMS        =      0x03,    --电流有效值寄存器,无符号
        V_RMS        =      0x04,    --电压有效值寄存器,无符号
        I_FAST_RMS   =      0x05,    --电流快速有效值寄存器,无符号
        WATT         =      0x06,    --有功功率寄存器,有符号
        CF_CNT       =      0x07,    --有功电能脉冲计数寄存器,无符号
        FREQ         =      0x08,    --线电压频率寄存器
        STATUS       =      0x09,    --状态寄存器

        ---------用户操作寄存器(读写)--------------------
        I_RMSOS       =      0x12,    --电流有效值小信号校正寄存器
        WA_CREEP      =      0x14,    --有功功率防潜寄存器
        I_FAST_RMS_TH =      0x15,    --电流快速有效值阈值寄存器
        I_FAST_RMS_CYC=      0x16,    --电流快速有效值刷新周期寄存器
        FREQ_CYC      =      0x17,    --线电压频率刷新周期寄存器
        OT_FUNX       =      0x18,   --输出配置寄存器
        MODE          =      0x19,    --用户模式选择寄存器
        GAIN_CR       =      0x1A,    --电流通道增益控制寄存器
        SOFT_RESET    =      0x1C,    --写入 0x5A5A5A 时,用户区寄存器复位
        USR_WRPROT    =      0x1D    --用户写保护设置寄存器。
                                     --写入0x55后,用户操作寄存器可以写入;
                                     --写入其他值,用户操作寄存器区域不可写入
    },
    __newindex = function() end
})


local function Check_ConStat(HEAD,address,data0_7,data8_15,data16_23)
     local sum=HEAD+address+data0_7+data8_15+data16_23
     local sumAnd=bit.band(sum,0xff)
     local checksum=bit.bnot(sumAnd)--这个输出位数大于2个字节,其十进制数位-207 十六进制:FFFF FFFF FFFF FF31
     local result=bit.band(checksum,0xff)--保证校验位1个字节,去除前面的14个FF
    return result;
end


function BL0942_Read(ID,address)
     uart.write(ID,string.char(bl0942.READ_HEAD,address))
end
--
 function BL0942_Write(ID,address,data0_7,data8_15,data16_23)
     local checksum=Check_ConStat(bl0942.WRITE_HEAD,address,data0_7,data8_15,data16_23) 
     uart.write(ID,string.char(bl0942.WRITE_HEAD,address,data0_7,data8_15,data16_23,checksum))
end

return bl0942

在修改特殊寄存器前,必须0X1D寄存器写入0x55。

代码实现了读取全电数据包和0x19寄存器的功能,特别注意在分别解析串口返回的数据时,对数据的长度进行了判断,对不符合解析长度的数据包进行了丢弃,保证了数据的准确性。

另外2个读取循环在延时时间上相互错开,避免遇到同时读取。

MODE=903 即0011 1000 0111,也就是[9:8]=11,波特率调整到了38400bps。

注意:交替循环读会出现电流显示600多ma的数据,目前我还没有解决,如果单独读取全电数据包能正常准确解析数据。读特殊寄存器一般用于调试阶段。

相关推荐
scan16 小时前
单片机串口接收状态机STM32
stm32·单片机·串口·51·串口接收
Qingniu016 小时前
【青牛科技】应用方案 | RTC实时时钟芯片D8563和D1302
科技·单片机·嵌入式硬件·实时音视频·安防·工控·储能
深圳市青牛科技实业有限公司8 小时前
【青牛科技】应用方案|D2587A高压大电流DC-DC
人工智能·科技·单片机·嵌入式硬件·机器人·安防监控
Mr.谢尔比9 小时前
电赛入门之软件stm32keil+cubemx
stm32·单片机·嵌入式硬件·mcu·信息与通信·信号处理
LightningJie9 小时前
STM32中ARR(自动重装寄存器)为什么要减1
stm32·单片机·嵌入式硬件
西瓜籽@10 小时前
STM32——毕设基于单片机的多功能节能窗控制系统
stm32·单片机·课程设计
远翔调光芯片^1382879887212 小时前
远翔升压恒流芯片FP7209X与FP7209M什么区别?做以下应用市场摄影补光灯、便携灯、智能家居(调光)市场、太阳能、车灯、洗墙灯、舞台灯必看!
科技·单片机·智能家居·能源
极客小张13 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩
m0_7393128716 小时前
【STM32】项目实战——OV7725/OV2604摄像头颜色识别检测(开源)
stm32·单片机·嵌入式硬件
徐嵌17 小时前
STM32项目---水质水位检测
stm32·单片机·嵌入式硬件