• Luatos Air700 改变BL0942串口波特率


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

    luatos 改变AIR530串口波特率

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

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

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

     

     完整代码

    main.lua

    1. -- LuaTools需要PROJECT和VERSION这两个信息
    2. PROJECT = "EMQX_Plug"
    3. VERSION = "1.0.1"
    4. --[[
    5. 本demo需要mqtt库, 大部分能联网的设备都具有这个库
    6. mqtt也是内置库, 无需require
    7. ]]
    8. -- sys库是标配
    9. _G.sys = require("sys")
    10. --[[特别注意, 使用mqtt库需要下列语句]]
    11. _G.sysplus = require("sysplus")
    12. -- 自动低功耗, 轻休眠模式
    13. -- Air780E支持uart唤醒和网络数据下发唤醒, 但需要断开USB,或者pm.power(pm.USB, false) 但这样也看不到日志了
    14. -- pm.request(pm.LIGHT)
    15. -- 串口ID,串口读缓冲区
    16. local bl0942 = require "bl0942"
    17. local UART_ID1, UART1receQueue = 1, {}
    18. local uartimeout, UART1recvReady = 25,"UART_RECV_ID1"
    19. local RD_SPECIAL_REGISTER_FLAG=0
    20. local RD_DATA_REGISTER_FLAG=0
    21. local BAUD_CHANGED_FLAG=0
    22. local LED = gpio.setup(31, 1, gpio.PULLUP)
    23. local RELAY = gpio.setup(9, 1, gpio.PULLUP)
    24. LED(1)
    25. if wdt then
    26. --添加硬狗防止程序卡死,在支持的设备上启用这个功能
    27. wdt.init(9000)--初始化watchdog设置为9s
    28. sys.timerLoopStart(wdt.feed, 3000)--3s喂一次狗
    29. end
    30. -- 最常用115200 8N1
    31. local result1 = uart.setup(
    32. UART_ID1,--串口id
    33. 9600,--波特率
    34. 8,--数据位
    35. 1--停止位
    36. )
    37. print(_VERSION)
    38. sys.taskInit(function()
    39. log.info("初始化","bl0942软件复位")
    40. BL0942_Write(UART_ID1,bl0942.SOFT_RESET,0x5A,0x5A,0x5A)
    41. sys.wait(100)
    42. -- 以下代码设置防潜动阈值寄存器,保证电度数据不会累计噪声形成负值
    43. BL0942_Write(UART_ID1,bl0942.USR_WRPROT,0x55,0x00,0x00)
    44. BL0942_Write(UART_ID1,bl0942.WA_CREEP,0x33,0x00,0x00)
    45. --以下改变串口波特率
    46. BL0942_Write(UART_ID1,bl0942.MODE,0x87,0x03,0x00)
    47. BSP_FLAG=1
    48. uart.write(UART_ID1," ")--触发uart.on的sent事件--触发uart.on的sent事件
    49. print("已改变GPS串口波特率")
    50. end)
    51. uart.on(UART_ID1, "sent", function(uid)
    52. if BSP_FLAG==1 then
    53. -- uart.close(UART_ID1)--此代码注释掉也能实现波特率更改
    54. result1 = uart.setup(
    55. UART_ID1,--串口id
    56. 38400,--波特率
    57. 8,--数据位
    58. 1--停止位
    59. )
    60. print("已改变Air700 UART1串口波特率")
    61. BL0942_Write(UART_ID1,bl0942.USR_WRPROT,0xff,0x00,0x00)
    62. sys.publish("38400")
    63. BSP_FLAG=0
    64. BAUD_CHANGED_FLAG=1
    65. end
    66. end)
    67. sys.subscribe("38400",function()
    68. uart.on(UART_ID1, "receive", function(uid, length)
    69. local s
    70. while true do--保证读完不能丢包
    71. s = uart.read(uid, length)
    72. if #s == 0 then break end
    73. table.insert(UART1receQueue, s)
    74. end
    75. sys.timerStart(sys.publish, uartimeout, UART1recvReady)
    76. end)
    77. end)
    78. sys.subscribe(UART1recvReady, function()
    79. if (RD_SPECIAL_REGISTER_FLAG==1) then
    80. local m={}
    81. local strRe = table.concat(UART1receQueue)
    82. if (#strRe)>4 then --可能会有全电参数数据包的23个字节混入,必须剔除
    83. return --读单个寄存器一般返回3个字节
    84. end
    85. -- log.info("特殊寄存器",#strRe)
    86. UART1receQueue = {}
    87. RD_SPECIAL_REGISTER_FLAG=0
    88. m[1]=string.byte(strRe,1)
    89. m[2]=string.byte(strRe,2)
    90. m[3]=string.byte(strRe,3)
    91. -- print(m[1],m[2],m[3])
    92. local m_temp = string.char(m[1],m[2],m[3])
    93. local mode=string.unpack("i3", m_temp)
    94. print(string.format("MODE=%d",mode))
    95. end
    96. if (RD_DATA_REGISTER_FLAG==1) then
    97. local v,c,e={},{},{}
    98. local vol,cur,engerywat
    99. -- local w,f={},{}
    100. -- local freq,engery
    101. local strDA = table.concat(UART1receQueue)
    102. if (#strDA)<23 then --避免解析读寄存器数据
    103. return
    104. end
    105. UART1receQueue = {}
    106. RD_DATA_REGISTER_FLAG=0
    107. c[1]=string.byte(strDA,2)
    108. c[2]=string.byte(strDA,3)
    109. c[3]=string.byte(strDA,4)
    110. v[1]=string.byte(strDA,5)
    111. v[2]=string.byte(strDA,6)
    112. v[3]=string.byte(strDA,7)
    113. e[1]=string.byte(strDA,14)
    114. e[2]=string.byte(strDA,15)
    115. e[3]=string.byte(strDA,16)
    116. local cur_temp = string.char(c[1],c[2],c[3])
    117. local vol_temp = string.char(v[1],v[2],v[3])
    118. local ene_temp = string.char(e[1],e[2],e[3])
    119. -- local wat_temp = string.char(w[1],w[2],w[3])
    120. -- local freq_temp = string.char(f[1],f[2],f[3])
    121. local cur = string.unpack("i3", cur_temp)
    122. local vol = string.unpack("i3", vol_temp)
    123. local energy= string.unpack("i3", ene_temp)
    124. -- print(string.format("energy=%d",energy))
    125. -- local wat = string.unpack("i3", wat_temp)
    126. -- local freq = string.unpack("i3",freq_temp)
    127. pub_vol=(vol*V_CONSTANT)/V_DENO
    128. pub_cur=(cur*VREF/I_DENO)*1000
    129. pub_energy=(energy*E_PER_PLUSE)
    130. print(string.format("电流=%.1fmA 电压=%.1fV 电度=%0.2f度 ",pub_cur,pub_vol,pub_energy))
    131. -- print(string.format("电流=%0.2fA 电压=%.1fV 功率=%0.1fW 电度=%0.2f度 频率=%0.1fHz",Current,Voltage,Energy,Wat,Freq))
    132. end
    133. end)
    134. local cnt = 0
    135. sys.timerLoopStart(function()
    136. if BAUD_CHANGED_FLAG==1 then
    137. uartimeout=25
    138. BL0942_Read(UART_ID1,0xAA)--V_RMS 0xAA bl0942.V_RMS 读取全电参数数据包
    139. RD_DATA_REGISTER_FLAG=1
    140. RD_SPECIAL_REGISTER_FLAG=0
    141. end
    142. end, 1000)
    143. sys.timerLoopStart(function()
    144. if BAUD_CHANGED_FLAG==1 then
    145. uartimeout=5
    146. BL0942_Read(UART_ID1,bl0942.MODE) --读0x19用户模式选择寄存器
    147. RD_SPECIAL_REGISTER_FLAG=1
    148. RD_DATA_REGISTER_FLAG=0
    149. end
    150. end, 2400)
    151. -- 用户代码已结束---------------------------------------------
    152. -- 结尾总是这一句
    153. sys.run()
    154. -- sys.run()之后后面不要加任何语句!!!!!

     bl0942.lua

    1. local sys = require "sys"
    2. VREF = 1.218
    3. V_DENO =1842052.2
    4. V_CONSTANT=121.8
    5. I_DENO =504863.7 --305978*(3.3*1000)/2000
    6. DOUBLE_FS =1000000.0
    7. POWER_COEFF=148.3524 --1.218*1.218*20*5
    8. P_DENO =145317.645 --3537*(3.3*1000/2000)*0.0249*1000
    9. E_PER_PLUSE=0.000118942
    10. bl0942= setmetatable({}, {
    11. __index = {
    12. WRITE_HEAD = 0xA8,
    13. READ_HEAD = 0x58,
    14. I_WAVE = 0x01, --电流波形寄存器,有符号
    15. V_WAVE = 0x02, --电压波形寄存器,有符号
    16. I_RMS = 0x03, --电流有效值寄存器,无符号
    17. V_RMS = 0x04, --电压有效值寄存器,无符号
    18. I_FAST_RMS = 0x05, --电流快速有效值寄存器,无符号
    19. WATT = 0x06, --有功功率寄存器,有符号
    20. CF_CNT = 0x07, --有功电能脉冲计数寄存器,无符号
    21. FREQ = 0x08, --线电压频率寄存器
    22. STATUS = 0x09, --状态寄存器
    23. ---------用户操作寄存器(读写)--------------------
    24. I_RMSOS = 0x12, --电流有效值小信号校正寄存器
    25. WA_CREEP = 0x14, --有功功率防潜寄存器
    26. I_FAST_RMS_TH = 0x15, --电流快速有效值阈值寄存器
    27. I_FAST_RMS_CYC= 0x16, --电流快速有效值刷新周期寄存器
    28. FREQ_CYC = 0x17, --线电压频率刷新周期寄存器
    29. OT_FUNX = 0x18, --输出配置寄存器
    30. MODE = 0x19, --用户模式选择寄存器
    31. GAIN_CR = 0x1A, --电流通道增益控制寄存器
    32. SOFT_RESET = 0x1C, --写入 0x5A5A5A 时,用户区寄存器复位
    33. USR_WRPROT = 0x1D --用户写保护设置寄存器。
    34. --写入0x55后,用户操作寄存器可以写入;
    35. --写入其他值,用户操作寄存器区域不可写入
    36. },
    37. __newindex = function() end
    38. })
    39. local function Check_ConStat(HEAD,address,data0_7,data8_15,data16_23)
    40. local sum=HEAD+address+data0_7+data8_15+data16_23
    41. local sumAnd=bit.band(sum,0xff)
    42. local checksum=bit.bnot(sumAnd)--这个输出位数大于2个字节,其十进制数位-207 十六进制:FFFF FFFF FFFF FF31
    43. local result=bit.band(checksum,0xff)--保证校验位1个字节,去除前面的14个FF
    44. return result;
    45. end
    46. function BL0942_Read(ID,address)
    47. uart.write(ID,string.char(bl0942.READ_HEAD,address))
    48. end
    49. --
    50. function BL0942_Write(ID,address,data0_7,data8_15,data16_23)
    51. local checksum=Check_ConStat(bl0942.WRITE_HEAD,address,data0_7,data8_15,data16_23)
    52. uart.write(ID,string.char(bl0942.WRITE_HEAD,address,data0_7,data8_15,data16_23,checksum))
    53. end
    54. return bl0942

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

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

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

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

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

  • 相关阅读:
    Windows Powershell命令一条命令安装Python
    Redis篇---第四篇
    Angular: 为Angular SPA程序添加Authorization支持
    超好用的画图工具推荐
    C++ 哈希
    >Web 3.0顶级干货教学:浅析区块链与货币关系
    工作汇报
    URP渲染管线实战教程系列 之URP渲染管线实战解密(一)
    【ML】 第四章 训练模型
    js对象:
  • 原文地址:https://blog.csdn.net/armcsdn/article/details/134269519