mirror of
https://github.com/silenty4ng/uv-k5-firmware-chinese-lts
synced 2025-03-25 02:46:08 +00:00
增加eeprom说明
This commit is contained in:
parent
c69d3c5a96
commit
9b88dd8771
17 changed files with 471 additions and 348 deletions
61
.idea/workspace.xml
generated
61
.idea/workspace.xml
generated
|
@ -20,11 +20,14 @@
|
||||||
</configurations>
|
</configurations>
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="cea36e80-e289-4d69-9030-7186d540ac0e" name="更改" comment="减少eeprom延时">
|
<list default="true" id="cea36e80-e289-4d69-9030-7186d540ac0e" name="更改" comment="修正MDC联系人地址">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Makefile" beforeDir="false" afterPath="$PROJECT_DIR$/Makefile" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/MDC_WRITE/MDC.txt" beforeDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/main.c" beforeDir="false" afterPath="$PROJECT_DIR$/main.c" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/MDC_WRITE/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/MDC_WRITE/main.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/radio.c" beforeDir="false" afterPath="$PROJECT_DIR$/radio.c" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/ui/menu.c" beforeDir="false" afterPath="$PROJECT_DIR$/ui/menu.c" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ui/menu.h" beforeDir="false" afterPath="$PROJECT_DIR$/ui/menu.h" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/ui/welcome.c" beforeDir="false" afterPath="$PROJECT_DIR$/ui/welcome.c" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/version.c" beforeDir="false" afterPath="$PROJECT_DIR$/version.c" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
@ -73,27 +76,27 @@
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent"><![CDATA[{
|
<component name="PropertiesComponent">{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"ASKED_ADD_EXTERNAL_FILES": "true",
|
"ASKED_ADD_EXTERNAL_FILES": "true",
|
||||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.cidr.known.project.marker": "true",
|
"RunOnceActivity.cidr.known.project.marker": "true",
|
||||||
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
"WebServerToolWindowFactoryState": "false",
|
"WebServerToolWindowFactoryState": "false",
|
||||||
"cf.first.check.clang-format": "false",
|
"cf.first.check.clang-format": "false",
|
||||||
"cidr.known.project.marker": "true",
|
"cidr.known.project.marker": "true",
|
||||||
"last_opened_file_path": "C:/Users/RUPC/Desktop/UV-K6/uv-k5-firmware-chinese",
|
"last_opened_file_path": "C:/Users/RUPC/Desktop/UV-K6/uv-k5-firmware-chinese",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"settings.editor.selected.configurable": "language.cpp.clang-tidy",
|
"settings.editor.selected.configurable": "language.cpp.clang-tidy",
|
||||||
"structure.view.defaults.are.configured": "true",
|
"structure.view.defaults.are.configured": "true",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
}
|
}
|
||||||
}]]></component>
|
}</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
<recent name="C:\Users\RUPC\Desktop\UV-K6\uv-k5-firmware-chinese" />
|
<recent name="C:\Users\RUPC\Desktop\UV-K6\uv-k5-firmware-chinese" />
|
||||||
|
@ -103,7 +106,7 @@
|
||||||
<recent name="C:\Users\RUPC\Desktop\UV-K6\uv-k5-firmware-chinese\app" />
|
<recent name="C:\Users\RUPC\Desktop\UV-K6\uv-k5-firmware-chinese\app" />
|
||||||
</key>
|
</key>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunManager" selected="Makefile 目标.all">
|
<component name="RunManager" selected="Makefile 目标.flash">
|
||||||
<configuration name="all" type="MAKEFILE_TARGET_RUN_CONFIGURATION" factoryName="Makefile" temporary="true">
|
<configuration name="all" type="MAKEFILE_TARGET_RUN_CONFIGURATION" factoryName="Makefile" temporary="true">
|
||||||
<makefile filename="$PROJECT_DIR$/Makefile" target="all" workingDirectory="" arguments="">
|
<makefile filename="$PROJECT_DIR$/Makefile" target="all" workingDirectory="" arguments="">
|
||||||
<envs />
|
<envs />
|
||||||
|
@ -191,10 +194,10 @@
|
||||||
</list>
|
</list>
|
||||||
<recent_temporary>
|
<recent_temporary>
|
||||||
<list>
|
<list>
|
||||||
<item itemvalue="Makefile 目标.all" />
|
|
||||||
<item itemvalue="Makefile 目标.flash" />
|
<item itemvalue="Makefile 目标.flash" />
|
||||||
<item itemvalue="Makefile 目标.clean" />
|
<item itemvalue="Makefile 目标.all" />
|
||||||
<item itemvalue="Makefile 目标.build" />
|
<item itemvalue="Makefile 目标.build" />
|
||||||
|
<item itemvalue="Makefile 目标.clean" />
|
||||||
<item itemvalue="Makefile 目标.debug" />
|
<item itemvalue="Makefile 目标.debug" />
|
||||||
</list>
|
</list>
|
||||||
</recent_temporary>
|
</recent_temporary>
|
||||||
|
@ -264,6 +267,10 @@
|
||||||
<workItem from="1704370562673" duration="1618000" />
|
<workItem from="1704370562673" duration="1618000" />
|
||||||
<workItem from="1704421657950" duration="14943000" />
|
<workItem from="1704421657950" duration="14943000" />
|
||||||
<workItem from="1704442479624" duration="15616000" />
|
<workItem from="1704442479624" duration="15616000" />
|
||||||
|
<workItem from="1704611227205" duration="7887000" />
|
||||||
|
<workItem from="1704636744423" duration="1043000" />
|
||||||
|
<workItem from="1704681883948" duration="331000" />
|
||||||
|
<workItem from="1704682476299" duration="8000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00059" summary="写频">
|
<task id="LOCAL-00059" summary="写频">
|
||||||
<created>1701739409050</created>
|
<created>1701739409050</created>
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
542B BG2FZV UVK6 SB
|
|
||||||
5438 BG2FZV IS A SB
|
|
||||||
4242 I AM SO STUPID
|
|
||||||
2B54 I AM A PIG
|
|
||||||
2B2B PIG I AM HA
|
|
||||||
3838 BG2FZV IS DSB
|
|
||||||
5454 WO SHI SHA BI
|
|
||||||
1234 zhu nao wo shi
|
|
||||||
7890 ~!@#$%^&*()_+/
|
|
||||||
1111 niu bi wo cao
|
|
||||||
2222 sha zi bu hui
|
|
||||||
3333 nao tan
|
|
||||||
4444 chun zhu tou
|
|
||||||
5555 xiao si wo le
|
|
||||||
6666 ji ni tai mei
|
|
|
@ -1,23 +1,14 @@
|
||||||
import sys
|
|
||||||
import serial.tools.list_ports
|
|
||||||
import re
|
|
||||||
import serial
|
import serial
|
||||||
max_contact=15
|
from PyQt5.QtCore import QTimer
|
||||||
line_count=0
|
from PyQt5.QtWidgets import QMainWindow, QPushButton, QFileDialog, QLabel, QRadioButton, QMessageBox, QComboBox, \
|
||||||
MDC_ADD= [ 0x1D48, 0x1D88, 0x1DC8,0x1F08]
|
QProgressBar
|
||||||
MDC_NUM_ADD=0X1D00
|
from PyQt5.QtWidgets import QApplication
|
||||||
file_out="MDC.txt"
|
import sys
|
||||||
|
from PyQt5.QtGui import QImage, QPixmap, QColor
|
||||||
|
resized_image=None
|
||||||
|
cal_bin=1
|
||||||
com_open=""
|
com_open=""
|
||||||
|
pixel_list =[]
|
||||||
|
|
||||||
def payload_xor(payload):
|
|
||||||
XOR_ARRAY = bytes.fromhex('166c14e62e910d402135d5401303e980')
|
|
||||||
XOR_LEN = len(XOR_ARRAY)
|
|
||||||
|
|
||||||
ba=bytearray(payload)
|
|
||||||
for i in range(0,len(ba)):
|
|
||||||
ba[i] ^= XOR_ARRAY[i%XOR_LEN]
|
|
||||||
return bytes(ba)
|
|
||||||
Crc16Tab = [0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 41290, 45419, 49548, 53677, 57806, 61935, 4657, 528, 12915, 8786, 21173, 17044, 29431, 25302,
|
Crc16Tab = [0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 41290, 45419, 49548, 53677, 57806, 61935, 4657, 528, 12915, 8786, 21173, 17044, 29431, 25302,
|
||||||
37689, 33560, 45947, 41818, 54205, 50076, 62463, 58334, 9314, 13379, 1056, 5121, 25830, 29895, 17572, 21637, 42346, 46411, 34088, 38153, 58862, 62927, 50604, 54669, 13907,
|
37689, 33560, 45947, 41818, 54205, 50076, 62463, 58334, 9314, 13379, 1056, 5121, 25830, 29895, 17572, 21637, 42346, 46411, 34088, 38153, 58862, 62927, 50604, 54669, 13907,
|
||||||
9842, 5649, 1584, 30423, 26358, 22165, 18100, 46939, 42874, 38681, 34616, 63455, 59390, 55197, 51132, 18628, 22757, 26758, 30887, 2112, 6241, 10242, 14371, 51660, 55789,
|
9842, 5649, 1584, 30423, 26358, 22165, 18100, 46939, 42874, 38681, 34616, 63455, 59390, 55197, 51132, 18628, 22757, 26758, 30887, 2112, 6241, 10242, 14371, 51660, 55789,
|
||||||
|
@ -30,260 +21,334 @@ Crc16Tab = [0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 4129
|
||||||
6864, 10931, 14994, 64814, 60687, 56684, 52557, 48554, 44427, 40424, 36297, 31782, 27655, 23652, 19525, 15522, 11395, 7392, 3265, 61215, 65342, 53085, 57212, 44955,
|
6864, 10931, 14994, 64814, 60687, 56684, 52557, 48554, 44427, 40424, 36297, 31782, 27655, 23652, 19525, 15522, 11395, 7392, 3265, 61215, 65342, 53085, 57212, 44955,
|
||||||
49082, 36825, 40952, 28183, 32310, 20053, 24180, 11923, 16050, 3793, 7920]
|
49082, 36825, 40952, 28183, 32310, 20053, 24180, 11923, 16050, 3793, 7920]
|
||||||
|
|
||||||
|
class MainWindow(QMainWindow):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
def crc16_ccitt(data):
|
self.initUI()
|
||||||
i2 = 0
|
|
||||||
for i3 in range(0, len(data)):
|
|
||||||
out = Crc16Tab[((i2 >> 8) ^ data[i3]) & 255]
|
|
||||||
i2 = out ^ (i2 << 8)
|
|
||||||
|
|
||||||
return 65535 & i2
|
def initUI(self):
|
||||||
def convert_payload_to_hex(code):
|
global cal_bin
|
||||||
payload_decoded = payload_xor(code[4:-4]) # 跳过头部和尾部的校验信息
|
|
||||||
hex_payload = ' '.join(['{:02X}'.format(byte) for byte in payload_decoded])
|
|
||||||
return hex_payload
|
|
||||||
def check_format(line):
|
|
||||||
pattern = r'^[0-9A-Fa-f]{4}\s[\x20-\x7E]{1,14}$'
|
|
||||||
match = re.match(pattern, line)
|
|
||||||
if match:
|
|
||||||
remaining_chars = 14 - len(match.group(0)) + 5 # 计算还需要多少个字符(14个字符长度减去前面已匹配的字符长度和空格)
|
|
||||||
line = line.rstrip() + ' ' * remaining_chars # 使用空格填充到14个字符长度
|
|
||||||
return line + '\n' # 返回修改后的行,加上换行符
|
|
||||||
else:
|
|
||||||
print("文件格式错误,请仔细阅读示例!")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def update_file(file_path):
|
self.setWindowTitle("Image Processing")
|
||||||
updated_lines = []
|
self.setGeometry(100, 100, 50+50+256, 300)
|
||||||
with open(file_path, 'r') as file:
|
|
||||||
lines = file.readlines()
|
self.open_button = QPushButton("Open Image", self)
|
||||||
for line in lines:
|
self.open_button.setGeometry(20, 20, 100, 30)
|
||||||
updated_line = check_format(line.strip())
|
self.open_button.clicked.connect(self.open_image)
|
||||||
if updated_line is not None:
|
|
||||||
updated_lines.append(updated_line)
|
self.process_button = QPushButton("Process Image", self)
|
||||||
|
self.process_button.setGeometry(20, 70, 120, 30)
|
||||||
|
self.process_button.clicked.connect(self.process_image)
|
||||||
|
self.process_button.setEnabled(False)
|
||||||
|
|
||||||
|
self.label = QLabel(self)
|
||||||
|
self.label.setGeometry(50, 150, 256, 128)
|
||||||
|
|
||||||
|
self.radioButton1 = QRadioButton("效果1", self)
|
||||||
|
self.radioButton2 = QRadioButton("效果2", self)
|
||||||
|
cal_bin = 1
|
||||||
|
self.radioButton1.setGeometry(0, 100, 120, 30)
|
||||||
|
self.radioButton2.setGeometry(50, 100, 120, 30)
|
||||||
|
|
||||||
|
self.radioButton1.setChecked(True) # 默认选中第一个单选按钮
|
||||||
|
|
||||||
|
self.radioButton1.toggled.connect(self.on_radio_button_toggled)
|
||||||
|
self.radioButton2.toggled.connect(self.on_radio_button_toggled)
|
||||||
|
|
||||||
|
self.combo_box = QComboBox(self)
|
||||||
|
self.combo_box.setGeometry(20, 120, 200, 30)
|
||||||
|
self.populate_serial_ports() # Populate available serial ports
|
||||||
|
self.combo_box.currentIndexChanged.connect(self.on_combo_box_changed)
|
||||||
|
|
||||||
|
self.timer = QTimer()
|
||||||
|
self.timer.timeout.connect(self.populate_serial_ports)
|
||||||
|
self.timer.start(500) # Refresh every 5 seconds (1000 milliseconds)
|
||||||
|
|
||||||
|
self.progress_bar = QProgressBar(self)
|
||||||
|
self.progress_bar.setGeometry(50, 150, 200, 20)
|
||||||
|
self.progress_bar.setValue(0)
|
||||||
|
# ... (previous code remains the same)
|
||||||
|
|
||||||
|
from PyQt5.QtWidgets import QComboBox
|
||||||
|
|
||||||
|
class MainWindow(QMainWindow):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.initUI()
|
||||||
|
|
||||||
|
def initUI(self):
|
||||||
|
# ... (existing code)
|
||||||
|
|
||||||
|
self.combo_box = QComboBox(self)
|
||||||
|
self.combo_box.setGeometry(20, 120, 200, 30)
|
||||||
|
self.populate_serial_ports() # Populate available serial ports
|
||||||
|
self.combo_box.currentIndexChanged.connect(self.on_combo_box_changed)
|
||||||
|
|
||||||
|
def populate_serial_ports(self):
|
||||||
|
com_open = self.combo_box.currentText()
|
||||||
|
import serial.tools.list_ports
|
||||||
|
self.combo_box.clear()
|
||||||
|
ports = serial.tools.list_ports.comports()
|
||||||
|
for port in ports:
|
||||||
|
self.combo_box.addItem(port.device)
|
||||||
|
if com_open!="":
|
||||||
|
index = self.combo_box.findText(com_open)
|
||||||
|
if index >= 0:
|
||||||
|
self.combo_box.setCurrentIndex(index)
|
||||||
else:
|
else:
|
||||||
updated_lines.append(line) # 不符合条件的行保持不变
|
com_open = ""
|
||||||
|
|
||||||
# 将修改后的行写回文件
|
def qimage_to_gray_list(self,img):
|
||||||
with open(file_path, 'w') as file:
|
if img.isNull():
|
||||||
file.writelines(updated_lines)
|
return None
|
||||||
|
|
||||||
def check_duplicates(file_path):
|
width = img.width()
|
||||||
lines_seen = set()
|
height = img.height()
|
||||||
line_number = 0
|
|
||||||
|
|
||||||
with open(file_path, 'r') as file:
|
pixel_list = []
|
||||||
for line in file:
|
for y in range(height):
|
||||||
line_number += 1
|
for x in range(width):
|
||||||
first_four = line[:4]
|
gray_value = QColor(img.pixelColor(x, y)).lightness()
|
||||||
if first_four in lines_seen:
|
pixel_list.append(gray_value)
|
||||||
print(f"MDC ID不能重复!!")
|
|
||||||
print(f"重复发现在第 {line_number} 行: {first_four}")
|
|
||||||
input("按 Enter 键退出程序")
|
|
||||||
|
|
||||||
sys.exit()
|
return pixel_list
|
||||||
else:
|
|
||||||
lines_seen.add(first_four)
|
|
||||||
def time_set():
|
|
||||||
global com_open
|
|
||||||
with serial.Serial( com_open, 38400, timeout=1) as ser:
|
|
||||||
|
|
||||||
settime = b'\xAB\xCD\x08\x00\x02\x69\x10\xE6\xAC\xD1\x79\x25\x9D\xAD\xDC\xBA'
|
def on_combo_box_changed(self, index):
|
||||||
ser.write(settime)
|
|
||||||
full_response = ser.read(128)
|
|
||||||
if len(full_response) == 0:
|
|
||||||
print("连接失败!")
|
|
||||||
input("按 Enter 键退出程序")
|
|
||||||
|
|
||||||
sys.exit()
|
|
||||||
def read_eeprom_byte(add):
|
|
||||||
global com_open
|
|
||||||
with serial.Serial(com_open, 38400, timeout=1) as ser:
|
|
||||||
payload = b'\x1B\x05' + b'\x08\x00' + add.to_bytes(2, byteorder='little') + b'\x11\x00' + b'\x82\x40\x74\x65'
|
|
||||||
# 将 payload 中的最后四个字节替换为当前时间戳
|
|
||||||
hex_string = ' '.join(['{:02X}'.format(byte) for byte in payload])
|
|
||||||
crc = crc16_ccitt(payload)
|
|
||||||
payload = payload + bytes([crc & 0xFF, ]) + bytes([crc >> 8, ]) # swap bytes of crc to get little endian
|
|
||||||
message = b'\xAB\xCD' + b'\x0C\x00' + payload_xor(payload) + b'\xDC\xBA'
|
|
||||||
ser.write(message)
|
|
||||||
full_response = ser.read(128)
|
|
||||||
if len(full_response) == 0:
|
|
||||||
print("读取失败!")
|
|
||||||
input("按 Enter 键退出程序")
|
|
||||||
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
full_response_hex = full_response.hex()
|
|
||||||
# 将16进制字符串转换为字节串
|
|
||||||
full_response = bytes.fromhex(full_response_hex)
|
|
||||||
# 对payload部分进行解码,然后以两位十六进制输出
|
|
||||||
|
|
||||||
payload_decoded = convert_payload_to_hex(full_response)
|
|
||||||
return payload_decoded[24:26]
|
|
||||||
def read_eeprom():
|
|
||||||
num_contact = int( read_eeprom_byte(MDC_NUM_ADD), 16)
|
|
||||||
if num_contact==0 or num_contact>max_contact:
|
|
||||||
print("手台并无设置联系人,请先写入联系人!")
|
|
||||||
input("按 Enter 键退出程序")
|
|
||||||
|
|
||||||
sys.exit()
|
|
||||||
print("开始读取MDC联系人")
|
|
||||||
with open(file_out, 'w+') as file:
|
|
||||||
global com_open
|
global com_open
|
||||||
with serial.Serial(com_open, 38400, timeout=1) as ser:
|
com_open = self.combo_box.currentText()
|
||||||
a=0
|
|
||||||
while a<num_contact:
|
# Debugging: print selected serial port
|
||||||
add=MDC_ADD[a//4]+(a%4)*16
|
print(f"Selected port: {com_open}")
|
||||||
a=a+1
|
def on_radio_button_toggled(self):
|
||||||
print(a*100/num_contact,end='%\n')
|
global cal_bin
|
||||||
payload = b'\x1B\x05' + b'\x08\x00' +add.to_bytes(2, byteorder='little')+b'\x10\x00'+b'\x82\x40\x74\x65'
|
global resized_image
|
||||||
# 将 payload 中的最后四个字节替换为当前时间戳
|
global pixel_list
|
||||||
hex_string = ' '.join(['{:02X}'.format(byte) for byte in payload])
|
|
||||||
crc = crc16_ccitt(payload)
|
sender = self.sender()
|
||||||
payload = payload + bytes([crc & 0xFF,]) + bytes([crc>>8,]) #swap bytes of crc to get little endian
|
|
||||||
message = b'\xAB\xCD' + b'\x0C\x00' + payload_xor(payload) + b'\xDC\xBA'
|
if sender.isChecked():
|
||||||
ser.write(message)
|
if sender == self.radioButton1:
|
||||||
|
self.radioButton2.setChecked(False)
|
||||||
|
if self.process_button.isEnabled() and cal_bin == 2:
|
||||||
|
binarized_image = self.binarize_image1(resized_image)
|
||||||
|
pixel_list=self.qimage_to_gray_list(binarized_image)
|
||||||
|
self.show_img(binarized_image)
|
||||||
|
cal_bin=1
|
||||||
|
else:
|
||||||
|
self.radioButton1.setChecked(False)
|
||||||
|
if self.process_button.isEnabled() and cal_bin == 1:
|
||||||
|
binarized_image = self.binarize_image2(resized_image)
|
||||||
|
pixel_list=self.qimage_to_gray_list(binarized_image)
|
||||||
|
self.show_img(binarized_image)
|
||||||
|
cal_bin=2
|
||||||
|
def open_image(self):
|
||||||
|
global resized_image
|
||||||
|
global cal_bin
|
||||||
|
global pixel_list
|
||||||
|
|
||||||
|
options = QFileDialog.Options()
|
||||||
|
file_path, _ = QFileDialog.getOpenFileName(self, "Open Image File", "", "Image Files (*.jpg *.png *.bmp *.jpeg)",
|
||||||
|
options=options)
|
||||||
|
if file_path:
|
||||||
|
self.image_path = file_path
|
||||||
|
self.process_button.setEnabled(True)
|
||||||
|
try:
|
||||||
|
original_image = QImage(self.image_path)
|
||||||
|
resized_image = self.resize_image_qimage(original_image, 128, 64)
|
||||||
|
if cal_bin==1:
|
||||||
|
binarized_image = self.binarize_image1(resized_image)
|
||||||
|
else:
|
||||||
|
binarized_image = self.binarize_image2(resized_image)
|
||||||
|
|
||||||
|
#binarized_image.save("C:/Users/RUPC/Desktop/3.jpg")
|
||||||
|
pixel_list=self.qimage_to_gray_list(binarized_image)
|
||||||
|
self.show_img(binarized_image)
|
||||||
|
|
||||||
|
|
||||||
|
# 设置 label 为主窗口的中央部件
|
||||||
|
# self.setCentralWidget(label)
|
||||||
|
except Exception as e:
|
||||||
|
print("Exception occurred:", str(e))
|
||||||
|
|
||||||
|
def process_image(self):
|
||||||
|
global pixel_list
|
||||||
|
global com_open
|
||||||
|
|
||||||
|
self.disable_all_widgets()
|
||||||
|
if self.time_set()==False:
|
||||||
|
self.enable_all_widgets()
|
||||||
|
self.progress_bar.setValue(0)
|
||||||
|
|
||||||
|
return False
|
||||||
|
add=0x1E320
|
||||||
|
num=128
|
||||||
|
self.progress_bar.setValue(20)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with serial.Serial(com_open, 38400, timeout=1) as ser:
|
||||||
|
pass
|
||||||
|
for i in range(8):
|
||||||
|
add1=add-0x10000
|
||||||
|
payload = b'\x38\x05' + b'\x8A\x00' + b'\x01\x00' + b'\x82\x00' + b'\x82\x40\x74\x65' + add1.to_bytes(2, byteorder='little')
|
||||||
|
for value in pixel_list[i*128:i*128+128]:
|
||||||
|
payload += value.to_bytes(1, byteorder='big') # 转换为字节并添加到 payload
|
||||||
|
|
||||||
|
# 将 payload 中的最后四个字节替换为当前时间戳
|
||||||
|
crc = self.crc16_ccitt(payload)
|
||||||
|
payload = payload + bytes([crc & 0xFF, ]) + bytes([crc >> 8, ]) # swap bytes of crc to get little endian
|
||||||
|
|
||||||
|
message = b'\xAB\xCD' + b'\x8e\x00' + self.payload_xor(payload) + b'\xDC\xBA'
|
||||||
|
hex_payload = ' '.join(hex(byte) for byte in message)
|
||||||
|
print(hex_payload)
|
||||||
|
ser.write(message)
|
||||||
|
full_response = ser.read(128)
|
||||||
|
if len(full_response) == 0:
|
||||||
|
self.message('写入失败')
|
||||||
|
self.progress_bar.setValue(0)
|
||||||
|
self.enable_all_widgets()
|
||||||
|
return False;
|
||||||
|
add=add+128
|
||||||
|
self.progress_bar.setValue(20+(i+1)*10)
|
||||||
|
self.message('写入成功')
|
||||||
|
self.progress_bar.setValue(0)
|
||||||
|
self.enable_all_widgets()
|
||||||
|
|
||||||
|
|
||||||
|
except serial.SerialException:
|
||||||
|
self.self.message('写入失败')
|
||||||
|
self.progress_bar.setValue(0)
|
||||||
|
self.enable_all_widgets()
|
||||||
|
return False;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def disable_all_widgets(self):
|
||||||
|
for widget in self.findChildren((QComboBox, QPushButton,QRadioButton)):
|
||||||
|
widget.setEnabled(False)
|
||||||
|
|
||||||
|
def enable_all_widgets(self):
|
||||||
|
for widget in self.findChildren((QComboBox, QPushButton,QRadioButton)):
|
||||||
|
widget.setEnabled(True)
|
||||||
|
def show_img(self,binarized_image):
|
||||||
|
pixmap = QPixmap.fromImage(self.resize_image_qimage(binarized_image, 256, 128))
|
||||||
|
self.label.setPixmap(pixmap)
|
||||||
|
def binarize_image1(self, original_image):
|
||||||
|
binarized_image = original_image.convertToFormat(QImage.Format_Mono)
|
||||||
|
return binarized_image
|
||||||
|
|
||||||
|
def otsu_threshold(self,qimage):
|
||||||
|
# Convert QImage to grayscale
|
||||||
|
gray_qimage = qimage.convertToFormat(QImage.Format_Grayscale8)
|
||||||
|
|
||||||
|
# Calculate histogram
|
||||||
|
histogram = [0] * 256
|
||||||
|
total_pixels = gray_qimage.width() * gray_qimage.height()
|
||||||
|
|
||||||
|
for y in range(gray_qimage.height()):
|
||||||
|
for x in range(gray_qimage.width()):
|
||||||
|
pixel = QColor(gray_qimage.pixel(x, y))
|
||||||
|
histogram[pixel.red()] += 1
|
||||||
|
|
||||||
|
# Compute Otsu's threshold
|
||||||
|
sum_total = 0
|
||||||
|
for i in range(256):
|
||||||
|
sum_total += i * histogram[i]
|
||||||
|
|
||||||
|
sumB = 0
|
||||||
|
wB = 0
|
||||||
|
maximum = 0.0
|
||||||
|
threshold = 0
|
||||||
|
|
||||||
|
for i in range(256):
|
||||||
|
wB += histogram[i]
|
||||||
|
if wB == 0:
|
||||||
|
continue
|
||||||
|
wF = total_pixels - wB
|
||||||
|
if wF == 0:
|
||||||
|
break
|
||||||
|
sumB += i * histogram[i]
|
||||||
|
mB = sumB / wB
|
||||||
|
mF = (sum_total - sumB) / wF
|
||||||
|
between = wB * wF * (mB - mF) * (mB - mF)
|
||||||
|
if between >= maximum:
|
||||||
|
threshold = i
|
||||||
|
maximum = between
|
||||||
|
|
||||||
|
return threshold
|
||||||
|
def binarize_image2(self, qimage):
|
||||||
|
threshold = self.otsu_threshold(qimage)
|
||||||
|
|
||||||
|
# Convert QImage to grayscale
|
||||||
|
gray_qimage = qimage.convertToFormat(QImage.Format_Grayscale8)
|
||||||
|
|
||||||
|
# Apply Otsu's thresholding
|
||||||
|
for y in range(gray_qimage.height()):
|
||||||
|
for x in range(gray_qimage.width()):
|
||||||
|
pixel = QColor(gray_qimage.pixel(x, y))
|
||||||
|
if pixel.red() > threshold:
|
||||||
|
gray_qimage.setPixel(x, y, QColor(255, 255, 255).rgb()) # White pixel
|
||||||
|
else:
|
||||||
|
gray_qimage.setPixel(x, y, QColor(0, 0, 0).rgb()) # Black pixel
|
||||||
|
|
||||||
|
return gray_qimage
|
||||||
|
|
||||||
|
def resize_image_qimage(self, image,width,high):
|
||||||
|
|
||||||
|
|
||||||
|
# 缩放图像
|
||||||
|
resized_image = image.scaled(width, high)
|
||||||
|
|
||||||
|
return resized_image
|
||||||
|
|
||||||
|
def payload_xor(self,payload):
|
||||||
|
XOR_ARRAY = bytes.fromhex('166c14e62e910d402135d5401303e980')
|
||||||
|
XOR_LEN = len(XOR_ARRAY)
|
||||||
|
|
||||||
|
ba = bytearray(payload)
|
||||||
|
for i in range(0, len(ba)):
|
||||||
|
ba[i] ^= XOR_ARRAY[i % XOR_LEN]
|
||||||
|
return bytes(ba)
|
||||||
|
|
||||||
|
def crc16_ccitt(self,data):
|
||||||
|
i2 = 0
|
||||||
|
for i3 in range(0, len(data)):
|
||||||
|
out = Crc16Tab[((i2 >> 8) ^ data[i3]) & 255]
|
||||||
|
i2 = out ^ (i2 << 8)
|
||||||
|
|
||||||
|
return 65535 & i2
|
||||||
|
|
||||||
|
def convert_payload_to_hex(self,code):
|
||||||
|
payload_decoded = self.payload_xor(code[4:-4]) # 跳过头部和尾部的校验信息
|
||||||
|
hex_payload = ' '.join(['{:02X}'.format(byte) for byte in payload_decoded])
|
||||||
|
return hex_payload
|
||||||
|
def message(self,text):
|
||||||
|
msg_box = QMessageBox()
|
||||||
|
msg_box.setWindowTitle("提示")
|
||||||
|
msg_box.setText(text)
|
||||||
|
msg_box.setIcon(QMessageBox.Critical)
|
||||||
|
msg_box.setStandardButtons(QMessageBox.Ok)
|
||||||
|
msg_box.exec()
|
||||||
|
def time_set(self):
|
||||||
|
global com_open
|
||||||
|
try:
|
||||||
|
with serial.Serial(com_open, 38400, timeout=1) as ser:
|
||||||
|
settime = b'\xAB\xCD\x08\x00\x02\x69\x10\xE6\xAC\xD1\x79\x25\x9D\xAD\xDC\xBA'
|
||||||
|
ser.write(settime)
|
||||||
full_response = ser.read(128)
|
full_response = ser.read(128)
|
||||||
if len(full_response) == 0:
|
if len(full_response) == 0:
|
||||||
print("读取失败!")
|
self.populate_serial_ports() # Populate available serial ports
|
||||||
input("按 Enter 键退出程序")
|
self.message("连接失败")
|
||||||
|
return False # Connection failed due to exception
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
full_response_hex = full_response.hex()
|
|
||||||
# 将16进制字符串转换为字节串
|
|
||||||
full_response = bytes.fromhex(full_response_hex)
|
|
||||||
# 对payload部分进行解码,然后以两位十六进制输出
|
|
||||||
|
|
||||||
payload_decoded = convert_payload_to_hex(full_response)
|
|
||||||
i=0
|
|
||||||
# 将print的输出定向到文件中
|
|
||||||
for element in payload_decoded.split(' ')[8:]:
|
|
||||||
i = i + 1
|
|
||||||
if i == 3:
|
|
||||||
file.write(' ')
|
|
||||||
if i >= 3:
|
|
||||||
file.write(chr(int(element, 16)))
|
|
||||||
else:
|
|
||||||
file.write(element.upper())
|
|
||||||
file.write('\n')
|
|
||||||
print("读取成功,联系人保存至 MDC.txt")
|
|
||||||
return True
|
|
||||||
def write_eeprom_byte(add,num):
|
|
||||||
global com_open
|
|
||||||
with serial.Serial(com_open, 38400, timeout=1) as ser:
|
|
||||||
payload = b'\x1D\x05' + b'\x09\x00' + add.to_bytes(2,
|
|
||||||
byteorder='little') + b'\x0F\x00' + b'\x82\x40\x74\x65' + num.to_bytes(1, byteorder='big')
|
|
||||||
# 将 payload 中的最后四个字节替换为当前时间戳
|
|
||||||
crc = crc16_ccitt(payload)
|
|
||||||
payload = payload + bytes([crc & 0xFF, ]) + bytes([crc >> 8, ]) # swap bytes of crc to get little endian
|
|
||||||
message = b'\xAB\xCD' + b'\x0D\x00' + payload_xor(payload) + b'\xDC\xBA'
|
|
||||||
ser.write(message)
|
|
||||||
|
|
||||||
full_response = ser.read(128)
|
|
||||||
if len(full_response) == 0:
|
|
||||||
print("写入失败!")
|
|
||||||
input("按 Enter 键退出程序")
|
|
||||||
|
|
||||||
sys.exit()
|
|
||||||
def write_eeprom_select(a,my_str):
|
|
||||||
global com_open
|
|
||||||
with serial.Serial(com_open, 38400, timeout=1) as ser:
|
|
||||||
add = MDC_ADD[a // 4] + (a % 4) * 16
|
|
||||||
payload_data = ''.join(my_str).encode('utf-8')
|
|
||||||
hex1 = int(payload_data[0:2], 16)
|
|
||||||
hex2 = int(payload_data[2:4], 16)
|
|
||||||
payload_data = bytearray([hex1, hex2]) + payload_data[5:]
|
|
||||||
payload = b'\x1D\x05' + b'\x18\x00' + add.to_bytes(2,
|
|
||||||
byteorder='little') + b'\x10\x00' + b'\x82\x40\x74\x65' + payload_data
|
|
||||||
# 将 payload 中的最后四个字节替换为当前时间戳
|
|
||||||
crc = crc16_ccitt(payload)
|
|
||||||
payload = payload + bytes([crc & 0xFF, ]) + bytes([crc >> 8, ]) # swap bytes of crc to get little endian
|
|
||||||
message = b'\xAB\xCD' + b'\x1C\x00' + payload_xor(payload) + b'\xDC\xBA'
|
|
||||||
ser.write(message)
|
|
||||||
|
|
||||||
full_response = ser.read(128)
|
|
||||||
if len(full_response) == 0:
|
|
||||||
print("写入失败!")
|
|
||||||
input("按 Enter 键退出程序")
|
|
||||||
|
|
||||||
sys.exit()
|
|
||||||
def deal_blank_line():
|
|
||||||
global line_count # 声明 line_count 是全局变量
|
|
||||||
with open(file_out, 'r') as file:
|
|
||||||
lines = file.readlines()
|
|
||||||
with open(file_out, 'w') as file:
|
|
||||||
for line in lines:
|
|
||||||
if line.strip():
|
|
||||||
file.write(line)
|
|
||||||
with open(file_out, 'r') as file:
|
|
||||||
line_count = sum(1 for line in file)
|
|
||||||
if line_count==0:
|
|
||||||
print("请填写MDC联系人!")
|
|
||||||
input("按 Enter 键退出程序")
|
|
||||||
|
|
||||||
sys.exit()
|
|
||||||
elif line_count>max_contact:
|
|
||||||
print("MDC联系人数量最大为",max_contact)
|
|
||||||
|
|
||||||
|
|
||||||
def write_eeprom():
|
|
||||||
print("正在将MDC.txt写入到手台中")
|
|
||||||
global line_count # 声明 line_count 是全局变量
|
|
||||||
a=0
|
|
||||||
deal_blank_line()
|
|
||||||
update_file(file_out)
|
|
||||||
with open(file_out, 'r') as file:
|
|
||||||
for line in file:
|
|
||||||
add = MDC_ADD[a // 4] + (a % 4) * 16
|
|
||||||
my_str = []
|
|
||||||
my_str.append(line.replace('\n', '')) # 去除行尾的换行符
|
|
||||||
write_eeprom_select(a,my_str)
|
|
||||||
print((a+1) * 100 / line_count, end='%\n')
|
|
||||||
a = a + 1
|
|
||||||
if a==line_count:
|
|
||||||
break
|
|
||||||
|
|
||||||
write_eeprom_byte(MDC_NUM_ADD,line_count)
|
|
||||||
print("写入成功")
|
|
||||||
return True
|
|
||||||
|
|
||||||
# def main():
|
|
||||||
|
|
||||||
|
except serial.SerialException:
|
||||||
|
self.message("连接失败")
|
||||||
|
|
||||||
|
return False # Connection failed due to exception
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
available_ports = list(serial.tools.list_ports.comports())
|
app = QApplication(sys.argv)
|
||||||
|
window = MainWindow()
|
||||||
if available_ports:
|
window.show()
|
||||||
print("可用串口:")
|
sys.exit(app.exec_())
|
||||||
for port in available_ports:
|
|
||||||
print(port.device)
|
|
||||||
else:
|
|
||||||
print("没有发现可用串口。")
|
|
||||||
com_open=input("输入串口(例:COM4):")
|
|
||||||
value=-1
|
|
||||||
print("第一次使用MDC联系人请先写入联系人!!")
|
|
||||||
while value!=0 and value!=1:
|
|
||||||
value = int(input("写入(0)或读取(1)联系人:")) # 获取用户输入的整数值
|
|
||||||
|
|
||||||
if value == 0:
|
|
||||||
time_set()
|
|
||||||
write_eeprom()
|
|
||||||
elif value == 1:
|
|
||||||
time_set()
|
|
||||||
read_eeprom()
|
|
||||||
else:
|
|
||||||
value = int(input("输入无效!\n输入(0/1)来(写入/读取)联系人:")) # 获取用户输入的整数值
|
|
||||||
input("按 Enter 键退出程序")
|
|
||||||
|
|
||||||
# main()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# code =[0xAB,0xCD,0x6C,0x00,0x0B,0x69,0x7C,0xE6,0x5E,0x9F,0x6D,0x41,0xBF,0x61,0xA1,0x25,0x13,0x02,0xE8,0x80,0x16,0x93,0x15,0xE2,0xD1,0x91,0x0D,0x44,0x20,0x36,0xD5,0x41,0x13,0x03,0x24,0x80,0x16,0xA1,0xDB,0x29,0xD1,0x6E,0x0D,0x40,0xDE,0xCA,0x2A,0xBF,0x13,0x00,0xE1,0x80,0x16,0x6D,0x14,0xE6,0xD1,0x6E,0xF2,0xBF,0xDE,0xCA,0x2A,0xBF,0x12,0x03,0x16,0x7F,0xE9,0x93,0xEB,0x19,0x2E,0x91,0x0D,0x40,0xDE,0xCA,0x2A,0xBF,0x42,0x56,0xA8,0xCE,0x45,0x24,0x51,0xA8,0x69,0x91,0x0D,0x40,0x21,0x35,0xD5,0x40,0x46,0x55,0xC4,0xCB,0x23,0x6C,0x14,0xE6,0x2E,0x91,0x0D,0x40,0x21,0x35,0xD5,0x40,0x79,0x5A,0xDC,0xBA]
|
|
||||||
# # code=[0xAB, 0xCD, 0x1C, 0x00, 0x0B, 0x69, 0x0C, 0xE6, 0xCE, 0x80, 0x1D, 0x40, 0xBF, 0x61, 0xA1, 0x25, 0xEC, 0xFC, 0x16, 0x7F, 0xE9, 0x93, 0xEB, 0x19, 0xD1, 0x6E, 0xF2, 0xBF, 0xDE, 0xCA, 0x2A, 0xBF, 0xCF, 0x04, 0xDC, 0xBA]
|
|
||||||
# payload_decoded = convert_payload_to_hex(code) # 跳过头部和尾部的校验信息
|
|
||||||
# hex_payload = ' '.join(['{:02X}'.format(byte) for byte in payload_decoded])
|
|
||||||
# print(hex_payload)
|
|
||||||
|
|
||||||
|
|
12
README.md
12
README.md
|
@ -59,6 +59,18 @@
|
||||||
* 使用 EXIT 停止扫描时还原初始频率/频道,使用 MENU 按钮记住上次找到的传输
|
* 使用 EXIT 停止扫描时还原初始频率/频道,使用 MENU 按钮记住上次找到的传输
|
||||||
|
|
||||||
|
|
||||||
|
# Eeprom分布说明:
|
||||||
|
* **前8K**基本不变
|
||||||
|
* **0X1D00~0X1E00、0X1F90~0X1FF0** 22个MDC联系人,**0X1FFF**存放联系人数量
|
||||||
|
* **0X0E92、0X0E91** MDC联系人高低8bit
|
||||||
|
*
|
||||||
|
**扩容版(K)**:
|
||||||
|
* **0x2000~1E31C** 中文字库(三个字库大小为:40960、40960、33564)
|
||||||
|
* **0x1E320~0x1E332** 开机字符1 ,**1xE31E** 存放长度
|
||||||
|
* **0x1E333~0x1E345** 开机字符2 ,**0x1E31F** 存放长度
|
||||||
|
* **0x1E350~0X1E450** 开机画面
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 示例
|
# 示例
|
||||||
|
|
||||||
|
|
29
app/menu.c
29
app/menu.c
|
@ -184,12 +184,13 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax) {
|
||||||
*pMin = 0;
|
*pMin = 0;
|
||||||
*pMax = ARRAY_SIZE(gSubMenu_ROGER) - 1;
|
*pMax = ARRAY_SIZE(gSubMenu_ROGER) - 1;
|
||||||
break;
|
break;
|
||||||
|
#if ENABLE_CHINESE_FULL==4
|
||||||
|
|
||||||
// case MENU_PONMSG:
|
case MENU_PONMSG:
|
||||||
// *pMin = 0;
|
*pMin = 0;
|
||||||
// *pMax = ARRAY_SIZE(gSubMenu_OFF_ON) - 1;
|
*pMax = ARRAY_SIZE(gSubMenu_PONMSG) - 1;
|
||||||
// break;
|
break;
|
||||||
|
#endif
|
||||||
case MENU_R_DCS:
|
case MENU_R_DCS:
|
||||||
case MENU_T_DCS:
|
case MENU_T_DCS:
|
||||||
*pMin = 0;
|
*pMin = 0;
|
||||||
|
@ -697,10 +698,12 @@ void MENU_AcceptSetting(void) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
// case MENU_PONMSG:
|
#if ENABLE_CHINESE_FULL==4
|
||||||
// gEeprom.POWER_ON_DISPLAY_MODE = gSubMenuSelection;
|
|
||||||
// break;
|
|
||||||
|
|
||||||
|
case MENU_PONMSG:
|
||||||
|
gEeprom.POWER_ON_DISPLAY_MODE = gSubMenuSelection;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case MENU_ROGER:
|
case MENU_ROGER:
|
||||||
gEeprom.ROGER = gSubMenuSelection;
|
gEeprom.ROGER = gSubMenuSelection;
|
||||||
break;
|
break;
|
||||||
|
@ -1076,11 +1079,11 @@ void MENU_ShowCurrentSetting(void) {
|
||||||
case MENU_D_LIVE_DEC:
|
case MENU_D_LIVE_DEC:
|
||||||
gSubMenuSelection = gSetting_live_DTMF_decoder;
|
gSubMenuSelection = gSetting_live_DTMF_decoder;
|
||||||
break;
|
break;
|
||||||
|
#if ENABLE_CHINESE_FULL==4
|
||||||
// case MENU_PONMSG:
|
case MENU_PONMSG:
|
||||||
// gSubMenuSelection = gEeprom.POWER_ON_DISPLAY_MODE;
|
gSubMenuSelection = gEeprom.POWER_ON_DISPLAY_MODE;
|
||||||
// break;
|
break;
|
||||||
|
#endif
|
||||||
case MENU_ROGER:
|
case MENU_ROGER:
|
||||||
gSubMenuSelection = gEeprom.ROGER;
|
gSubMenuSelection = gEeprom.ROGER;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -170,6 +170,7 @@
|
||||||
#define 省电模式 "\x88\xD1\x81\x1C\x95\xE1\x81\xAA"
|
#define 省电模式 "\x88\xD1\x81\x1C\x95\xE1\x81\xAA"
|
||||||
#define 麦克风增益 "\x83\x05\x83\x70\x80\xAE\x97\x51\x8D\x26"
|
#define 麦克风增益 "\x83\x05\x83\x70\x80\xAE\x97\x51\x8D\x26"
|
||||||
#define 信道显示模式 "\x89\x89\x92\xC8\x88\xE5\x80\xDF\x95\xE1\x81\xAA"
|
#define 信道显示模式 "\x89\x89\x92\xC8\x88\xE5\x80\xDF\x95\xE1\x81\xAA"
|
||||||
|
#define 开机显示 "\x80\x56\x81\xD9\x88\xE5\x80\xDF"
|
||||||
#define 自动背光 "\x82\x5B\x81\xAF\x88\xC8\x82\x08"
|
#define 自动背光 "\x82\x5B\x81\xAF\x88\xC8\x82\x08"
|
||||||
#define 背光亮度 "\x88\xC8\x82\x08\x89\xEA\x89\xEC"
|
#define 背光亮度 "\x88\xC8\x82\x08\x89\xEA\x89\xEC"
|
||||||
#define 首尾音 "\x8A\x1E\x84\xE1\x8A\x01"
|
#define 首尾音 "\x8A\x1E\x84\xE1\x8A\x01"
|
||||||
|
@ -273,6 +274,8 @@
|
||||||
#define 模拟亚音 "\x95\xE1\x83\x48\x81\xD2\x8A\x01"
|
#define 模拟亚音 "\x95\xE1\x83\x48\x81\xD2\x8A\x01"
|
||||||
#define 数字亚音 "\x95\x19\x82\xBB\x81\xD2\x8A\x01"
|
#define 数字亚音 "\x95\x19\x82\xBB\x81\xD2\x8A\x01"
|
||||||
|
|
||||||
|
#define 图片 "\x86\x4C\x80\x92"
|
||||||
|
#define 信息 "\x89\x89\x8C\x8C"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif //UV_K5_FIRMWARE_CUSTOM_0_17_CHINESE_H
|
#endif //UV_K5_FIRMWARE_CUSTOM_0_17_CHINESE_H
|
||||||
|
|
10
main.c
10
main.c
|
@ -293,7 +293,7 @@ void Main(void) {
|
||||||
//BootMode = BOOT_GetMode();
|
//BootMode = BOOT_GetMode();
|
||||||
|
|
||||||
// if (BootMode == BOOT_MODE_F_LOCK)
|
// if (BootMode == BOOT_MODE_F_LOCK)
|
||||||
gMenuListCount = 45;
|
gMenuListCount = 46;
|
||||||
|
|
||||||
|
|
||||||
// wait for user to release all butts before moving on
|
// wait for user to release all butts before moving on
|
||||||
|
@ -316,8 +316,14 @@ void Main(void) {
|
||||||
UI_DisplayWelcome();
|
UI_DisplayWelcome();
|
||||||
|
|
||||||
boot_counter_10ms = 250;
|
boot_counter_10ms = 250;
|
||||||
|
|
||||||
while (boot_counter_10ms > 0) {
|
while (boot_counter_10ms > 0) {
|
||||||
if (KEYBOARD_Poll() == KEY_EXIT) { // halt boot beeps
|
|
||||||
|
if (KEYBOARD_Poll() == KEY_EXIT
|
||||||
|
#if ENABLE_CHINESE_FULL==4
|
||||||
|
||gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE
|
||||||
|
#endif
|
||||||
|
) { // halt boot beeps
|
||||||
boot_counter_10ms = 0;
|
boot_counter_10ms = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,8 +120,9 @@ void SETTINGS_InitEEPROM(void)
|
||||||
// gEeprom.KEY_2_LONG_PRESS_ACTION = (Data[4] < ACTION_OPT_LEN) ? Data[4] : ACTION_OPT_NONE;
|
// gEeprom.KEY_2_LONG_PRESS_ACTION = (Data[4] < ACTION_OPT_LEN) ? Data[4] : ACTION_OPT_NONE;
|
||||||
gEeprom.SCAN_RESUME_MODE = (Data[5] < 3) ? Data[5] : SCAN_RESUME_CO;
|
gEeprom.SCAN_RESUME_MODE = (Data[5] < 3) ? Data[5] : SCAN_RESUME_CO;
|
||||||
// gEeprom.AUTO_KEYPAD_LOCK = (Data[6] < 2) ? Data[6] : false;
|
// gEeprom.AUTO_KEYPAD_LOCK = (Data[6] < 2) ? Data[6] : false;
|
||||||
// gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 4) ? Data[7] : POWER_ON_DISPLAY_MODE_MESSAGE;
|
#if ENABLE_CHINESE_FULL==4
|
||||||
|
gEeprom.POWER_ON_DISPLAY_MODE = (Data[7] < 4) ? Data[7] : POWER_ON_DISPLAY_MODE_NONE;
|
||||||
|
#endif
|
||||||
// 0E98..0E9F
|
// 0E98..0E9F
|
||||||
EEPROM_ReadBuffer(0x0E98, Data, 8);
|
EEPROM_ReadBuffer(0x0E98, Data, 8);
|
||||||
memcpy(&gEeprom.POWER_ON_PASSWORD, Data, 4);
|
memcpy(&gEeprom.POWER_ON_PASSWORD, Data, 4);
|
||||||
|
@ -537,7 +538,9 @@ void SETTINGS_SaveSettings(void)
|
||||||
State[4] = 0;//gEeprom.KEY_2_LONG_PRESS_ACTION;
|
State[4] = 0;//gEeprom.KEY_2_LONG_PRESS_ACTION;
|
||||||
State[5] = gEeprom.SCAN_RESUME_MODE;
|
State[5] = gEeprom.SCAN_RESUME_MODE;
|
||||||
State[6] = 0;//gEeprom.AUTO_KEYPAD_LOCK;
|
State[6] = 0;//gEeprom.AUTO_KEYPAD_LOCK;
|
||||||
State[7] = 0;//gEeprom.POWER_ON_DISPLAY_MODE;
|
#if ENABLE_CHINESE_FULL==4
|
||||||
|
State[7] = gEeprom.POWER_ON_DISPLAY_MODE;
|
||||||
|
#endif
|
||||||
EEPROM_WriteBuffer(0x0E90, State,8);
|
EEPROM_WriteBuffer(0x0E90, State,8);
|
||||||
|
|
||||||
memset(Password, 0xFF, sizeof(Password));
|
memset(Password, 0xFF, sizeof(Password));
|
||||||
|
|
18
settings.h
18
settings.h
|
@ -24,14 +24,16 @@
|
||||||
#include <helper/battery.h>
|
#include <helper/battery.h>
|
||||||
#include "radio.h"
|
#include "radio.h"
|
||||||
#include <driver/backlight.h>
|
#include <driver/backlight.h>
|
||||||
|
#if ENABLE_CHINESE_FULL==4
|
||||||
|
|
||||||
//enum POWER_OnDisplayMode_t {
|
enum POWER_OnDisplayMode_t {
|
||||||
// POWER_ON_DISPLAY_MODE_NONE
|
POWER_ON_DISPLAY_MODE_NONE,
|
||||||
//,
|
POWER_ON_DISPLAY_MODE_PIC,
|
||||||
// POWER_ON_DISPLAY_MODE_MESSAGE,
|
POWER_ON_DISPLAY_MODE_MESSAGE
|
||||||
//};
|
|
||||||
|
};
|
||||||
typedef enum POWER_OnDisplayMode_t POWER_OnDisplayMode_t;
|
typedef enum POWER_OnDisplayMode_t POWER_OnDisplayMode_t;
|
||||||
|
#endif
|
||||||
enum TxLockModes_t {
|
enum TxLockModes_t {
|
||||||
F_LOCK_DEF, //all default frequencies + configurable
|
F_LOCK_DEF, //all default frequencies + configurable
|
||||||
F_LOCK_FCC,
|
F_LOCK_FCC,
|
||||||
|
@ -189,7 +191,9 @@ typedef struct {
|
||||||
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
|
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
|
||||||
ALARM_Mode_t ALARM_MODE;
|
ALARM_Mode_t ALARM_MODE;
|
||||||
#endif
|
#endif
|
||||||
// POWER_OnDisplayMode_t POWER_ON_DISPLAY_MODE;
|
#if ENABLE_CHINESE_FULL==4
|
||||||
|
POWER_OnDisplayMode_t POWER_ON_DISPLAY_MODE;
|
||||||
|
#endif
|
||||||
ROGER_Mode_t ROGER;
|
ROGER_Mode_t ROGER;
|
||||||
uint8_t REPEATER_TAIL_TONE_ELIMINATION;
|
uint8_t REPEATER_TAIL_TONE_ELIMINATION;
|
||||||
// uint8_t KEY_1_SHORT_PRESS_ACTION;
|
// uint8_t KEY_1_SHORT_PRESS_ACTION;
|
||||||
|
|
25
ui/menu.c
25
ui/menu.c
|
@ -72,7 +72,9 @@ const t_menu_item MenuList[] =
|
||||||
{/*"BatSav",*/ VOICE_ID_SAVE_MODE, MENU_SAVE, 省电模式}, // was "SAVE"
|
{/*"BatSav",*/ VOICE_ID_SAVE_MODE, MENU_SAVE, 省电模式}, // was "SAVE"
|
||||||
{/*"Mic",*/ VOICE_ID_INVALID, MENU_MIC, 麦克风增益},
|
{/*"Mic",*/ VOICE_ID_INVALID, MENU_MIC, 麦克风增益},
|
||||||
{/*"ChDisp",*/ VOICE_ID_INVALID, MENU_MDF, 信道显示模式}, // was "MDF"
|
{/*"ChDisp",*/ VOICE_ID_INVALID, MENU_MDF, 信道显示模式}, // was "MDF"
|
||||||
// {/*"POnMsg",*/ VOICE_ID_INVALID, MENU_PONMSG ,开机显示},
|
#if ENABLE_CHINESE_FULL==4
|
||||||
|
{/*"POnMsg",*/ VOICE_ID_INVALID, MENU_PONMSG ,开机显示},
|
||||||
|
#endif
|
||||||
{/*"BackLt",*/ VOICE_ID_INVALID, MENU_ABR, 自动背光}, // was "ABR"
|
{/*"BackLt",*/ VOICE_ID_INVALID, MENU_ABR, 自动背光}, // was "ABR"
|
||||||
{/*"BLMax",*/ VOICE_ID_INVALID, MENU_ABR_MAX, 背光亮度},
|
{/*"BLMax",*/ VOICE_ID_INVALID, MENU_ABR_MAX, 背光亮度},
|
||||||
{/*"MDCID",*/ VOICE_ID_INVALID, MENU_MDC_ID, MDC_ID},
|
{/*"MDCID",*/ VOICE_ID_INVALID, MENU_MDC_ID, MDC_ID},
|
||||||
|
@ -126,12 +128,19 @@ const t_menu_item MenuList[] =
|
||||||
|
|
||||||
// {/*"",*/ VOICE_ID_INVALID, 0xff ,"\x00"} // end of list - DO NOT delete or move this this
|
// {/*"",*/ VOICE_ID_INVALID, 0xff ,"\x00"} // end of list - DO NOT delete or move this this
|
||||||
};
|
};
|
||||||
|
#if ENABLE_CHINESE_FULL == 4
|
||||||
|
const char gSubMenu_PONMSG[][5]={
|
||||||
|
关闭,
|
||||||
|
图片,
|
||||||
|
信息
|
||||||
|
};
|
||||||
|
#endif
|
||||||
const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK;
|
const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK;
|
||||||
#if ENABLE_CHINESE_FULL != 4
|
#if ENABLE_CHINESE_FULL != 4
|
||||||
const char gSubMenu_SFT_D[][10] =//4
|
const char gSubMenu_SFT_D[][10] =//4
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
const char gSubMenu_SFT_D[][16] =//4
|
const char gSubMenu_SFT_D[][16] =//4
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -928,12 +937,12 @@ void UI_DisplayMenu(void) {
|
||||||
memcpy(String, Contact, 8);
|
memcpy(String, Contact, 8);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
// case MENU_PONMSG:
|
#if ENABLE_CHINESE_FULL==4
|
||||||
// strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// break;
|
|
||||||
|
|
||||||
|
case MENU_PONMSG:
|
||||||
|
strcpy(String, gSubMenu_PONMSG[gSubMenuSelection]);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case MENU_ROGER:
|
case MENU_ROGER:
|
||||||
strcpy(String, gSubMenu_ROGER[gSubMenuSelection]);
|
strcpy(String, gSubMenu_ROGER[gSubMenuSelection]);
|
||||||
|
|
||||||
|
|
12
ui/menu.h
12
ui/menu.h
|
@ -106,7 +106,11 @@ enum
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MENU_D_LIVE_DEC,
|
MENU_D_LIVE_DEC,
|
||||||
// MENU_PONMSG,
|
#if ENABLE_CHINESE_FULL==4
|
||||||
|
|
||||||
|
MENU_PONMSG,
|
||||||
|
#endif
|
||||||
|
|
||||||
MENU_ROGER,
|
MENU_ROGER,
|
||||||
// MENU_VOL,
|
// MENU_VOL,
|
||||||
//MENU_BAT_TXT,
|
//MENU_BAT_TXT,
|
||||||
|
@ -141,16 +145,22 @@ enum
|
||||||
|
|
||||||
extern const uint8_t FIRST_HIDDEN_MENU_ITEM;
|
extern const uint8_t FIRST_HIDDEN_MENU_ITEM;
|
||||||
extern const t_menu_item MenuList[];
|
extern const t_menu_item MenuList[];
|
||||||
|
#if ENABLE_CHINESE_FULL==4
|
||||||
|
|
||||||
|
extern const char gSubMenu_PONMSG[3][5];
|
||||||
|
#endif
|
||||||
|
|
||||||
//extern const char gSubMenu_TXP[3][2];//5
|
//extern const char gSubMenu_TXP[3][2];//5
|
||||||
#if ENABLE_CHINESE_FULL!=4
|
#if ENABLE_CHINESE_FULL!=4
|
||||||
extern const char gSubMenu_SFT_D[3][10];//3
|
extern const char gSubMenu_SFT_D[3][10];//3
|
||||||
#else
|
#else
|
||||||
|
|
||||||
extern const char gSubMenu_SFT_D[3][16];//3
|
extern const char gSubMenu_SFT_D[3][16];//3
|
||||||
#endif
|
#endif
|
||||||
//extern const char gSubMenu_W_N[2][3];//7
|
//extern const char gSubMenu_W_N[2][3];//7
|
||||||
#if ENABLE_CHINESE_FULL!=4
|
#if ENABLE_CHINESE_FULL!=4
|
||||||
extern const char gSubMenu_OFF_ON[2][3];//4
|
extern const char gSubMenu_OFF_ON[2][3];//4
|
||||||
|
|
||||||
#else
|
#else
|
||||||
extern const char gSubMenu_OFF_ON[2][5];//4
|
extern const char gSubMenu_OFF_ON[2][5];//4
|
||||||
#endif
|
#endif
|
||||||
|
|
24
ui/welcome.c
24
ui/welcome.c
|
@ -50,31 +50,41 @@ void UI_DisplayWelcome(void) {
|
||||||
|
|
||||||
memset(gStatusLine, 0, sizeof(gStatusLine));
|
memset(gStatusLine, 0, sizeof(gStatusLine));
|
||||||
UI_DisplayClear();
|
UI_DisplayClear();
|
||||||
|
ST7565_BlitStatusLine(); // blank status line
|
||||||
|
ST7565_BlitFullScreen();
|
||||||
|
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_MESSAGE) {
|
||||||
|
|
||||||
#if ENABLE_CHINESE_FULL == 4
|
#if ENABLE_CHINESE_FULL == 4
|
||||||
uint8_t welcome_len[2];
|
uint8_t welcome_len[2];
|
||||||
EEPROM_ReadBuffer(0x1e31e, welcome_len, 2) ;
|
EEPROM_ReadBuffer(0x1e31e, welcome_len, 2) ;
|
||||||
welcome_len[0]=welcome_len[0]>18?0:welcome_len[0];
|
welcome_len[0]=welcome_len[0]>18?0:welcome_len[0];
|
||||||
welcome_len[1]=welcome_len[1]>18?0:welcome_len[1];
|
welcome_len[1]=welcome_len[1]>18?0:welcome_len[1];
|
||||||
|
|
||||||
EEPROM_ReadBuffer(0x1e320, WelcomeString0, welcome_len[0]) ;
|
EEPROM_ReadBuffer(0x1e320, WelcomeString0, welcome_len[0]) ;
|
||||||
EEPROM_ReadBuffer(0x1e333, WelcomeString1, welcome_len[1]);
|
EEPROM_ReadBuffer(0x1e333, WelcomeString1, welcome_len[1]);
|
||||||
UI_PrintStringSmall( WelcomeString0, 0, 127, 0);
|
|
||||||
UI_PrintStringSmall( WelcomeString1, 0, 127, 2);
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
EEPROM_ReadBuffer(0x0EB0, WelcomeString0, 16);
|
EEPROM_ReadBuffer(0x0EB0, WelcomeString0, 16);
|
||||||
EEPROM_ReadBuffer(0x0EC0, WelcomeString1, 16);
|
EEPROM_ReadBuffer(0x0EC0, WelcomeString1, 16);
|
||||||
UI_PrintStringSmall(WelcomeString0, 0, 127, 0);
|
|
||||||
UI_PrintStringSmall(WelcomeString1, 0, 127, 2);
|
|
||||||
#endif
|
#endif
|
||||||
|
UI_PrintStringSmall( WelcomeString0, 0, 127, 0);
|
||||||
|
UI_PrintStringSmall( WelcomeString1, 0, 127, 2);
|
||||||
sprintf(WelcomeString1, "%u.%02uV %u%%",
|
sprintf(WelcomeString1, "%u.%02uV %u%%",
|
||||||
gBatteryVoltageAverage / 100,
|
gBatteryVoltageAverage / 100,
|
||||||
gBatteryVoltageAverage % 100,
|
gBatteryVoltageAverage % 100,
|
||||||
BATTERY_VoltsToPercent(gBatteryVoltageAverage));
|
BATTERY_VoltsToPercent(gBatteryVoltageAverage));
|
||||||
UI_PrintStringSmall(WelcomeString1, 0, 127, 4);
|
UI_PrintStringSmall(WelcomeString1, 0, 127, 4);
|
||||||
|
|
||||||
UI_PrintStringSmall(Version, 0, 127, 6);
|
UI_PrintStringSmall(Version, 0, 127, 6);
|
||||||
|
}
|
||||||
|
#if ENABLE_CHINESE_FULL == 4
|
||||||
|
else if(gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_PIC)
|
||||||
|
{
|
||||||
|
EEPROM_ReadBuffer( 0x1E350, gStatusLine, 128);
|
||||||
|
for (int i = 0; i < 7; ++i) EEPROM_ReadBuffer(0x1E350+128+128*i, &gFrameBuffer[i], 128);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ST7565_BlitStatusLine(); // blank status line
|
ST7565_BlitStatusLine(); // blank status line
|
||||||
ST7565_BlitFullScreen();
|
ST7565_BlitFullScreen();
|
||||||
|
|
|
@ -6997,4 +6997,6 @@
|
||||||
ף½
|
ף½
|
||||||
לא
|
לא
|
||||||
Q
|
Q
|
||||||
这是俺拾得嘞七
|
开机显示
|
||||||
|
图片
|
||||||
|
信息
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
Start testing: Dec 23 13:01 中国标准时间
|
Start testing: Jan 08 10:58 中国标准时间
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
End testing: Dec 23 13:01 中国标准时间
|
End testing: Jan 08 10:58 中国标准时间
|
||||||
|
|
|
@ -6997,4 +6997,6 @@
|
||||||
\x9B\x70
|
\x9B\x70
|
||||||
\x9B\x71
|
\x9B\x71
|
||||||
\x9B\x72
|
\x9B\x72
|
||||||
\x84\x6C\x88\xD9\x8C\x6C\x88\x18\x8F\x8C\x96\x27\x80\x07
|
\x80\x56\x81\xD9\x88\xE5\x80\xDF
|
||||||
|
\x86\x4C\x80\x92
|
||||||
|
\x89\x89\x8C\x8C
|
||||||
|
|
|
@ -6997,4 +6997,6 @@
|
||||||
\x9B\x70
|
\x9B\x70
|
||||||
\x9B\x71
|
\x9B\x71
|
||||||
\x9B\x72
|
\x9B\x72
|
||||||
\x84\x6C\x88\xD9\x8C\x6C\x88\x18\x8F\x8C\x96\x27\x80\x07
|
\x80\x56\x81\xD9\x88\xE5\x80\xDF
|
||||||
|
\x86\x4C\x80\x92
|
||||||
|
\x89\x89\x8C\x8C
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#ifdef GIT_HASH
|
#ifdef GIT_HASH
|
||||||
#define VER GIT_HASH
|
#define VER GIT_HASH
|
||||||
#else
|
#else
|
||||||
#define VER "113"
|
#define VER "114TEST"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue