Compare commits

...

10 Commits

18 changed files with 2979 additions and 277 deletions

View File

@ -142,5 +142,5 @@ void uart_send(uint8_t port, uint16_t len, const uint8_t *data)
} }
while (!(uart->SR.TBEM)); // wait tx finish while (!(uart->SR.TBEM)); // wait tx finish
//while (uart->SR.BUSY); // wait idle state //while (uart->SR.BUSY); // wait idle state /*BUG修复概率性死锁修复方法注释改行 zsxfly 20240615*/
} }

View File

@ -0,0 +1,383 @@
import serial
import serial.tools.list_ports
import struct
import sys
import time
import os
import fnmatch
def crc16(data):
crc = 0xFFFF
for byte in data:
crc ^= byte
for _ in range(8):
if (crc & 0x0001) != 0:
crc >>= 1
crc ^= 0xA001
else:
crc >>= 1
return crc
def create_frame(index, data):
crc = crc16(struct.pack('>H', index) + data)
frame = struct.pack('>H', index) + data + struct.pack('>H', crc)
return frame
def list_serial_ports():
ports = serial.tools.list_ports.comports()
return [port.device for port in ports]
def list_bin_files(directory):
bin_files = []
for dirpath, dirnames, filenames in os.walk(directory):
for filename in fnmatch.filter(filenames, '*.bin'):
# 使用 os.path.relpath 将路径转换为相对路径
relative_path = os.path.relpath(os.path.join(dirpath, filename), start=os.getcwd())
bin_files.append(relative_path)
return bin_files
# def list_bin_files(directory):
# bin_files = []
# for dirpath, dirnames, filenames in os.walk(directory):
# for filename in fnmatch.filter(filenames, '*.bin'):
# bin_files.append(os.path.join(dirpath, filename))
# return bin_files
def select_option(options, prompt):
for index, option in enumerate(options):
print(f"{index + 1}: {option}")
selected_index = int(input(prompt)) - 1
if selected_index < 0 or selected_index >= len(options):
print("无效的选择。")
sys.exit(1)
return options[selected_index]
def main():
# 列出可用串口
serial_ports = list_serial_ports()
if not serial_ports:
print("没有找到可用的串口。")
sys.exit(1)
print("可用串口:")
selected_port = select_option(serial_ports, "请选择串口序号: ")
# 列出当前目录及子目录下所有的bin文件
bin_files = list_bin_files(os.path.dirname(os.path.abspath(__file__)))
if not bin_files:
print("没有找到任何 .bin 文件。")
sys.exit(1)
print("找到以下 .bin 文件:")
selected_file = select_option(bin_files, "请选择文件序号: ")
baudrate = 9600 # 这里可以根据需要设置波特率
init_delay = 0.04 # 这里也可以根据需要设置延迟
COM_serial = serial.Serial(selected_port, baudrate, timeout=0)
with open(selected_file, 'rb') as f:
file_data = f.read()
time.sleep(2) # 等待串口稳定
# 发送初始化帧
chunk = file_data[8:11]
chunk = chunk.ljust(16, b'\x00')
init_frame = create_frame(0xFF01, chunk)
count = 0
ACK_OK = False
while True:
print(f"Sent start frame: {init_frame.hex().upper()}")
COM_serial.write(init_frame)
time_count = 0
while True:
response = COM_serial.read(2)
if len(response) == 2:
error_code = int.from_bytes(response, byteorder='big')
if 0xFF01 == error_code:
ACK_OK = True
print("Initialization response received: 0xFF01")
break
elif 0x5501 == error_code:
print("Firmware partition verification fails. Please check whether the selected firmware is correct.")
sys.exit(1)
elif 0x5502 <= error_code <= 0x5514:
print(f"Received error code: {error_code:04X}. Stopping file transmission.")
sys.exit(1)
time.sleep(0.001)
time_count += 1
if time_count > 1000:
count += 1
print("Initialization response not received. Retrying...")
break
if ACK_OK:
break
if count >= 3:
sys.exit(1)
index = 0
frame_size = 16
num_frames = (len(file_data) + frame_size - 1) // frame_size
# 发送数据帧
for i in range(num_frames):
start = i * frame_size
end = start + frame_size
chunk = file_data[start:end]
if len(chunk) < frame_size:
chunk = chunk.ljust(frame_size, b'\x00')
frame = create_frame(index, chunk)
COM_serial.write(frame)
if (index % 16 == 0): # 每16个数据帧delay一下
time.sleep(0.02)
# 尝试接收响应和错误码
time_count = 0
while True:
response = COM_serial.read(2)
if len(response) == 2:
error_code = int.from_bytes(response, byteorder='big')
if 0x5501 <= error_code <= 0x5514:
print(f"Received error code: {error_code:04X}. Stopping file transmission.")
sys.exit(1)
time.sleep(0.001)
time_count += 1
if time_count > (1000 * init_delay):
break
frame_crc = struct.pack('>H', crc16(struct.pack('>H', index) + chunk))
print(f"IDX:{struct.pack('>H', index).hex().upper()}|DATA:{chunk.hex().upper()}|CRC:{frame_crc.hex().upper()}")
index += 1
# 发送尾帧
end_frame_index = index - 1
end_frame_index_bytes = struct.pack('>H', end_frame_index)
end_frame_index_inverted = struct.pack('>H', ~end_frame_index & 0xFFFF)
end_frame_data = end_frame_index_bytes + end_frame_index_inverted + b'\x00' * 12
end_frame = create_frame(0xFF02, end_frame_data)
print(f"Sent end frame: {end_frame.hex().upper()}")
COM_serial.write(end_frame)
# 尝试接收尾帧响应和错误码
time_count = 0
while True:
response = COM_serial.read(2)
if len(response) == 2:
error_code = int.from_bytes(response, byteorder='big')
if 0xFF02 == error_code:
print("OTA update successfully.")
break
elif 0x5501 <= error_code <= 0x5514:
print(f"OTA update failed: error code:{error_code:04X}")
sys.exit(1)
time.sleep(0.001)
time_count += 1
if time_count > 1500:
print("OTA update failed: timeout...")
break
if __name__ == "__main__":
main()
# import serial
# import struct
# import sys
# import time
# def crc16(data):
# crc = 0xFFFF
# for byte in data:
# crc ^= byte
# for _ in range(8):
# if (crc & 0x0001) != 0:
# crc >>= 1
# crc ^= 0xA001
# else:
# crc >>= 1
# return crc
# def create_frame(index, data):
# crc = crc16(struct.pack('>H', index) + data)
# frame = struct.pack('>H', index) + data + struct.pack('>H', crc)
# return frame
# def save_frame_to_file(frame, index):
# with open('frames.txt', 'a') as f:
# f.write(f"Frame {index}: {frame.hex().upper()}\n")
# def main():
# if len(sys.argv) != 5:
# print("Usage: python serial_sender.py <port> <baudrate> <file> <float_delay>")
# sys.exit(1)
# port = sys.argv[1]
# baudrate = int(sys.argv[2])
# file_path = sys.argv[3]
# init_delay = float(sys.argv[4])
# COM_serial = serial.Serial(port, baudrate, timeout=0)
# with open(file_path, 'rb') as f:
# file_data = f.read()
# time.sleep(2) #等待串口稳定
# # 发送初始化帧
# chunk = file_data[8:11]
# chunk = chunk.ljust(16, b'\x00')
# init_frame = create_frame(0xFF01, chunk)
# # init_frame = create_frame(0xFF01, b'\x00' * 16)
# # response = COM_serial.read(2)
# # print(f"Received response: {response.hex().upper()}")
# count =0
# ACK_OK = False
# while True:
# print(f"Sent satrt frame: {init_frame.hex().upper()}")
# COM_serial.write(init_frame)
# time_count = 0
# while True:
# response = COM_serial.read(2)
# error_code = int.from_bytes(response, byteorder='big')
# if 0xFF01 == error_code:
# ACK_OK = True
# print("Initialization response received: 0xFF01")
# break
# elif 0x5501 == error_code:
# print("Firmware partition verification fails. Please check whether the selected firmware is correct.")
# sys.exit(1)
# # break
# elif 0x5502 <= error_code <= 0x5514:
# print(f"Received error code: {error_code:04X}. Stopping file transmission.")
# # sys.exit(1)
# break
# else:
# time.sleep(0.001)
# time_count += 1
# if time_count > 1000:
# count += 1
# print("Initialization response not received. Retrying...")
# break
# if ACK_OK:
# break
# if count >= 3:
# sys.exit(1)
# # save_frame_to_file(init_frame, 0)
# index = 0
# frame_size = 16
# num_frames = (len(file_data) + frame_size - 1) // frame_size
# # 发送数据帧
# for i in range(num_frames):
# start = i * frame_size
# end = start + frame_size
# chunk = file_data[start:end]
# if len(chunk) < frame_size:
# chunk = chunk.ljust(frame_size, b'\x00')
# frame = create_frame(index, chunk) # 发送数据帧
# COM_serial.write(frame)
# if (index % 16 == 0): # 每16个数据帧delay一下
# # print("delay...")
# time.sleep(0.02)
# # 尝试接收响应和错误码
# time_count = 0
# while True:
# response = COM_serial.read(2)
# error_code = int.from_bytes(response, byteorder='big')
# if 0x5501 <= error_code <= 0x5514:
# print(f"Received error code: {error_code:04X}. Stopping file transmission.")
# sys.exit(1)
# else:
# time.sleep(0.001)
# time_count += 1
# if time_count > (1000 * init_delay):
# # print("timeout...")
# break
# # response = COM_serial.read(2)
# # if response:
# # error_code = int.from_bytes(response, byteorder='big')
# # if 0x5501 <= error_code <= 0x5514:
# # print(f"Received error code: {error_code:04X}. Stopping file transmission.")
# # sys.exit(1)
# # # save_frame_to_file(frame, index)
# # time.sleep(init_delay)
# frame_crc = struct.pack('>H',crc16(struct.pack('>H', index) + chunk))
# frame_index = struct.pack('>H', index)
# print(f"IDX:{frame_index.hex().upper()}|DATA:{chunk.hex().upper()}|CRC:{frame_crc.hex().upper()}")
# index += 1
# # 发送尾帧
# end_frame_index = index - 1
# end_frame_index_bytes = struct.pack('>H', end_frame_index)
# end_frame_index_inverted = struct.pack('>H', ~end_frame_index & 0xFFFF)
# end_frame_data = end_frame_index_bytes + end_frame_index_inverted + b'\x00' * 12
# end_frame = create_frame(0xFF02, end_frame_data)
# print(f"Sent end frame: {end_frame.hex().upper()}")
# COM_serial.write(end_frame)
# # 尝试接收尾帧响应和错误码
# time_count = 0
# while True:
# response = COM_serial.read(2)
# error_code = int.from_bytes(response, byteorder='big')
# if 0xFF02 == error_code:
# print("OTA update successfully.")
# break
# elif 0x5501 <= error_code <= 0x5514:
# print(f"OTA update failed: error code:{error_code:04X}")
# sys.exit(1)
# else:
# time.sleep(0.001)
# time_count += 1
# if time_count > 1500:
# print("OTA update failed: timeout...")
# break
# # save_frame_to_file(end_frame, index)
# # end_frame_count = 0
# # while True:
# # # if COM_serial.in_waiting > 0: # 检查是否有数据可读
# # response = COM_serial.read(2)
# # if response:
# # print(f"Received response: {response.hex().upper()}")
# # error_code = int.from_bytes(response, byteorder='big')
# # if 0x5501 <= error_code <= 0x5514:
# # print(f"Received error code: {error_code:04X}. Stopping file transmission.")
# # sys.exit(1)
# # elif error_code == 0xFF02:
# # print("OTA update successfully.")
# # break
# # else:
# # end_frame_count +=1
# # if end_frame_count > 10:
# # print("End frame response not received. Stopping file transmission.")
# # sys.exit(1)
# # print("End frame response not received. Retrying...")
# if __name__ == "__main__":
# main()

