feat: initialize mesh role and broadcast online
This commit is contained in:
@@ -61,6 +61,11 @@ _App_Reset:
|
||||
bset 0x5007, #5
|
||||
bset 0x5008, #5
|
||||
bres 0x5009, #5
|
||||
; PB4:蓝牙初始化故障指示灯,低电平点亮;正常流程中输出高电平熄灭。
|
||||
bset 0x5005, #4
|
||||
bset 0x5007, #4
|
||||
bset 0x5008, #4
|
||||
bres 0x5009, #4
|
||||
; PA2/PWRC:低电平进入JDY-28M AT指令窗口,高电平恢复Mesh通信。
|
||||
bres 0x5000, #2
|
||||
bset 0x5002, #2
|
||||
@@ -100,6 +105,24 @@ _App_Reset:
|
||||
mov 0x5235, #0x0C
|
||||
; PWRC拉低后等待约10ms,给JDY-28M预留AT指令窗口建立时间。
|
||||
call _App_Delay10ms
|
||||
; 上电先确认模块是否处于MESH指令模式ROLE2。
|
||||
call _App_QueryRole2
|
||||
ld a, 0x004C
|
||||
jrne _App_RoleReady
|
||||
; 非ROLE2时写入ROLE2,并重新查询;最多再尝试两轮。
|
||||
call _App_SetRole2
|
||||
call _App_Delay10ms
|
||||
call _App_QueryRole2
|
||||
ld a, 0x004C
|
||||
jrne _App_RoleReady
|
||||
call _App_SetRole2
|
||||
call _App_Delay10ms
|
||||
call _App_QueryRole2
|
||||
ld a, 0x004C
|
||||
jrne _App_RoleReady
|
||||
jpf _App_BluetoothInitFault
|
||||
|
||||
_App_RoleReady:
|
||||
call _App_QueryModuleAddress
|
||||
; 查询结束后释放PWRC,模块恢复正常Mesh通信。
|
||||
bset 0x5000, #2
|
||||
@@ -114,17 +137,9 @@ _App_Reset:
|
||||
mov 0x0035, #0x00
|
||||
mov 0x0036, #0x00
|
||||
mov 0x5235, #0x2C
|
||||
; 蓝牙模式、短地址和串口业务状态均初始化完成后,广播一次上线通知。
|
||||
call _App_SendOnlineBroadcast
|
||||
rim
|
||||
; 发送一次固定的0x55,仅用于现场确认TX链路、波特率和串口接线。
|
||||
; 该字节不是业务协议数据,正式联调确认TX正常后可删除这三行。
|
||||
ld a, #0x55
|
||||
ld 0x0020, a
|
||||
_App_StartupTxWait:
|
||||
ld a, 0x5230
|
||||
and a, #0x80
|
||||
jreq _App_StartupTxWait
|
||||
ld a, 0x0020
|
||||
ld 0x5231, a
|
||||
|
||||
_App_MainLoop:
|
||||
; 主循环从环形缓冲区取出字节。UART中断只负责接收和入队,
|
||||
@@ -151,6 +166,203 @@ _App_MainLoop:
|
||||
mov 0x0036, #0x00
|
||||
jra _App_MainLoop
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; 蓝牙初始化故障停机点。
|
||||
; 模块未确认ROLE2时点亮PB4,释放PWRC后停留在此处,不进入Mesh业务。
|
||||
; PB5仍由TIM4驱动,便于区分蓝牙故障和MCU停机。
|
||||
;-------------------------------------------------------------------------------
|
||||
_App_BluetoothInitFault:
|
||||
bset 0x5000, #2
|
||||
bres 0x5005, #4
|
||||
rim
|
||||
_App_BluetoothFaultLoop:
|
||||
jra _App_BluetoothFaultLoop
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; 查询JDY-28M当前模式,只有收到+ROLE=2才将0x004C置1。
|
||||
; 该函数在启动阶段调用,此时UART接收中断尚未开启,因此直接轮询UART。
|
||||
;-------------------------------------------------------------------------------
|
||||
_App_QueryRole2:
|
||||
mov 0x004B, #0x00
|
||||
mov 0x004C, #0x00
|
||||
; 发送AT+ROLE\r\n。
|
||||
mov 0x003E, #0x41
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x54
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x2B
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x52
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x4F
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x4C
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x45
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x0D
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x0A
|
||||
call _App_SendByte
|
||||
ldw x, #0xFFFF
|
||||
_App_RoleWait:
|
||||
ld a, 0x5230
|
||||
and a, #0x20
|
||||
jrne _App_RoleRead
|
||||
decw x
|
||||
jrne _App_RoleWait
|
||||
ret
|
||||
_App_RoleRead:
|
||||
ld a, 0x5231
|
||||
ld 0x003E, a
|
||||
call _App_RoleParseByte
|
||||
tnz 0x004C
|
||||
jrne _App_RoleDone
|
||||
decw x
|
||||
jrne _App_RoleWait
|
||||
_App_RoleDone:
|
||||
ret
|
||||
|
||||
; 逐字节匹配字符串“+ROLE=2”。收到完整字符串后确认ROLE2。
|
||||
_App_RoleParseByte:
|
||||
ld a, 0x003E
|
||||
ld 0x003F, a
|
||||
ld a, 0x004B
|
||||
cp a, #0x00
|
||||
jreq _App_RolePlus
|
||||
cp a, #0x01
|
||||
jreq _App_RoleR
|
||||
cp a, #0x02
|
||||
jreq _App_RoleO
|
||||
cp a, #0x03
|
||||
jreq _App_RoleL
|
||||
cp a, #0x04
|
||||
jreq _App_RoleE
|
||||
cp a, #0x05
|
||||
jreq _App_RoleEqual
|
||||
ld a, 0x003F
|
||||
cp a, #0x32
|
||||
jrne _App_RoleReset
|
||||
mov 0x004C, #0x01
|
||||
ret
|
||||
_App_RolePlus:
|
||||
ld a, 0x003F
|
||||
cp a, #0x2B
|
||||
jreq _App_RoleNext
|
||||
jra _App_RoleReset
|
||||
_App_RoleR:
|
||||
ld a, 0x003F
|
||||
cp a, #0x52
|
||||
jreq _App_RoleNext
|
||||
jra _App_RoleReset
|
||||
_App_RoleO:
|
||||
ld a, 0x003F
|
||||
cp a, #0x4F
|
||||
jreq _App_RoleNext
|
||||
jra _App_RoleReset
|
||||
_App_RoleL:
|
||||
ld a, 0x003F
|
||||
cp a, #0x4C
|
||||
jreq _App_RoleNext
|
||||
jra _App_RoleReset
|
||||
_App_RoleE:
|
||||
ld a, 0x003F
|
||||
cp a, #0x45
|
||||
jreq _App_RoleNext
|
||||
jra _App_RoleReset
|
||||
_App_RoleEqual:
|
||||
ld a, 0x003F
|
||||
cp a, #0x3D
|
||||
jreq _App_RoleNext
|
||||
jra _App_RoleReset
|
||||
_App_RoleNext:
|
||||
inc 0x004B
|
||||
ret
|
||||
_App_RoleReset:
|
||||
mov 0x004B, #0x00
|
||||
ret
|
||||
|
||||
; 发送AT+ROLE2\r\n,将模块切换到MESH指令模式。
|
||||
_App_SetRole2:
|
||||
mov 0x003E, #0x41
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x54
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x2B
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x52
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x4F
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x4C
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x45
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x32
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x0D
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x0A
|
||||
call _App_SendByte
|
||||
ret
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; 发送设备上线广播。
|
||||
;
|
||||
; 业务格式:CMD=07、LEN=00、CRC16_H、CRC16_L。
|
||||
; 外层目标地址固定使用FFFF,表示广播到Mesh网络内的所有设备。
|
||||
; 该函数只在本次上电初始化全部成功后调用一次,用于通知其他设备或主机:
|
||||
; 本设备已经完成ROLE2确认、短地址查询,并进入可通信状态。
|
||||
;
|
||||
; 发送帧格式:
|
||||
; 41 54 2B AA A1 FF FF A0 07 00 CRC_H CRC_L 0D 0A
|
||||
;
|
||||
; 注意:函数不依赖外层接收帧中的源地址,也不把本机地址重复放入业务数据;
|
||||
; 其他设备需要使用JDY-28M接收外层提供的发送方短地址识别本设备。
|
||||
;-------------------------------------------------------------------------------
|
||||
_App_SendOnlineBroadcast:
|
||||
; 准备业务区并计算CMD、LEN的CRC16/MODBUS。
|
||||
mov 0x0040, #0x07
|
||||
mov 0x0041, #0x00
|
||||
call _App_CrcBusiness3
|
||||
|
||||
; JDY-28M Mesh发送固定帧头。
|
||||
mov 0x003E, #0x41
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x54
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x2B
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0xAA
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0xA1
|
||||
call _App_SendByte
|
||||
; FFFF表示广播目标地址。
|
||||
mov 0x003E, #0xFF
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0xFF
|
||||
call _App_SendByte
|
||||
; A0表示Mesh数据通信类型。
|
||||
mov 0x003E, #0xA0
|
||||
call _App_SendByte
|
||||
; 发送业务区:07 00 CRC高字节 CRC低字节。
|
||||
mov 0x003E, #0x07
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x00
|
||||
call _App_SendByte
|
||||
ld a, 0x003D
|
||||
ld 0x003E, a
|
||||
call _App_SendByte
|
||||
ld a, 0x003C
|
||||
ld 0x003E, a
|
||||
call _App_SendByte
|
||||
; 保留JDY-28M发送帧尾0D 0A。
|
||||
mov 0x003E, #0x0D
|
||||
call _App_SendByte
|
||||
mov 0x003E, #0x0A
|
||||
call _App_SendByte
|
||||
ret
|
||||
|
||||
;-------------------------------------------------------------------------------
|
||||
; 查询JDY-28M本机Mesh短地址。
|
||||
; 发送AT+MADDR\r\n,解析+MADDR=XXXX。地址保存到0x0046/0x0047,
|
||||
|
||||
@@ -385,14 +385,12 @@ def main() -> None:
|
||||
parser.add_argument("--port", help="直接指定电脑串口;不指定时启动后扫描并选择")
|
||||
parser.add_argument("--baudrate", type=int, default=9600, help="串口波特率,默认9600")
|
||||
parser.add_argument("--timeout", type=float, default=0.2, help="串口读取超时,默认0.2秒")
|
||||
parser.add_argument("--response-timeout", type=float, default=3.0, help="设备应答等待时间,默认10秒")
|
||||
parser.add_argument("--response-timeout", type=float, default=10.0, help="设备应答等待时间,默认10秒")
|
||||
args = parser.parse_args()
|
||||
|
||||
selected_port = args.port or select_serial_port()
|
||||
with serial.Serial(selected_port, args.baudrate, timeout=args.timeout) as port:
|
||||
print(f"已打开串口:{selected_port},波特率:{args.baudrate}")
|
||||
run_menu(port, args.response_timeout)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user