View File

@ -0,0 +1,134 @@
$Bank_A = '_0x04000'
$Bank_B = '_0x20000'
$Ext_lnp = '.lnp'
$Ext_axf = '.axf'
$Ext_hex = '.hex'
$Ext_bin = '.bin'
$Ext_asm = '.asm'
$Path_lnp = '.\output\'
# user defined
$Path_cmd = 'C:\app\keil_MDK\Keil_v5\ARM\ARMCC\bin'
$env:path+=";$Path_cmd;"
# 获取最新的lnp文件(eg:\projects\bleOTA\mdk\output\bleOTA.lnp)
$full_path = Get-ChildItem -Path $Path_lnp -Recurse -ErrorAction SilentlyContinue -Filter *.lnp | Where-Object { $_.Extension -eq '.lnp' } | Where-Object {$_.LastWriteTime} | Select-Object -last 1 | Select-Object -ExpandProperty FullName
# 以.为分隔符, 分割带路径的文件名(eg:\projects\bleOTA\mdk\output\bleOTA)和后缀名(eg:lnp)
# 去掉.lnp的长度
$full_paht_len = $full_path.length - 4
#$Pname, $Ext = $full_path.Split(".")
$Pname = $full_path.Substring(0, $full_paht_len)
# 带路径不带后缀的名称
# (eg:\projects\bleOTA\mdk\output\bleOTA)
# (eg:\projects\bleOTA\mdk\output\bleOTA_0x20000)
$Bank_A_name = $Pname
$Bank_B_name = $Pname+$Bank_B
# 获取不带路径且不带后缀的lnp文件名
$Bank_A_File_Name = (Get-Item $full_path).BaseName
$Bank_B_File_Name = $Bank_A_File_Name+$Bank_B
# 拼成带路径的原始文件
# (eg:\projects\bleOTA\mdk\output\bleOTA.lnp)
# (eg:\projects\bleOTA\mdk\output\bleOTA.axf)
# (eg:\projects\bleOTA\mdk\output\bleOTA_0x04000.hex)
# (eg:\projects\bleOTA\mdk\output\bleOTA_0x04000.bin)
# (eg:\projects\bleOTA\mdk\output\bleOTA_0x04000.asm)
$Org_lnp = $Bank_A_name+$Ext_lnp
$Org_axf = $Bank_A_name+$Ext_axf
$Org_hex = $Bank_A_name+'_0x04000'+$Ext_hex
$Org_bin = $Bank_A_name+'_0x04000'+$Ext_bin
$Org_asm = $Bank_A_name+'_0x04000'+$Ext_asm
# 拼成带路径的目标文件
# (eg:\projects\bleOTA\mdk\output\bleOTA_0x20000.lnp)
# (eg:\projects\bleOTA\mdk\output\bleOTA_0x20000.axf)
# (eg:\projects\bleOTA\mdk\output\bleOTA_0x20000.hex)
# (eg:\projects\bleOTA\mdk\output\bleOTA_0x20000.bin)
# (eg:\projects\bleOTA\mdk\output\bleOTA_0x20000.asm)
$Obj_lnp = $Bank_B_name+$Ext_lnp
$Obj_axf = $Bank_B_name+$Ext_axf
$Obj_hex = $Bank_B_name+$Ext_hex
$Obj_bin = $Bank_B_name+$Ext_bin
$Obj_asm = $Bank_B_name+$Ext_asm
# 在原始lnp文件基础上替换sct文件, 并保存为目标lnp文件
# (eg:link_xip_ble_0x04000替换为link_xip_ble_0x20000)
(Get-Content $Org_lnp) -Replace $Bank_A, $Bank_B | Set-Content $Obj_lnp
# 替换目标lnp文件中的文件名
# (eg:bleOTA替换为bleOTA_0x20000
(Get-Content $Obj_lnp) -Replace $Bank_A_File_Name, $Bank_B_File_Name | Set-Content $Obj_lnp
Write-Output "**************** Linking High Bank ... ****************"
# 链接生成目标文件(axf, map)
armlink.exe --Via $Obj_lnp
# 删除目标lnp, 防止下次读取时存在多个lnp导致的报错
Remove-Item $Obj_lnp
# 生成hex
fromelf.exe $Org_axf --i32combined --output $Org_hex
fromelf.exe $Obj_axf --i32combined --output $Obj_hex
# 生成bin
fromelf.exe $Org_axf --bin --output $Org_bin
fromelf.exe $Obj_axf --bin --output $Obj_bin
# 生成asm
fromelf.exe $Org_axf --text -a -c --output $Org_asm
fromelf.exe $Obj_axf --text -a -c --output $Obj_asm
# 计算CRC32
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class Win32Api {
[DllImport("ntdll.dll")]
public static extern uint RtlComputeCrc32(uint dwInitial, byte[] pData, int iLen);
}
"@
function Get-CRC32 {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true,ValueFromPipeline = $true)]
[string]$InputFile
)
#Write-host $InputFile
# Read the file as bytes
$fileBytes = [System.IO.File]::ReadAllBytes($InputFile)
# Calculate the CRC32 checksum using the Win32 API
$crc32 = [Win32Api]::RtlComputeCrc32(0, $fileBytes, $fileBytes.Length)
# Convert the CRC32 value to hexadecimal string
$crc32String = $crc32.ToString("X8")
# Display the CRC32 checksum
Write-Output $crc32String
}
$Bank_A = "File : " + $Bank_A_File_Name + '_0x04000' + $Ext_bin
$Bank_B = "File : " + $Bank_B_File_Name + $Ext_bin
$CRC32 = Get-CRC32 $Org_bin
Write-Output "================================="
Write-Output $Bank_A
$CRC32 = "CRC32: " + "0x" +$CRC32
Write-Output $CRC32
Write-Output "================================="
$CRC32 = Get-CRC32 $Obj_bin
Write-Output $Bank_B
$CRC32 = "CRC32: " + "0x" +$CRC32
Write-Output $CRC32
Write-Output "================================="
#pause

View File

@ -0,0 +1,40 @@
#! armcc -E -I ..\src\
#include "cfg.h"
#define SCT_FLASH_BASE (0x18004000)
#define SCT_FLASH_END (0x18020000)
#define SCT_FLASH_LEN (SCT_FLASH_END - SCT_FLASH_BASE)
LR_IROM1 SCT_FLASH_BASE SCT_FLASH_LEN
{
ER_IROM1 SCT_FLASH_BASE SCT_FLASH_LEN
{
*.o (RESET, +First)
*(InRoot$$Sections)
startup*.o (+RO)
.ANY (+RO)
}
RW_IRAM_VECT 0x20003000 EMPTY 152
{
; sram vector
}
RW_IRAM_USER +0
{
*.o(ram_func*)
.ANY (+RW +ZI)
}
RW_IRAM_STACK 0x20008000-0x600 UNINIT 0x600
{
.ANY (STACK)
}
RW_IRAM_RETN 0x20008000 UNINIT 0x2000
{
; retention memory 8KB
; user manual init
*.o(user_retention)
}
}

View File

@ -0,0 +1,40 @@
#! armcc -E -I ..\src\
#include "cfg.h"
#define SCT_FLASH_BASE (0x18020000)
#define SCT_FLASH_END (0x18040000)
#define SCT_FLASH_LEN (SCT_FLASH_END - SCT_FLASH_BASE)
LR_IROM1 SCT_FLASH_BASE SCT_FLASH_LEN
{
ER_IROM1 SCT_FLASH_BASE SCT_FLASH_LEN
{
*.o (RESET, +First)
*(InRoot$$Sections)
startup*.o (+RO)
.ANY (+RO)
}
RW_IRAM_VECT 0x20003000 EMPTY 152
{
; sram vector
}
RW_IRAM_USER +0
{
*.o(ram_func*)
.ANY (+RW +ZI)
}
RW_IRAM_STACK 0x20008000-0x600 UNINIT 0x600
{
.ANY (STACK)
}
RW_IRAM_RETN 0x20008000 UNINIT 0x2000
{
; retention memory 8KB
; user manual init
*.o(user_retention)
}
}

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -22,7 +22,7 @@
</DaveTm> </DaveTm>
<Target> <Target>
<TargetName>uartTest</TargetName> <TargetName>OTA</TargetName>
<ToolsetNumber>0x4</ToolsetNumber> <ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName> <ToolsetName>ARM-ADS</ToolsetName>
<TargetOption> <TargetOption>
@ -30,8 +30,8 @@
<OPTTT> <OPTTT>
<gFlags>1</gFlags> <gFlags>1</gFlags>
<BeepAtEnd>1</BeepAtEnd> <BeepAtEnd>1</BeepAtEnd>
<RunSim>0</RunSim> <RunSim>1</RunSim>
<RunTarget>1</RunTarget> <RunTarget>0</RunTarget>
<RunAbUc>0</RunAbUc> <RunAbUc>0</RunAbUc>
</OPTTT> </OPTTT>
<OPTHX> <OPTHX>
@ -89,7 +89,7 @@
<sRfunc>1</sRfunc> <sRfunc>1</sRfunc>
<sRbox>1</sRbox> <sRbox>1</sRbox>
<tLdApp>1</tLdApp> <tLdApp>1</tLdApp>
<tGomain>1</tGomain> <tGomain>0</tGomain>
<tRbreak>1</tRbreak> <tRbreak>1</tRbreak>
<tRwatch>1</tRwatch> <tRwatch>1</tRwatch>
<tRmem>1</tRmem> <tRmem>1</tRmem>
@ -117,106 +117,25 @@
<pMon>Segger\JL2CM3.dll</pMon> <pMon>Segger\JL2CM3.dll</pMon>
</DebugOpt> </DebugOpt>
<TargetDriverDllRegistry> <TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>UL2CM3</Key>
<Name>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000)</Name>
</SetRegEntry>
<SetRegEntry> <SetRegEntry>
<Number>0</Number> <Number>0</Number>
<Key>JL2CM3</Key> <Key>JL2CM3</Key>
<Name>-U20090928 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8001 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO11 -FD20003000 -FC5000 -FN1 -FF0B6x_256kB_PY_D.FLM -FS018000000 -FL040000 -FP0($$Device:B6x$.\Flash\B6x_256kB_PY_D.FLM)</Name> <Name>-U20090928 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(0BC11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8008 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO31 -FD20003000 -FC5000 -FN1 -FF0B6x_256kB_PY_D.FLM -FS018000000 -FL040000 -FP0($$Device:B6x$.\Flash\B6x_256kB_PY_D.FLM)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMRTXEVENTFLAGS</Key>
<Name>-L70 -Z18 -C0 -M0 -T1</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGTARM</Key>
<Name>(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)</Name>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMDBGFLAGS</Key>
<Name></Name>
</SetRegEntry> </SetRegEntry>
</TargetDriverDllRegistry> </TargetDriverDllRegistry>
<Breakpoint> <Breakpoint/>
<Bp>
<Number>0</Number>
<Type>0</Type>
<LineNumber>0</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>402735504</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>1</BreakIfRCount>
<Filename></Filename>
<ExecCommand></ExecCommand>
<Expression>0x18014190</Expression>
</Bp>
<Bp>
<Number>1</Number>
<Type>0</Type>
<LineNumber>0</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>402735500</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>1</BreakIfRCount>
<Filename></Filename>
<ExecCommand></ExecCommand>
<Expression>0x1801418C</Expression>
</Bp>
<Bp>
<Number>2</Number>
<Type>0</Type>
<LineNumber>0</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>402735502</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>1</BreakIfRCount>
<Filename></Filename>
<ExecCommand></ExecCommand>
<Expression>0x1801418E</Expression>
</Bp>
</Breakpoint>
<WatchWindow1>
<Ww>
<count>0</count>
<WinNumber>1</WinNumber>
<ItemText>gBleSleep</ItemText>
</Ww>
<Ww>
<count>1</count>
<WinNumber>1</WinNumber>
<ItemText>DMA_RX_BUFF</ItemText>
</Ww>
</WatchWindow1>
<Tracepoint> <Tracepoint>
<THDelay>0</THDelay> <THDelay>0</THDelay>
</Tracepoint> </Tracepoint>
<DebugFlag> <DebugFlag>
<trace>0</trace> <trace>0</trace>
<periodic>1</periodic> <periodic>0</periodic>
<aLwin>1</aLwin> <aLwin>0</aLwin>
<aCover>0</aCover> <aCover>0</aCover>
<aSer1>0</aSer1> <aSer1>0</aSer1>
<aSer2>0</aSer2> <aSer2>0</aSer2>
<aPa>0</aPa> <aPa>0</aPa>
<viewmode>1</viewmode> <viewmode>0</viewmode>
<vrSel>0</vrSel> <vrSel>0</vrSel>
<aSym>0</aSym> <aSym>0</aSym>
<aTbox>0</aTbox> <aTbox>0</aTbox>
@ -424,7 +343,7 @@
<GroupNumber>2</GroupNumber> <GroupNumber>2</GroupNumber>
<FileNumber>14</FileNumber> <FileNumber>14</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\src\sys_config.c</PathWithFileName> <PathWithFileName>..\src\sys_config.c</PathWithFileName>

View File

@ -7,7 +7,7 @@
<Targets> <Targets>
<Target> <Target>
<TargetName>uartTest</TargetName> <TargetName>OTA</TargetName>
<ToolsetNumber>0x4</ToolsetNumber> <ToolsetNumber>0x4</ToolsetNumber>
<ToolsetName>ARM-ADS</ToolsetName> <ToolsetName>ARM-ADS</ToolsetName>
<pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed> <pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed>
@ -48,7 +48,7 @@
<InvalidFlash>1</InvalidFlash> <InvalidFlash>1</InvalidFlash>
</TargetStatus> </TargetStatus>
<OutputDirectory>.\output\</OutputDirectory> <OutputDirectory>.\output\</OutputDirectory>
<OutputName>uartTest.elf</OutputName> <OutputName>OTA_V2_8</OutputName>
<CreateExecutable>1</CreateExecutable> <CreateExecutable>1</CreateExecutable>
<CreateLib>0</CreateLib> <CreateLib>0</CreateLib>
<CreateHexFile>1</CreateHexFile> <CreateHexFile>1</CreateHexFile>
@ -79,10 +79,10 @@
<nStopB2X>0</nStopB2X> <nStopB2X>0</nStopB2X>
</BeforeMake> </BeforeMake>
<AfterMake> <AfterMake>
<RunUserProg1>1</RunUserProg1> <RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2> <RunUserProg2>1</RunUserProg2>
<UserProg1Name>fromelf.exe --bin -o "$L@L.bin" "#L"</UserProg1Name> <UserProg1Name>fromelf.exe --bin -o "$L@L.bin" "#L"</UserProg1Name>
<UserProg2Name></UserProg2Name> <UserProg2Name>powershell -executionpolicy Unrestricted -file .\link_high_bank.PS1</UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode> <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode> <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
<nStopA1X>0</nStopA1X> <nStopA1X>0</nStopA1X>
@ -184,6 +184,8 @@
<uocXRam>0</uocXRam> <uocXRam>0</uocXRam>
<RvdsVP>0</RvdsVP> <RvdsVP>0</RvdsVP>
<RvdsMve>0</RvdsMve> <RvdsMve>0</RvdsMve>
<RvdsCdeCp>0</RvdsCdeCp>
<nBranchProt>0</nBranchProt>
<hadIRAM2>0</hadIRAM2> <hadIRAM2>0</hadIRAM2>
<hadIROM2>0</hadIROM2> <hadIROM2>0</hadIROM2>
<StupSel>0</StupSel> <StupSel>0</StupSel>
@ -350,7 +352,7 @@
<NoWarn>0</NoWarn> <NoWarn>0</NoWarn>
<uSurpInc>0</uSurpInc> <uSurpInc>0</uSurpInc>
<useXO>0</useXO> <useXO>0</useXO>
<uClangAs>0</uClangAs> <ClangAsOpt>4</ClangAsOpt>
<VariousControls> <VariousControls>
<MiscControls>--thumb</MiscControls> <MiscControls>--thumb</MiscControls>
<Define></Define> <Define></Define>
@ -368,7 +370,7 @@
<TextAddressRange>0x00000000</TextAddressRange> <TextAddressRange>0x00000000</TextAddressRange>
<DataAddressRange>0x00000000</DataAddressRange> <DataAddressRange>0x00000000</DataAddressRange>
<pXoBase></pXoBase> <pXoBase></pXoBase>
<ScatterFile>..\..\..\core\mdk\link_xip.sct</ScatterFile> <ScatterFile>.\link_xip_0x04000.sct</ScatterFile>
<IncludeLibs></IncludeLibs> <IncludeLibs></IncludeLibs>
<IncludeLibsPath></IncludeLibsPath> <IncludeLibsPath></IncludeLibsPath>
<Misc>--diag_suppress=L6312,L6314,L6329</Misc> <Misc>--diag_suppress=L6312,L6314,L6329</Misc>
@ -653,4 +655,13 @@
<files/> <files/>
</RTE> </RTE>
<LayerInfo>
<Layers>
<Layer>
<LayName>zhongkong</LayName>
<LayPrjMark>1</LayPrjMark>
</Layer>
</Layers>
</LayerInfo>
</Project> </Project>

View File

@ -4,6 +4,16 @@
#include "sys_config.h" #include "sys_config.h"
#define DBG_TIME_ENEVT 0
#if (DBG_TIME_ENEVT)
#include "dbg.h"
#define DEBUG(format, ...) debug("[TR_ET]" format "\r\n", ##__VA_ARGS__)
#else
#define DEBUG(format, ...)
//#define debugHex(dat, len)
#endif
static Time_Events_t Time_Events[Time_Event_MAX]; static Time_Events_t Time_Events[Time_Event_MAX];
tmr_tk_t Time_Event_tmr_id; tmr_tk_t Time_Event_tmr_id;
@ -15,15 +25,20 @@ void Event_Handle(uint16_t Event_List ,bool isOn,void *Parameter){
(void)Parameter; (void)Parameter;
switch(Event_List){ switch(Event_List){
case Buzzer_Event: case Buzzer_Event:
Set_Status(IO_TTL_TX,isOn); Set_Status(OUT_BUZZER,isOn);
break; break;
case Pmode_Timeout_Event: case Pmode_Timeout_Event:
if(!isOn){ if(!isOn){
sys_sta.Pmode =0; DEBUG("Pmode_Timeout_Event\n\nERROR\n\n");
// sys_sta.Pmode =0;
} }
break; break;
case GRB_WS2812_Event: case GRB_WS2812_Event:
if(0x01 == (sys_sta.Pmode | sys_sta.Smode)){
GRB_WS2812_Write_color(WS2812_GRBs.len, isOn ? WS2812_GRBs.GRBs : 0x0); GRB_WS2812_Write_color(WS2812_GRBs.len, isOn ? WS2812_GRBs.GRBs : 0x0);
}else{
GRB_WS2812_Write_color(WS2812_GRBs.len, isOn ? GRB_ORANGE : 0x0);
}
break; break;
default: default:
@ -47,6 +62,7 @@ static tmr_tk_t Time_Event_Handle(tmr_id_t id) {
// 打开 // 打开
Events->isOn = true; Events->isOn = true;
if(Events->Ms_delayoff){ if(Events->Ms_delayoff){
DEBUG("OffDelay:%d,delay:%d\n",i,Events->Ms_delayoff);
Events->mode = Time_MODE_OFF; Events->mode = Time_MODE_OFF;
Events->delay =1 + Events->Ms_delayoff; Events->delay =1 + Events->Ms_delayoff;
Events->Ms_delayoff =0; Events->Ms_delayoff =0;
@ -72,7 +88,7 @@ static tmr_tk_t Time_Event_Handle(tmr_id_t id) {
} }
} }
return (Time_delay_interval / 10); return (Time_delay_interval / 10);//1;
} }
void Time_Event_Init(void) { void Time_Event_Init(void) {
@ -84,23 +100,31 @@ void Time_Event_Init(void) {
Time_Events[i].blinkCount = 0; Time_Events[i].blinkCount = 0;
Time_Events[i].isOn = false; Time_Events[i].isOn = false;
Time_Events[i].Parameter=NULL; Time_Events[i].Parameter=NULL;
Time_Events[i].Ms_delayoff =0;
DEBUG("Delay:%d,%dms",i, Time_Events[i].Ms_delayoff);
} }
Time_Event_tmr_id = sftmr_start(10, Time_Event_Handle); Time_Event_tmr_id = sftmr_start(10, Time_Event_Handle);
} }
void Time_Event_On(uint16_t ledIndex,void *Parameter) { void Time_Event_On(uint16_t ledIndex,void *Parameter) {
DEBUG("On:%d",ledIndex);
Time_Events[ledIndex].mode = Time_MODE_ON; Time_Events[ledIndex].mode = Time_MODE_ON;
Time_Events[ledIndex].delay = 1; Time_Events[ledIndex].delay = 1;
// Time_Events[ledIndex].Ms_delayoff =0;
Time_Events[ledIndex].Parameter=Parameter; Time_Events[ledIndex].Parameter=Parameter;
} }
void Time_Event_Off(uint16_t ledIndex,void *Parameter) { void Time_Event_Off(uint16_t ledIndex,void *Parameter) {
DEBUG("Off:%d",ledIndex);
Time_Events[ledIndex].mode = Time_MODE_OFF; Time_Events[ledIndex].mode = Time_MODE_OFF;
Time_Events[ledIndex].delay = 1; Time_Events[ledIndex].delay = 1;
// Time_Events[ledIndex].Ms_delayoff =0;
Time_Events[ledIndex].Parameter=Parameter; Time_Events[ledIndex].Parameter=Parameter;
} }
void Time_Event_DelayOff(uint16_t ledIndex ,uint16_t Ms_delayoff,void *Parameter) { void Time_Event_DelayOff(uint16_t ledIndex ,uint16_t Ms_delayoff,void *Parameter) {
DEBUG("Delay:%d,%dms",ledIndex, Ms_delayoff);
if(0 == Ms_delayoff/Time_delay_interval){return;}
Time_Events[ledIndex].mode = Time_MODE_ON; Time_Events[ledIndex].mode = Time_MODE_ON;
Time_Events[ledIndex].delay = 1; Time_Events[ledIndex].delay = 1;
Time_Events[ledIndex].Ms_delayoff =Ms_delayoff / Time_delay_interval; Time_Events[ledIndex].Ms_delayoff =Ms_delayoff / Time_delay_interval;
@ -108,12 +132,16 @@ void Time_Event_DelayOff(uint16_t ledIndex ,uint16_t Ms_delayoff,void *Parameter
} }
void Time_Event_Cancel_DelayOff(uint16_t ledIndex) { void Time_Event_Cancel_DelayOff(uint16_t ledIndex) {
DEBUG("Cancel:%d",ledIndex);
Time_Events[ledIndex].mode = Time_MODE_OFF;
Time_Events[ledIndex].delay = 0; Time_Events[ledIndex].delay = 0;
Time_Events[ledIndex].Ms_delayoff =0; Time_Events[ledIndex].Ms_delayoff =0;
Time_Events[ledIndex].Parameter =NULL; Time_Events[ledIndex].Parameter =NULL;
} }
void Time_Event_Blink(uint16_t ledIndex, uint16_t Ms_on, uint16_t Ms_off, uint16_t blinkCount,void *Parameter) { void Time_Event_Blink(uint16_t ledIndex, uint16_t Ms_on, uint16_t Ms_off, uint16_t blinkCount,void *Parameter) {
DEBUG("Blink:%d,on%dms,off%dms,count%d",ledIndex, Ms_on, Ms_off, blinkCount);
Time_Events[ledIndex].mode = Time_MODE_BLINK; Time_Events[ledIndex].mode = Time_MODE_BLINK;
Time_Events[ledIndex].Ms_on = Ms_on / Time_delay_interval; Time_Events[ledIndex].Ms_on = Ms_on / Time_delay_interval;
Time_Events[ledIndex].Ms_off = Ms_off / Time_delay_interval; Time_Events[ledIndex].Ms_off = Ms_off / Time_delay_interval;

View File

@ -5,19 +5,143 @@
#include "app_bat.h" #include "app_bat.h"
#include "sys_config.h" #include "sys_config.h"
#define BAT_Message_interval 1000 #define DBG_EN 0
#if (DBG_EN)
#include "dbg.h"
#define DEBUG(format, ...) debug("[Bat]" format, ##__VA_ARGS__)
#else
#define DEBUG(format, ...)
//#define debugHex(dat, len)
#endif
#define BAT_Message_interval 100
tmr_id_t BAT_Message_tmr_id; tmr_id_t BAT_Message_tmr_id;
BAT_Message_t BAT_Message; BAT_Message_t BAT_Message;
uint16_t Bat_Voltage_Last;
uint16_t Voltage_lag_count;
uint8_t Bat_STA_Last;
// 门锁状态更新标志 // 门锁状态更新标志
bool GRB_Door_lock_updata=0; bool GRB_Door_lock_updata=0;
uint8_t Bat_STA_Last;
uint16_t Voltage_lag_count;
uint16_t Voltage_update_count;
float temp_bat_voltage=0;
// uint16_t Bat_Voltage_Last;
// uint8_t bat_str[50]={0,0},bat_str_len=0; // uint8_t bat_str[50]={0,0},bat_str_len=0;
const uint16_t coulomp_voltage_table[11] = {
BAT_LEVEL_0PERCENT_VOLT,
BAT_LEVEL_10PERCENT_VOLT,
BAT_LEVEL_20PERCENT_VOLT,
BAT_LEVEL_30PERCENT_VOLT,
BAT_LEVEL_40PERCENT_VOLT,
BAT_LEVEL_50PERCENT_VOLT,
BAT_LEVEL_60PERCENT_VOLT,
BAT_LEVEL_70PERCENT_VOLT,
BAT_LEVEL_80PERCENT_VOLT,
BAT_LEVEL_90PERCENT_VOLT,
BAT_LEVEL_100PERCENT_VOLT,
};
uint8_t pmu_voltage_to_percent(uint32_t volt){//电压转百分比
uint8_t i, percent;
float step, base;
if((volt < coulomp_voltage_table[0])){
return 0;
}
if((volt >= coulomp_voltage_table[10])){
return 100;
}
for (i = 0; i < 10; i++) {
if((volt < coulomp_voltage_table[i+1]) && (volt >= coulomp_voltage_table[i])){
step = (coulomp_voltage_table[i+1] - coulomp_voltage_table[i]) / 10.0;
base = coulomp_voltage_table[i];
percent = (10 * i) + (volt - base) / step;
DEBUG("\n\ni:%d,volt:%d,step:%02.2f,base:%02.2f,percent:%d\n\n",i,volt,step,base,percent);
return (uint8_t)percent;
}
}
return 0;
}
uint8_t LED_control =0,LED_control_last =0;
static tmr_tk_t BAT_Message_Handle(tmr_id_t id) {
uint16_t in_acc_percent= get_in_acc_percent();
if(BAT_Message.Runing_Time < 0xFFFF){
BAT_Message.Runing_Time++;
}
temp_bat_voltage += get_bat_voltage() * 10;
Voltage_update_count++;
if(Voltage_update_count >= (1000/BAT_Message_interval)){//1s
BAT_Message.Bat_Voltage = temp_bat_voltage / Voltage_update_count;
Voltage_update_count=0;
temp_bat_voltage = 0;
}
// in_acc_percent =80;
if(in_acc_percent >= 80){ // 油门大于80%时,
if(BAT_Message.Deep_ACC_Time < 0xFFFF){
BAT_Message.Deep_ACC_Time++;
}
Voltage_lag_count++;
if(Voltage_lag_count >= (2000/BAT_Message_interval)){//2s
Voltage_lag_count=0;
BAT_Message.Bat_Percent = pmu_voltage_to_percent(BAT_Message.Bat_Voltage);
}
if(BAT_Message.Bat_Percent < 12){
BAT_Message.Bat_Low_Volt_count++;
}
}else{
Voltage_lag_count=0;
}
if(BAT_Message.Bat_Percent < 7){
BAT_Message.Bat_STA =(BAT_Message.Bat_STA & 0xE0)|Bat_Low_STA;
WS2812_GRBs.GRBs=GRB_RED;
}else if(BAT_Message.Bat_Percent < 30){ // 7~30%
BAT_Message.Bat_STA =(BAT_Message.Bat_STA & 0xE0)|Bat_30_STA;
WS2812_GRBs.GRBs=GRB_RED;
}else if(BAT_Message.Bat_Percent < 60){ // 30~60%
BAT_Message.Bat_STA =(BAT_Message.Bat_STA & 0xE0)|Bat_60_STA;
WS2812_GRBs.GRBs=GRB_BLUE;
}else if(BAT_Message.Bat_Percent < 80){ // 60~80%
BAT_Message.Bat_STA =(BAT_Message.Bat_STA & 0xE0)|Bat_80_STA;
WS2812_GRBs.GRBs=GRB_WHITE;
}else{
BAT_Message.Bat_STA =(BAT_Message.Bat_STA & 0xE0)|Bat_100_STA;
WS2812_GRBs.GRBs=GRB_WHITE;
}
if((Bat_STA_Last != BAT_Message.Bat_STA) || (GRB_Door_lock_updata != Get_Status(OUT_Door_lock)) || (LED_control != LED_control_last)){
GRB_Door_lock_updata=Get_Status(OUT_Door_lock);
LED_control_last =LED_control;
Bat_STA_Last =BAT_Message.Bat_STA;
if( Get_Status(OUT_Door_lock) || (LED_control != 0)){
if(BAT_Message.Bat_STA & Bat_Charge_STA){
Time_Event_Blink(GRB_WS2812_Event,500,500,0xffff,NULL);
}else{
if(BAT_Message.Bat_STA & Bat_Low_STA){
Time_Event_Blink(GRB_WS2812_Event,200,200,0xffff,NULL);
}else{
Time_Event_Blink(GRB_WS2812_Event,500,500,0xffff,NULL);
}
}
}else{
Time_Event_Off(GRB_WS2812_Event,NULL);
}
}
DEBUG("\n\nSTA:0x%#X,V:%d,%d %%,Run:%d,D_A:%d\n\n",BAT_Message.Bat_STA,BAT_Message.Bat_Voltage,BAT_Message.Bat_Percent,BAT_Message.Runing_Time,BAT_Message.Deep_ACC_Time);
return (BAT_Message_interval / 10);
}
/*
static tmr_tk_t BAT_Message_Handle(tmr_id_t id) { static tmr_tk_t BAT_Message_Handle(tmr_id_t id) {
uint16_t Bat_Voltage = get_bat_voltage() * 10; uint16_t Bat_Voltage = get_bat_voltage() * 10;
@ -33,10 +157,10 @@ static tmr_tk_t BAT_Message_Handle(tmr_id_t id) {
WS2812_GRBs.GRBs=GRB_BLUE; WS2812_GRBs.GRBs=GRB_BLUE;
}else if(Bat_Percent_100 > Bat_Voltage){ }else if(Bat_Percent_100 > Bat_Voltage){
BAT_Message.Bat_STA =(BAT_Message.Bat_STA & 0x03)|Bat_100_STA; BAT_Message.Bat_STA =(BAT_Message.Bat_STA & 0x03)|Bat_100_STA;
WS2812_GRBs.GRBs=GRB_GREEN; WS2812_GRBs.GRBs=GRB_WHITE;
}else{ }else{
BAT_Message.Bat_STA =(BAT_Message.Bat_STA & 0xF3)|Bat_Full_STA; BAT_Message.Bat_STA =(BAT_Message.Bat_STA & 0xF3)|Bat_Full_STA;
WS2812_GRBs.GRBs=GRB_GREEN; WS2812_GRBs.GRBs=GRB_WHITE;
} }
if(0==(BAT_Message.Bat_STA & Bat_Charge_STA)){ if(0==(BAT_Message.Bat_STA & Bat_Charge_STA)){
Bat_Voltage_Last =Bat_Voltage; Bat_Voltage_Last =Bat_Voltage;
@ -74,7 +198,8 @@ static tmr_tk_t BAT_Message_Handle(tmr_id_t id) {
Bat_STA_Last =BAT_Message.Bat_STA; Bat_STA_Last =BAT_Message.Bat_STA;
if( Get_Status(OUT_Door_lock)){ if( Get_Status(OUT_Door_lock)){
if(BAT_Message.Bat_STA & Bat_Charge_STA){ if(BAT_Message.Bat_STA & Bat_Charge_STA){
Time_Event_On(GRB_WS2812_Event,NULL); // Time_Event_On(GRB_WS2812_Event,NULL);
Time_Event_Blink(GRB_WS2812_Event,500,500,0xffff,NULL);
}else if(BAT_Message.Bat_STA & Bat_Low_STA){ }else if(BAT_Message.Bat_STA & Bat_Low_STA){
Time_Event_Blink(GRB_WS2812_Event,150,150,0xffff,NULL); Time_Event_Blink(GRB_WS2812_Event,150,150,0xffff,NULL);
}else{ }else{
@ -89,8 +214,13 @@ static tmr_tk_t BAT_Message_Handle(tmr_id_t id) {
return (BAT_Message_interval / 10); return (BAT_Message_interval / 10);
} }
*/
void BAT_Message_Init(void) { void BAT_Message_Init(void) {
BAT_Message_tmr_id = sftmr_start(10, BAT_Message_Handle); BAT_Message_tmr_id = sftmr_start(10, BAT_Message_Handle);
Bat_Voltage_Last =get_bat_voltage() * 10; BAT_Message.Bat_Voltage = get_bat_voltage() * 10;
BAT_Message.Bat_Percent = pmu_voltage_to_percent(BAT_Message.Bat_Voltage);
BAT_Message.Runing_Time = 0;
BAT_Message.Deep_ACC_Time = 0;
BAT_Message.Bat_STA = 0;
} }

View File

@ -1,39 +1,61 @@
#ifndef _APP_BAT_H_ #ifndef _APP_BAT_H_
#define _APP_BAT_H_ #define _APP_BAT_H_
#define BAT_SxP1 4 // 电池四串一并
#define BAT_VOLT(_Volt) (_Volt * BAT_SxP1) //电压单位转换
#define BAT_Low_VOLT BAT_VOLT(105) //10.5V x 4 = 42V
#define BAT_Full_VOLT BAT_VOLT(144) //14.4V x 4 = 57.6V
// #define BAT_LEVEL_0PERCENT_VOLT BAT_VOLT(105) // 0%:(105~110]=(42.0V~44.0V]
// #define BAT_LEVEL_10PERCENT_VOLT BAT_VOLT(113) // 10%:(110~113]=(44.0V~45.2V]
// #define BAT_LEVEL_20PERCENT_VOLT BAT_VOLT(116) // 20%:(113~116]=(45.2V~46.4V]
// #define BAT_LEVEL_30PERCENT_VOLT BAT_VOLT(119) // 30%:(116~119]=(46.4V~47.6V]
// #define BAT_LEVEL_40PERCENT_VOLT BAT_VOLT(122) // 40%:(119~122]=(47.6V~48.8V]
// #define BAT_LEVEL_50PERCENT_VOLT BAT_VOLT(125) // 50%:(122~125]=(48.8V~50.0V]
// #define BAT_LEVEL_60PERCENT_VOLT BAT_VOLT(128) // 60%:(125~128]=(50.0V~51.2V]
// #define BAT_LEVEL_70PERCENT_VOLT BAT_VOLT(131) // 70%:(128~131]=(51.2V~52.4V]
// #define BAT_LEVEL_80PERCENT_VOLT BAT_VOLT(134) // 80%:(131~134]=(52.4V~53.6V]
// #define BAT_LEVEL_90PERCENT_VOLT BAT_VOLT(137) // 90%:(134~137]=(53.6V~54.8V]
// #define BAT_LEVEL_100PERCENT_VOLT BAT_VOLT(144) //100%:(137~144]=(54.8V~57.6V]
// 内阻 20mΩ * 4 =80mΩ // 线损 10A 0.1V
#define BAT_LEVEL_0PERCENT_VOLT BAT_VOLT(105) // 0%
#define BAT_LEVEL_10PERCENT_VOLT BAT_VOLT(107) // 10%
#define BAT_LEVEL_20PERCENT_VOLT BAT_VOLT(109) // 20%
#define BAT_LEVEL_30PERCENT_VOLT BAT_VOLT(111) // 30%
#define BAT_LEVEL_40PERCENT_VOLT BAT_VOLT(113) // 40%
#define BAT_LEVEL_50PERCENT_VOLT BAT_VOLT(115) // 50%
#define BAT_LEVEL_60PERCENT_VOLT BAT_VOLT(117) // 60%
#define BAT_LEVEL_70PERCENT_VOLT BAT_VOLT(119) // 70%
#define BAT_LEVEL_80PERCENT_VOLT BAT_VOLT(123) // 80%
#define BAT_LEVEL_90PERCENT_VOLT BAT_VOLT(127) // 90%
#define BAT_LEVEL_100PERCENT_VOLT BAT_VOLT(134) //100%
// 充电状态 // 充电状态
typedef enum { typedef enum {
Bat_NotCharge_STA=0x01, Bat_Low_STA=(1<<0),
Bat_Charge_STA=0x02, Bat_30_STA=(1<<1),
Bat_Full_STA=0x04, Bat_60_STA=(1<<2),
Bat_Low_STA=0x08, Bat_80_STA=(1<<3),
Bat_30_STA=0x10, Bat_100_STA=(1<<4),
Bat_60_STA=0x20, Bat_NotCharge_STA=(1<<5),
Bat_100_STA=0x40, Bat_Charge_STA=(1<<6),
} BAT_STA_t; } BAT_STA_t;
typedef enum {
Bat_Percent_Low =420,
Bat_Percent_30 =454,
Bat_Percent_60 =489,
Bat_Percent_100 =535,
} BAT_Percent_t;
// typedef enum {
// Bat_Percent_Low =240,
// Bat_Percent_30 =260,
// Bat_Percent_60 =300,
// Bat_Percent_100 =350,
// } BAT_Percent_t;
typedef struct BAT_Message{ typedef struct BAT_Message{
uint8_t Bat_STA; uint8_t Bat_STA;
uint8_t Bat_Remain_Time; // 剩余充电时间 uint8_t Bat_Percent; // 42=42%
uint8_t Bat_Low_Volt_count; // 低压计数
uint16_t Bat_Voltage; // 480=48.0V uint16_t Bat_Voltage; // 480=48.0V
uint16_t Bat_Percent; // 420=42.0% uint16_t Runing_Time; // 系统运行时间
uint16_t Deep_ACC_Time; // 深踩油门时间
} BAT_Message_t; } BAT_Message_t;
uint8_t pmu_voltage_to_percent(uint32_t volt); // 电压转百分比
void BAT_Message_Init(void); void BAT_Message_Init(void);
#endif #endif

View File

@ -25,31 +25,18 @@ uint16_t ACC_Dmax ;
bool app_control_en[PA_MAX]={ bool app_control_en[PA_MAX]={
[OUT_12V_Control] =OE_HIGH, // 12V电源控制输出 /H:12V输出 [OUT_12V_Control] =OE_HIGH, // 12V电源控制输出 /H:12V输出
[OUT_Door_lock] =OE_HIGH, // 开锁 /H:开锁(同) [OUT_Door_lock] =OE_HIGH, // 开锁 /H:开锁(同)
[IN_01] =OE_LOW, // 自定义输入 [IO_MANAGER_MODE] =OE_LOW, // 管理员模式 /低电平触发
[IN_GPS] =OE_HIGH, // GPS输入0 /H:低使能/边沿触发
[IO_MANAGER_MODE] =OE_LOW, // 管理员模式 /边沿触发
[IO_BACK] =OE_LOW, // 倒车 /H:前进/L:后退 [IO_BACK] =OE_LOW, // 倒车 /H:前进/L:后退
[IO_AUTO_BRAKE] =OE_HIGH, // 自动刹车 /H:高使能
[IO_BRAKE] =OE_LOW, // 制动 /L:低使能 [IO_BRAKE] =OE_LOW, // 制动 /L:低使能
[IO_TTL_TX] =OE_LOW, // 串口发送 [IO_TTL_TX] =OE_LOW, // 串口发送
[IO_TTL_RX] =OE_LOW, // 串口接收 [IO_TTL_RX] =OE_LOW, // 串口接收
};
[OUT_BUZZER] =OE_HIGH, // 蜂鸣器输出 /H:蜂鸣器响
[IO_INTERACTION] =OE_LOW, // 交互信号输入 (人体感应器) /L:低电平触发
};
sys_sta_t sys_sta; sys_sta_t sys_sta;
// ={
// .Pmode = 0,
// .Smode = 0,
// .O_12V = 0,
// .O_lock = 0,
// .I_01 = 0,
// .I_brake = 0,
// .I_back = 0,
// .IO_TX = 0,
// .IO_RX = 0,
// .A_brake = 0,
// .A_Speed_Cut = 0,
// .Reserve = 0,
// };
// 油门控制输入初始化/PA08/CH3 // 油门控制输入初始化/PA08/CH3
// 电池电压检测/充电检测/PA04/CH7 // 电池电压检测/充电检测/PA04/CH7
@ -60,7 +47,7 @@ static void acc_in_bat_in_sadc_init(void)
// ADC // ADC
iom_ctrl(PA08, IOM_ANALOG);//ACC//AIN7//油门 iom_ctrl(PA08, IOM_ANALOG);//ACC//AIN7//油门
iom_ctrl(PA02, IOM_ANALOG);//ACC_FEEDBACK//AIN2//油门反馈 // iom_ctrl(PA02, IOM_ANALOG);//ACC_FEEDBACK//AIN2//油门反馈
iom_ctrl(PA04, IOM_ANALOG);//BAT//AIN3//电池电量 iom_ctrl(PA04, IOM_ANALOG);//BAT//AIN3//电池电量
// sadc init // sadc init
@ -146,44 +133,42 @@ void set_out_acc_percent(uint8_t percent){
//中控控制IO初始化 //中控控制IO初始化
void app_control_init(void){ void app_control_init(void){
// out // IO init
gpio_dir_output(OUT_12V_Control,OE_LOW);// 12V电源控制输出 /H:12V输出 gpio_dir_output(OUT_12V_Control,OE_LOW);// 12V电源控制输出 /H:12V输出
gpio_dir_input(OUT_12V_Control,IE_UP);
gpio_dir_output(OUT_Door_lock,OE_LOW); // 电门锁 /H:开锁 gpio_dir_output(OUT_Door_lock,OE_LOW); // 电门锁 /H:开锁
gpio_dir_output(IO_MANAGER_MODE,OE_LOW);// 管理员模式 /边沿触发 gpio_dir_input(OUT_Door_lock,IE_UP);
gpio_dir_output(IO_BACK,OE_HIGH); // 倒车 /H:前进/L:后退
gpio_dir_output(IO_MANAGER_MODE,OE_HIGH);// 管理员模式 /边沿触发
gpio_dir_input(IO_MANAGER_MODE,IE_UP);
gpio_dir_output(IO_BACK,OE_HIGH);// 倒车 /H:前进/L:后退
gpio_dir_input(IO_BACK,IE_UP);
gpio_dir_output(IO_AUTO_BRAKE,OE_HIGH); // 自动刹车 /H:高使能
gpio_dir_input(IO_AUTO_BRAKE,IE_UP);
gpio_dir_output(IO_BRAKE,OE_LOW); // 制动 /L:低使能 gpio_dir_output(IO_BRAKE,OE_LOW); // 制动 /L:低使能
gpio_dir_input(IO_BRAKE,IE_UP);
gpio_dir_output(IO_TTL_TX,OE_HIGH); // 串口发送 gpio_dir_input(IO_TTL_TX,IE_UP); // 串口发送
gpio_dir_output(IO_TTL_RX,OE_LOW); // 串口接收 gpio_dir_input(IO_TTL_RX,IE_UP); // 串口接收
//in
// gpio_dir_input(OUT_12V_Control,IE_DOWN);// 12V电源控制输出 /H:12V输出
gpio_dir_input(OUT_Door_lock,IE_DOWN); // 电门锁 /H:开锁
gpio_dir_input(IO_MANAGER_MODE,IE_DOWN);// 管理员模式 /边沿触发
gpio_dir_input(IO_BACK,IE_DOWN); // 倒车 /H:前进/L:后退
gpio_dir_input(IO_BRAKE,IE_DOWN); // 制动 /L:低使能
gpio_dir_input(IO_TTL_TX,IE_DOWN); // 串口发送 gpio_dir_output(OUT_BUZZER,OE_LOW); // 蜂鸣器输出
gpio_dir_input(IO_TTL_RX,IE_DOWN); // 串口接收
gpio_dir_output(IO_INTERACTION,OE_HIGH);
gpio_dir_input(IO_INTERACTION,IE_UP); // 交互信号输入 (人体感应器)
//默认都失能 //默认都失能
Set_Status(OUT_12V_Control,0); Set_Status(OUT_12V_Control,0);
Set_Status(OUT_Door_lock,0); Set_Status(OUT_Door_lock,0);
Set_Status(IO_MANAGER_MODE,0); Set_Status(IO_AUTO_BRAKE,0);
Set_Status(IO_BACK,0); //失能倒车
Set_Status(IO_BRAKE,0); Set_Status(IO_BRAKE,0);
Set_Status(OUT_BUZZER,0);
Set_Status(IO_TTL_TX,0);
Set_Status(IO_TTL_RX,0);
// in
gpio_dir_input(IN_01,IE_UP); // 自定义输入
gpio_dir_input(IN_GPS,IE_UP); // GPS输入0 /边沿触发
// // EXTI config // // EXTI config
// exti_init(EXTI_DBC(15, 4)); // exti_init(EXTI_DBC(15, 4));
// exti_set(EXTI_FTS, EXTI_SRC(IN_GPS) | EXTI_SRC(IO_BACK) | EXTI_SRC(IO_BRAKE) | EXTI_SRC(IO_MANAGER_MODE)); // falling // exti_set(EXTI_FTS, EXTI_SRC(IO_INTERACTION) | EXTI_SRC(IO_BACK) | EXTI_SRC(IO_BRAKE) | EXTI_SRC(IO_MANAGER_MODE)); // falling
// exti_set(EXTI_DBE, EXTI_SRC(IN_GPS) | EXTI_SRC(IO_BACK) | EXTI_SRC(IO_BRAKE) | EXTI_SRC(IO_MANAGER_MODE)); // exti_set(EXTI_DBE, EXTI_SRC(IO_INTERACTION) | EXTI_SRC(IO_BACK) | EXTI_SRC(IO_BRAKE) | EXTI_SRC(IO_MANAGER_MODE));
// exti_set(EXTI_IER, EXTI_SRC(IN_GPS) | EXTI_SRC(IO_BACK) | EXTI_SRC(IO_BRAKE) | EXTI_SRC(IO_MANAGER_MODE)); // exti_set(EXTI_IER, EXTI_SRC(IO_INTERACTION) | EXTI_SRC(IO_BACK) | EXTI_SRC(IO_BRAKE) | EXTI_SRC(IO_MANAGER_MODE));
// IRQ enable // IRQ enable
// NVIC_EnableIRQ(EXTI_IRQn); // NVIC_EnableIRQ(EXTI_IRQn);
@ -192,13 +177,13 @@ void app_control_init(void){
sys_sta.Manager =0; sys_sta.Manager =0;
sys_sta.Tourist =0; sys_sta.Tourist =0;
// sys_sta.Smode = 0; // sys_sta.Smode = 0;
sys_sta.IOgps = Get_Status(IN_GPS); sys_sta.IOgps = 0;
sys_sta.IOmanager = Get_Status(IO_MANAGER_MODE); sys_sta.IOmanager = Get_Status(IO_MANAGER_MODE);
sys_sta.I_01 = Get_Status(IN_01); sys_sta.I_interaction = Get_Status(IO_INTERACTION);
sys_sta.A_brake = Get_Status(IO_AUTO_BRAKE);
sys_sta.I_back = Get_Status(IO_BACK); sys_sta.I_back = Get_Status(IO_BACK);
sys_sta.I_brake = Get_Status(IO_BRAKE); sys_sta.I_brake = Get_Status(IO_BRAKE);
sys_sta.A_brake = 0;
sys_sta.A_Speed_Cut = 0; sys_sta.A_Speed_Cut = 0;
sys_sta.O_lock = 0; sys_sta.O_lock = 0;
sys_sta.P_Radar_EN =1; sys_sta.P_Radar_EN =1;
@ -223,9 +208,9 @@ void EXTI_IRQHandler(void)
{ {
uint32_t irq_sta = EXTI->RIF.Word; uint32_t irq_sta = EXTI->RIF.Word;
if (irq_sta & EXTI_SRC(IN_GPS))// if (irq_sta & EXTI_SRC(IO_INTERACTION))//
{ {
EXTI->ICR.Word = EXTI_SRC(IN_GPS); EXTI->ICR.Word = EXTI_SRC(IO_INTERACTION);
} }
@ -252,26 +237,24 @@ void EXTI_IRQHandler(void)
void Control_procedure(void){ void Control_procedure(void){
//电门锁 //电门锁
// sys_sta.Smode = 0; // sys_sta.Smode = 0;
sys_sta.IOgps = Get_Status(IN_GPS); //更新GPS状态 sys_sta.IOgps = 0; //更新GPS状态
sys_sta.IOmanager = Get_Status(IO_MANAGER_MODE); //更新管理员模式状态 sys_sta.IOmanager = Get_Status(IO_MANAGER_MODE); //更新管理员模式状态
sys_sta.O_lock = (0 != (sys_sta.Pmode | sys_sta.Smode)); sys_sta.O_lock = (0 != (sys_sta.Pmode | sys_sta.Smode));
Set_Status(OUT_Door_lock, sys_sta.O_lock); Set_Status(OUT_Door_lock, sys_sta.O_lock);
// Set_Status(OUT_Door_lock,(PAD_User_Mode || PAD_Manager_Mode || Get_Status(IN_GPS) || SYS_Manager_STA));
//12V电源 //12V电源
Set_Status(OUT_12V_Control ,sys_sta.O_12V);// 更新12V电源状态 Set_Status(OUT_12V_Control ,sys_sta.O_12V);// 更新12V电源状态
// Set_Status(OUT_12V_Control,(PAD_LED_ONOFF));
// 刹车 // 刹车
Set_Status(IO_BRAKE ,sys_sta.A_brake);// 输出为低电平时,可刹车 Set_Status(IO_AUTO_BRAKE ,sys_sta.A_brake);// 高刹车
Set_Status(IO_BRAKE ,sys_sta.A_brake);// 低刹车
sys_sta.I_brake = Get_Status(IO_BRAKE); //更新刹车状态// 输出为高电平时,可读取外部刹车状态 sys_sta.I_brake = Get_Status(IO_BRAKE); //更新刹车状态// 输出为高电平时,可读取外部刹车状态
// Set_Status(IO_BRAKE,SYS_AUTO_brake);
sys_sta.I_01 = Get_Status(IN_01); sys_sta.I_interaction = Get_Status(IO_INTERACTION);
sys_sta.I_back = Get_Status(IO_BACK); sys_sta.I_back = Get_Status(IO_BACK);
sys_sta.IO_TX = Get_Status(IO_TTL_TX); sys_sta.IO_TX = Get_Status(IO_TTL_TX);
sys_sta.IO_RX = Get_Status(IO_TTL_RX); sys_sta.IO_RX = Get_Status(IO_TTL_RX);
// GRB_WS2812_Write_color(64, 0xffffff);
//油门控制 //油门控制
if(0 != (sys_sta.Pmode | sys_sta.Smode)){ if(0 != (sys_sta.Pmode | sys_sta.Smode)){
uint8_t acc_percent =0; uint8_t acc_percent =0;
@ -282,31 +265,12 @@ void Control_procedure(void){
acc_percent = (get_in_acc_percent() * sys_conf.Tourist_sLim) / 100.0; acc_percent = (get_in_acc_percent() * sys_conf.Tourist_sLim) / 100.0;
} }
}else{//管理员模式 }else{//管理员模式
// Time_Event_Blink(GRB_WS2812_Event,500,500,0xffff,NULL);
acc_percent = (get_in_acc_percent() * sys_conf.Manager_sLim) / 100.0; acc_percent = (get_in_acc_percent() * sys_conf.Manager_sLim) / 100.0;
} }
set_out_acc_percent(acc_percent); set_out_acc_percent(acc_percent);
}else{ }else{
// Time_Event_Off(GRB_WS2812_Event,NULL);
set_out_acc_percent(0); set_out_acc_percent(0);
} }
// //油门控制
// if((PAD_User_Mode || PAD_Manager_Mode || Get_Status(IN_GPS) || SYS_Manager_STA)){
// uint8_t acc_percent =0;
// // acc_percent = get_in_acc_percent() *
// // (((PAD_Manager_Mode || SYS_Manager_STA) ? sys_conf.Manager_sLim : (SYS_AUTO_Speed_Cut ? sys_conf.Speed_Cut_sLim : sys_conf.Tourist_sLim)) / 100.0);
// if(PAD_Manager_Mode || SYS_Manager_STA){//管理员模式
// acc_percent = (get_in_acc_percent() * sys_conf.Manager_sLim) / 100.0;
// }else{//游客模式
// if(SYS_AUTO_Speed_Cut){//自动减速
// acc_percent = (get_in_acc_percent() * sys_conf.Speed_Cut_sLim) / 100.0;
// }else{
// acc_percent = (get_in_acc_percent() * sys_conf.Tourist_sLim) / 100.0;
// }
// }
// set_out_acc_percent(acc_percent);
// }else{
// set_out_acc_percent(0);
// }
} }

View File

@ -22,7 +22,6 @@ extern uint16_t ACC_Dmax ;
enum app_adc_dac_chx{ enum app_adc_dac_chx{
ACC_IN_CH =SADC_CH_AIN7, // 油门输入 ACC_IN_CH =SADC_CH_AIN7, // 油门输入
ACC_FEED_CH =SADC_CH_AIN2, // 油门输出监测
BAT_IN_CH =SADC_CH_AIN3, // 电池输入 BAT_IN_CH =SADC_CH_AIN3, // 电池输入
}; };
@ -30,27 +29,28 @@ enum app_adc_dac_chx{
enum app_control{ enum app_control{
OUT_12V_Control =PA17, // 12V电源控制输出 /H:12V输出 OUT_12V_Control =PA17, // 12V电源控制输出 /H:12V输出
OUT_Door_lock =PA18, // 电门锁 /H:开锁 OUT_Door_lock =PA18, // 电门锁 /H:开锁
IN_01 =PA19, // 自定义输入
IN_GPS =PA03, // GPS输入0 /边沿触发
IO_MANAGER_MODE =PA13, // 管理员模式 /边沿触发 IO_MANAGER_MODE =PA13, // 管理员模式 /边沿触发
IO_BACK =PA14, // 倒车 /H:前进/L:后退 IO_BACK =PA14, // 倒车 /H:前进/L:后退
IO_BRAKE =PA15, // 制动 /L:低使能 IO_AUTO_BRAKE =PA03, // 高制动 /高:高使能
IO_BRAKE =PA15, // 低制动 /L:低使能
IO_TTL_TX =PA11, // 串口发送 IO_TTL_TX =PA11, // 串口发送
IO_TTL_RX =PA12, // 串口接收 IO_TTL_RX =PA12, // 串口接收
RADAR_TXD0 =PA07, // 串口0发送 RADAR_TXD0 =PA06, // 串口0发送
RADAR_RXD0 =PA06, // 串口0接收 RADAR_RXD0 =PA07, // 串口0接收
PAD_TXD1 =PA10, // 串口1发送 PAD_TXD1 =PA10, // 串口1发送
PAD_RXD1 =PA09, // 串口1接收 PAD_RXD1 =PA09, // 串口1接收
ACC_PA8_ADC7 =PA08, // 油门输入 ACC_PA8_ADC7 =PA08, // 油门输入
PWM4_DAC =PA05, // 油门输出 PWM4_DAC =PA05, // 油门输出
ACC_FEEDBACK_ADC2 =PA02, // 油门输出监测
RGB_DATA_IO =PA16, // RGB数据输出 RGB_DATA_IO =PA16, // RGB数据输出
BAT_PA4_ADC3 =PA04, // 电池电压输入 BAT_PA4_ADC3 =PA04, // 电池电压输入
OUT_BUZZER =PA19, // 蜂鸣器输出
IO_INTERACTION =PA02, // 交互信号输入 (人体感应器)
}; };
typedef struct sys_sta{ typedef struct sys_sta{
@ -74,7 +74,7 @@ typedef struct sys_sta{
union{// 输入状态 union{// 输入状态
uint8_t I_STA:8; uint8_t I_STA:8;
struct{ struct{
uint8_t I_01 :1; // 自定义输入状态 uint8_t I_interaction :1; // 交互信号(人体感应器)输入状态
uint8_t I_brake :1; // 制动信号输入状态 uint8_t I_brake :1; // 制动信号输入状态
uint8_t I_back :1; // 倒车信号输入状态 uint8_t I_back :1; // 倒车信号输入状态
uint8_t A_brake :1; // 自动刹车状态 uint8_t A_brake :1; // 自动刹车状态

View File

@ -24,25 +24,6 @@ static uint8_t MODBUS_ReceCount =0;
static uint8_t MODBUS_Rece_BUF[MODBUS_MAX_LEN]; static uint8_t MODBUS_Rece_BUF[MODBUS_MAX_LEN];
static uint8_t MODBUS_Sent_BUF[MODBUS_MAX_LEN]; static uint8_t MODBUS_Sent_BUF[MODBUS_MAX_LEN];
// 需掉电不丢失数据12*2字节//40027-40030//40514-40520
uint16_t MODBUS_FLASH_DAT[12] ={
[0]=1,//MODBUS从机地址
[1]=1,// 出厂模式状态 //写入 1设备将重置进入出厂模式
[2]=100,// 固件版本
[3]=1,// 硬件版本
[4]=30,//30*100ms // 代码过期时间
[5]=30,//30*100ms// 输出继电器的关闭时间
[6]=100,//100*100ms// Led 激活时间
[7]=10,//10*10ms// 蜂鸣器激活时间
[8]=0x001f,// Led 键盘颜色//RGB565 格式
[9]=0xf800,// Led Mifare 读卡颜色//RGB565 格式
[10]=0x07E0,// Led 状态灯0颜色//RGB565 格式
[11]=0x07ff,// Led 状态灯1颜色//RGB565 格式
};
bool app_modbus_CheckData(uint8_t *dat , uint8_t len); bool app_modbus_CheckData(uint8_t *dat , uint8_t len);
@ -80,6 +61,8 @@ void FunctionalCode_01(uint16_t reg_addr){//ID寄存器地址//返回7字节
} }
} }
extern uint8_t LED_control;
// 03 功能码 # 读 - 保持寄存器 // 03 功能码 # 读 - 保持寄存器
// 06 功能码 # 写 - 单个寄存器 // 06 功能码 # 写 - 单个寄存器
void FunctionalCode_03_06(uint8_t CMDCode, uint16_t reg_addr , uint16_t reg_val_num){//寄存器地址//返回8字节或15字节 void FunctionalCode_03_06(uint8_t CMDCode, uint16_t reg_addr , uint16_t reg_val_num){//寄存器地址//返回8字节或15字节
@ -115,25 +98,44 @@ void FunctionalCode_03_06(uint8_t CMDCode, uint16_t reg_addr , uint16_t reg_val_
} }
case 0x0002: // 设备的软件版本号 case 0x0002: // 设备的软件版本号
if(CMDCode == 0x03){ if(CMDCode == 0x03){
MODBUS_Sent_BUF[len_count++] =sys_conf.VERSION >> 8; MODBUS_Sent_BUF[len_count++] =(sys_conf.VERSION | VER_TYPE) >> 8;
MODBUS_Sent_BUF[len_count++] =sys_conf.VERSION & 0xff; MODBUS_Sent_BUF[len_count++] =(sys_conf.VERSION | VER_TYPE) & 0xff;
MODBUS_Sent_BUF[2] +=2; MODBUS_Sent_BUF[2] +=2;
if(0 == --reg_val_num){ if(0 == --reg_val_num){
break; break;
} }
}else if(CMDCode == 0x06){ }else if(CMDCode == 0x06){
sys_conf.VERSION =reg_val_num; len_count =0;
MODBUS_Sent_BUF[len_count++] =sys_conf.VERSION >> 8; // sys_conf.VERSION =reg_val_num;
MODBUS_Sent_BUF[len_count++] =sys_conf.VERSION & 0xff; // MODBUS_Sent_BUF[len_count++] =sys_conf.VERSION >> 8;
// MODBUS_Sent_BUF[len_count++] =sys_conf.VERSION & 0xff;
break;
}
case 0x0003: // 系统自检(只读)
if(CMDCode == 0x03){
uint16_t sys_sta=0;
MODBUS_Sent_BUF[len_count++] =sys_sta >> 8;
MODBUS_Sent_BUF[len_count++] =sys_sta & 0xff;
MODBUS_Sent_BUF[2] +=2;
if(0 == --reg_val_num){
break;
}
}else if(CMDCode == 0x06){
len_count =0;
// sys_conf.VERSION =reg_val_num;
// MODBUS_Sent_BUF[len_count++] =sys_conf.VERSION >> 8;
// MODBUS_Sent_BUF[len_count++] =sys_conf.VERSION & 0xff;
break; break;
} }
{ // 0x0101-0x0002 { // 0x0101-0x0002
case 0x0101: // // 写系统配置 case 0x0101: // // 写系统配置
if(CMDCode == 0x03){ // # 读 - 保持寄存器 if(CMDCode == 0x03){ // # 读 - 保持寄存器
len_count =0;
break; break;
}else if(CMDCode == 0x06){ // # 写 - 单个寄存器 }else if(CMDCode == 0x06){ // # 写 - 单个寄存器
write_cfg(&sys_conf); //保存写入配置 write_cfg(&sys_conf); //保存写入配置
MODBUS_Sent_BUF[len_count++] =reg_val_num >> 8;
MODBUS_Sent_BUF[len_count++] =reg_val_num & 0xff;
break; break;
} }
case 0x0102: // 管理员模式油门极限寄存器(Unit:%) case 0x0102: // 管理员模式油门极限寄存器(Unit:%)
@ -245,13 +247,17 @@ void FunctionalCode_03_06(uint8_t CMDCode, uint16_t reg_addr , uint16_t reg_val_
break; break;
} }
}else if(CMDCode == 0x06){ }else if(CMDCode == 0x06){
uint8_t Pmode_Timeout =((reg_val_num >> 8) & 0xff); // uint8_t Pmode_Timeout =((reg_val_num >> 8) & 0xff);
if(0 == Pmode_Timeout){ // if(0 == Pmode_Timeout){
Time_Event_Cancel_DelayOff(Pmode_Timeout_Event); // Time_Event_Cancel_DelayOff(Pmode_Timeout_Event);
}else{ // }else{
Time_Event_DelayOff(Pmode_Timeout_Event ,1000 * Pmode_Timeout ,NULL); // if(Pmode_Timeout > 65){
} // Pmode_Timeout =65;
// }
// Time_Event_DelayOff(Pmode_Timeout_Event ,1000 * Pmode_Timeout ,NULL);
// }
sys_sta.Pmode =reg_val_num & 0x03; sys_sta.Pmode =reg_val_num & 0x03;
LED_control = (0 ==(reg_val_num & 0x80))?0:1;
MODBUS_Sent_BUF[len_count++] =reg_val_num >> 8; MODBUS_Sent_BUF[len_count++] =reg_val_num >> 8;
MODBUS_Sent_BUF[len_count++] =sys_sta.Pmode & 0xff; MODBUS_Sent_BUF[len_count++] =sys_sta.Pmode & 0xff;
break; break;
@ -265,6 +271,7 @@ void FunctionalCode_03_06(uint8_t CMDCode, uint16_t reg_addr , uint16_t reg_val_
break; break;
} }
}else if(CMDCode == 0x06){ }else if(CMDCode == 0x06){
len_count =0;
// sys_sta.Smode =reg_val_num & 0xff; // sys_sta.Smode =reg_val_num & 0xff;
// MODBUS_Sent_BUF[len_count++] =sys_sta.Smode >> 8; // MODBUS_Sent_BUF[len_count++] =sys_sta.Smode >> 8;
// MODBUS_Sent_BUF[len_count++] =sys_sta.Smode & 0xff; // MODBUS_Sent_BUF[len_count++] =sys_sta.Smode & 0xff;
@ -329,16 +336,19 @@ void FunctionalCode_03_06(uint8_t CMDCode, uint16_t reg_addr , uint16_t reg_val_
} }
} }
{ // 0x0201-0x0203 { // 0x0201-0x0203
case 0x0301: // 电池状态 case 0x0301: // 电池状态及电量信息
if(CMDCode == 0x03){ if(CMDCode == 0x03){
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_STA >> 8; MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_STA;
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_STA & 0xff; MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Percent;
MODBUS_Sent_BUF[2] +=2; MODBUS_Sent_BUF[2] +=2;
if(0 == --reg_val_num){ if(0 == --reg_val_num){
break; break;
} }
}else if(CMDCode == 0x06){ }else if(CMDCode == 0x06){
BAT_Message.Bat_Voltage = get_bat_voltage() * 10;
BAT_Message.Bat_Percent = pmu_voltage_to_percent(BAT_Message.Bat_Voltage);
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_STA;
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Percent;
break; break;
} }
case 0x0302: // 电池电压 case 0x0302: // 电池电压
@ -350,34 +360,63 @@ void FunctionalCode_03_06(uint8_t CMDCode, uint16_t reg_addr , uint16_t reg_val_
break; break;
} }
}else if(CMDCode == 0x06){ }else if(CMDCode == 0x06){
len_count =0;
break; break;
} }
case 0x0303: // 电池电量 case 0x0303: // 系统运行时间
if(CMDCode == 0x03){ if(CMDCode == 0x03){
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Percent >> 8; MODBUS_Sent_BUF[len_count++] =BAT_Message.Runing_Time >> 8;
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Percent & 0xff; MODBUS_Sent_BUF[len_count++] =BAT_Message.Runing_Time & 0xff;
MODBUS_Sent_BUF[2] +=2; MODBUS_Sent_BUF[2] +=2;
if(0 == --reg_val_num){ if(0 == --reg_val_num){
break; break;
} }
}else if(CMDCode == 0x06){ }else if(CMDCode == 0x06){
BAT_Message.Runing_Time =0;
MODBUS_Sent_BUF[len_count++] =BAT_Message.Runing_Time >> 8;
MODBUS_Sent_BUF[len_count++] =BAT_Message.Runing_Time & 0xff;
break; break;
} }
case 0x0304: // 剩余充电时间 case 0x0304: // 深踩油门时间
if(CMDCode == 0x03){ if(CMDCode == 0x03){
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Remain_Time >> 8; MODBUS_Sent_BUF[len_count++] =BAT_Message.Deep_ACC_Time >> 8;
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Remain_Time & 0xff; MODBUS_Sent_BUF[len_count++] =BAT_Message.Deep_ACC_Time & 0xff;
MODBUS_Sent_BUF[2] +=2; MODBUS_Sent_BUF[2] +=2;
if(0 == --reg_val_num){ if(0 == --reg_val_num){
break; break;
} }
}else if(CMDCode == 0x06){ }else if(CMDCode == 0x06){
BAT_Message.Deep_ACC_Time =0;
MODBUS_Sent_BUF[len_count++] =BAT_Message.Deep_ACC_Time >> 8;
MODBUS_Sent_BUF[len_count++] =BAT_Message.Deep_ACC_Time & 0xff;
break; break;
} }
case 0x0305: // 雷达距离信息 case 0x0305: // 低压计数
if(CMDCode == 0x03){
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Low_Volt_count >> 8;
MODBUS_Sent_BUF[len_count++] =BAT_Message.Bat_Low_Volt_count & 0xff;
MODBUS_Sent_BUF[2] +=2;
if(0 == --reg_val_num){
break;
}
}else if(CMDCode == 0x06){
len_count =0;
break;
}
case 0x0306: // 当前油门百分比
if(CMDCode == 0x03){
uint16_t in_acc_percent= get_in_acc_percent();
MODBUS_Sent_BUF[len_count++] =in_acc_percent >> 8;
MODBUS_Sent_BUF[len_count++] =in_acc_percent & 0xff;
MODBUS_Sent_BUF[2] +=2;
if(0 == --reg_val_num){
break;
}
}else if(CMDCode == 0x06){
len_count =0;
break;
}
case 0x0307: // 雷达距离信息
if(CMDCode == 0x03){ if(CMDCode == 0x03){
MODBUS_Sent_BUF[len_count++] =radar_data.distance >> 8; MODBUS_Sent_BUF[len_count++] =radar_data.distance >> 8;
MODBUS_Sent_BUF[len_count++] =radar_data.distance & 0xff; MODBUS_Sent_BUF[len_count++] =radar_data.distance & 0xff;
@ -386,7 +425,7 @@ void FunctionalCode_03_06(uint8_t CMDCode, uint16_t reg_addr , uint16_t reg_val_
break; break;
} }
}else if(CMDCode == 0x06){ }else if(CMDCode == 0x06){
len_count =0;
break; break;
} }
} }

View File

@ -52,6 +52,8 @@ void radar_AUTO_BrakeORSpeedCut(uint8_t radar_id , uint16_t Car_Distance){ //距
} }
} }
static uint8_t new_state_cnt=3;//标记状态是否变化
// 定时处理数和获取数据 // 定时处理数和获取数据
static tmr_tk_t radar_timer_handler(tmr_id_t id){ static tmr_tk_t radar_timer_handler(tmr_id_t id){
(void)(id); (void)(id);
@ -60,21 +62,24 @@ static tmr_tk_t radar_timer_handler(tmr_id_t id){
radar_CMDSend_cnt =0; // 清空发送命令计数 radar_CMDSend_cnt =0; // 清空发送命令计数
DEBUG("ID =%d,distance =%d", radar_data.radar_id ,radar_data.distance); DEBUG("ID =%d,distance =%d", radar_data.radar_id ,radar_data.distance);
} }
if((radar_CMDSend_cnt !=0)){ if((radar_CMDSend_cnt !=0)||(1 ==new_state_cnt)){//
DEBUG("Clear:CMD_cnt =%d", radar_CMDSend_cnt); DEBUG("Clear:CMD_cnt =%d", radar_CMDSend_cnt);
radar_CMDSend_cnt =0; // 清空发送命令计数 radar_CMDSend_cnt =0; // 清空发送命令计数
radar_AUTO_BrakeORSpeedCut(0 , 0);//复位自动刹车和减速状态 radar_AUTO_BrakeORSpeedCut(radar_data.radar_id , 0);//复位自动刹车和减速状态
}
if(new_state_cnt > 0){
new_state_cnt--;
} }
// 进入游客模式开启雷达 //管理员模式优先于游客模式 // 进入游客模式开启雷达 //管理员模式优先于游客模式
if((0x01 == (sys_sta.Pmode | sys_sta.Smode)) && sys_sta.P_Radar_EN){ if((0x01 == (sys_sta.Pmode | sys_sta.Smode)) && sys_sta.P_Radar_EN){
// 根据倒车状态确定雷达ID // 根据倒车状态确定雷达ID
DEBUG("SendCMD:ID=%#02x", SYS_Back_STA ? RADAR_ID_Back : RADAR_ID_Front); DEBUG("SendCMD:ID=%#02x", SYS_Back_STA ? RADAR_ID_Back : RADAR_ID_Front);
app_radar_Sendcmd(SYS_Back_STA ? RADAR_ID_Back : RADAR_ID_Front,RADAR_MODE_Real); app_radar_Sendcmd(SYS_Back_STA ? RADAR_ID_Back : RADAR_ID_Front,RADAR_MODE_Real);
new_state_cnt =3;
radar_CMDSend_cnt++; radar_CMDSend_cnt++;
} }
return _MS(160);//300ms return _MS(140);//300ms
} }
static uint8_t radar_buff[RADAR_BUFF_MAX]; static uint8_t radar_buff[RADAR_BUFF_MAX];

View File

@ -14,9 +14,41 @@ typedef struct BLE_GRB_Data{
uint32_t GRBs; uint32_t GRBs;
} BLE_GRB_Data_t; } BLE_GRB_Data_t;
#define GRB_RED 0x00ff00; #define GRB_RED 0x00ff00
#define GRB_GREEN 0xff0000; #define GRB_GREEN 0xff0000
#define GRB_BLUE 0x0000ff; #define GRB_BLUE 0x0000ff
#define GRB_WHITE 0xffffff
#define GRB_BLACK 0x000000
#define GRB_YELLOW 0xffff00
#define GRB_CYAN 0x00ffff
#define GRB_MAGENTA 0xff00ff
#define GRB_ORANGE 0x2B73F5//0xa5ff00
#define GRB_PURPLE 0x800080
#define GRB_PINK 0xffc0cb
#define GRB_BROWN 0xa52a2a
#define GRB_GRAY 0x808080
#define GRB_LIGHT_BLUE 0xadd8e6
#define GRB_DARK_BLUE 0x00008b
#define GRB_LIGHT_GREEN 0x90ee90
#define GRB_DARK_GREEN 0x006400
#define GRB_LIGHT_RED 0xffc0cb
#define GRB_DARK_RED 0x8b0000
#define GRB_LIGHT_YELLOW 0xffffe0
#define GRB_DARK_YELLOW 0xffa500
#define GRB_LIGHT_CYAN 0xe0ffff
#define GRB_DARK_CYAN 0x008b8b
#define GRB_LIGHT_MAGENTA 0xffa07a
#define GRB_DARK_MAGENTA 0x8b008b
#define GRB_LIGHT_ORANGE 0xffa500
#define GRB_DARK_ORANGE 0xff8c00
#define GRB_LIGHT_PURPLE 0x800080
#define GRB_DARK_PURPLE 0x663399
#define GRB_LIGHT_PINK 0xffc0cb
#define GRB_DARK_PINK 0xff1493
#define GRB_LIGHT_BROWN 0xa52a2a
#define GRB_DARK_BROWN 0x663300
#define GRB_LIGHT_GRAY 0xd3d3d3
#define GRB_DARK_GRAY 0x808080
extern BLE_GRB_Data_t WS2812_GRBs; extern BLE_GRB_Data_t WS2812_GRBs;

View File

@ -16,7 +16,14 @@
// 必须4字节对齐 // 必须4字节对齐
typedef struct SYS_CONF{ typedef struct SYS_CONF{
union{
uint16_t VERSION; // 软件版本号 uint16_t VERSION; // 软件版本号
struct{
uint16_t SW_version:11; // 软件版本序号
uint16_t HW_version:4; // 硬件版本序号
uint16_t VER_type:1; // 当前固件类型00x0400010x20000
};
};
uint8_t Modbus_addr; // MODBUS地址 uint8_t Modbus_addr; // MODBUS地址
uint8_t Manager_sLim; // 管理员模式油门极限(Unit:%) uint8_t Manager_sLim; // 管理员模式油门极限(Unit:%)
uint8_t Tourist_sLim; // 游客模式油门极限 uint8_t Tourist_sLim; // 游客模式油门极限
@ -50,7 +57,14 @@ void conf_init(void);
/**************************系统版本**************************/ /**************************系统版本**************************/
// 软件本号 // 软件本号
#define SOFTWARE_ID 0x0101 #define SW_VERSION (8)
// 硬件本号
#define HW_VERSION (2)
// 版本类型00x0400010x20000//不可修改
#define VER_TYPE ((0x18004000 ==RD_32(0x18000008))?0x0000:0x8000)
#define SOFTWARE_ID (((SW_VERSION & 0x07FF) | ((HW_VERSION & 0x0F)<<11)) & 0x7fff)
#define D_Modbus_addr 0x37 #define D_Modbus_addr 0x37
/************************油门(Unit:%)************************/ /************************油门(Unit:%)************************/
// 管理员模式默认油门极限(0-100%) // 管理员模式默认油门极限(0-100%)