📄 umain.pas
字号:
stream.Position := 0;
mmoHex.Lines.BeginUpdate;
mmoHex.Clear;
mmoHex.Lines.LoadFromStream(stream);
mmoHex.Lines.Append(':00000001FF');
mmoHex.Lines.EndUpdate;
pgctMain.ActivePage := tsBin;
end;
loginfo('');
s := Format('V %-25s [%s]', [lang.msgLoadFileSuccess + ':', FileName]);
loginfo(s);
s := Format('> %-25s 0x%.04X/%d', [lang.msgFileLength + ':', DataSize, DataSize]);
loginfo(s);
s := Format('> %-25s 0x%.04X/%d', [lang.msgFlashSize + ':', FlashSize[cfg.FlashSize], FlashSize[cfg.FlashSize]]);
loginfo(s);
if DataSize > FlashSize[cfg.FlashSize] then
begin
mmoBin.DataSize := DataSize;
Application.MessageBox(PChar(lang.msgBufferOverflow + ': [' + IntToStr(DataSize) + '] > [' + IntToStr(FlashSize[cfg.FlashSize]) + ']'), PChar(lang.msgError), MB_OK + MB_ICONSTOP);
loginfo('X ' + lang.msgBufferOverflow + ': [' + IntToStr(DataSize) + '] > [' + IntToStr(FlashSize[cfg.FlashSize]) + ']');
end
else
begin
btnDownload.Enabled := True;
mnDownLoad.Enabled := True;
end;
if not (CompareText('.aub', ExtractFileExt(FileName)) = 0) then
begin
//make buffer size multiple frame size
if (DataSize mod cfg.FrameLen) <> 0 then
begin
DataSize := ((DataSize + cfg.FrameLen - 1) div cfg.FrameLen) * cfg.FrameLen;
end;
//even frame
if ((DataSize div cfg.FrameLen) mod 2) = 1 then
begin
DataSize := DataSize + cfg.FrameLen;
end;
//autoszie
if cfg.AutoSize then
begin
mmoBin.DataSize := DataSize;
end
else
begin
if DataSize < FlashSize[cfg.FlashSize] then
mmoBin.DataSize := FlashSize[cfg.FlashSize]
else
mmoBin.DataSize := DataSize;
end;
end;
s := Format('> %-25s 0x%.04X/%d', [lang.msgBufferSize + ':', mmoBin.DataSize, mmoBin.DataSize]);
loginfo(s);
//change Caption
Caption := 'AVRUBD - [' + FileName + ']';
for i := 0 to pmHisFile.Items.Count - 1 do
pmHisFile.Items[i].Checked := False;
if pmHisFile.Items.Find(FileName) = nil then
begin
//History file list
if pmHisFile.Items.Count >= MaxHisFileCount then
pmHisFile.Items.Delete(pmHisFile.Items.Count - 1);
hf := TMenuItem.Create(Self);
hf.OnClick := HisFileClick;
hf.Caption := FileName;
hf.RadioItem := True;
hf.Checked := True;
s := ExtractFileExt(FileName);
if CompareText(s, '.hex') = 0 then
hf.ImageIndex := 14
else
if CompareText(s, '.aub') = 0 then
hf.ImageIndex := 9
else
hf.ImageIndex := 15;
pmHisFile.Items.Insert(0, hf);
end
else
begin
pmHisFile.Items.Find(FileName).Checked := True;
end;
finally
stream.Free;
mmoBin.Tag := 0;
pgctMain.OnChange(nil);
if (cfg.fillunused and btnDownload.Enabled and (CompareText('.hex', ExtractFileExt(FileName)) = 0)) or (CompareText('.aub', ExtractFileExt(FileName)) = 0) then
mmoBinChange(nil);
end;
end;
procedure TfrmMain.mmoBinChange(Sender: TObject);
var
stream: TMemoryStream;
i, j: Integer;
s: string;
jy: Byte;
begin
if mmoBin.Tag <> 0 then
Exit;
mmoBin.SaveToBuffer(DataBuf, mmoBin.DataSize);
stream := TMemoryStream.Create;
try
stream.Clear;
for i := 0 to ((mmoBin.DataSize + 15) div 16) - 1 do
begin
if (i > 0) and (((i * 16) mod 65536) = 0) then
begin
//segment address
s := ':02000002100000 ';
j := (i * 16 * 16) div 65536;
s[10] := DateToChar(j div 16);
s[11] := DateToChar(j mod 16);
jy := 4 + CharToByte(s[10], s[11]);
jy := -jy;
s[14] := DateToChar(jy div 16);
s[15] := DateToChar(jy mod 16);
s[16] := #13;
s[17] := #10;
stream.WriteBuffer(s[1], 17);
end;
SetLength(s, 45);
s[1] := ':';
s[2] := '1';
s[3] := '0';
jy := (i * 16) div 256;
s[4] := DateToChar(jy div 16);
s[5] := DateToChar(jy mod 16);
jy := (i * 16) mod 256;
s[6] := DateToChar(jy div 16);
s[7] := DateToChar(jy mod 16);
s[8] := '0';
s[9] := '0';
jy := $10 + ((i * 16) div 256) + ((i * 16) mod 256);
//fill data
for j := 0 to 15 do
begin
jy := jy + DataBuf[i * 16 + j];
s[j * 2 + 10] := DateToChar(DataBuf[i * 16 + j] div 16);
s[j * 2 + 11] := DateToChar(DataBuf[i * 16 + j] mod 16);
end;
//校验
jy := -jy;
s[42] := DateToChar(jy div 16);
s[43] := DateToChar(jy mod 16);
s[44] := #13;
s[45] := #10;
stream.WriteBuffer(s[1], 45);
end;
stream.Position := 0;
mmoHex.Lines.BeginUpdate;
mmoHex.Clear;
mmoHex.Lines.LoadFromStream(stream);
mmoHex.Lines[mmoHex.Lines.Count - 1] := ':00000001FF';
mmoHex.Lines.EndUpdate;
finally
stream.Free;
end;
end;
//Log message
procedure TfrmMain.loginfo(Msg: string);
begin
mmoLog.Lines.Append(Msg);
//keep maxlines
if mmoLog.Lines.Count > MAXLOGLINES then
begin
mmoLog.Lines.BeginUpdate;
mmoLog.Lines.Delete(0);
mmoLog.Lines.EndUpdate;
end;
mmoLog.TopLine := mmoLog.Lines.Count - mmoLog.LinesInWindow + 1;
end;
//Load language file
procedure TfrmMain.loadlanguage(langname: string);
var
lng: TFastIniFile;
i: Integer;
begin
for i := 0 to pmLang.Items.Count - 1 do
if CompareText(langname, pmLang.Items[i].Caption) = 0 then
begin
pmLang.Items[i].Checked := True;
mnLanguage.Items[i].Checked := True;
end;
if CompareText(langname, 'Chinese') = 0 then
begin
pmLangChinese.ImageIndex := -1;
mnLangChinese.ImageIndex := -1;
end
else
begin
pmLangChinese.ImageIndex := 12;
mnLangChinese.ImageIndex := 12;
end;
if CompareText(langname, 'English') = 0 then
begin
pmLangEnglish.ImageIndex := -1;
mnLangEnglish.ImageIndex := -1;
end
else
begin
pmLangEnglish.ImageIndex := 13;
mnLangEnglish.ImageIndex := 13;
end;
if CompareText(langname, 'CHINESE') = 0 then
begin
//Main
//menu
mnFile.Caption := '文件';
mnLoad.Caption := '载入';
mnSave.Caption := '保存';
mnExit.Caption := '退出';
mnOperate.Caption := '操作';
mnDownLoad.Caption := '下载';
mnAutoCode.Caption := '自动生成配置代码';
mnOption.Caption := '选项';
mnSystem.Caption := '系统';
mnComPortSetup.Caption := '串口';
mnHelp.Caption := '帮助';
mnAbout.Caption := '关于';
mnContent.Caption := '使用方法';
btnMenuFile.Caption := mnFile.Caption;
btnMenuOperate.Caption := mnOperate.Caption;
btnMenuOption.Caption := mnOption.Caption;
btnMenuHelp.Caption := mnHelp.Caption;
//msg
lang.msgError := '错误';
lang.msgWarning := '警告';
lang.msgOpenComportFail := '打开串口失败.';
lang.msgSendRSTCmd := '发送复位命令';
lang.msgStartDownload := '开始下载';
lang.msgStopDownload := '停止下载';
lang.msgStartConnect := '开始联机';
lang.msgSendConnectKey := '发送联机密码';
lang.msgConnectSuccess := '联机成功';
lang.msgConnectFail := '联机失败';
lang.msgLines := '行';
lang.msgChecksum := '校验';
lang.msgLength := '长度';
lang.msgTooManyRetry := '重试次数太多!';
lang.msgLoadFileFail := '载入文件失败.';
lang.msgUnsupport32BitAddress := '不支持32位地址模式.';
lang.msgLoadFileSuccess := '载入文件成功';
lang.msgFileLength := '文件长度';
lang.msgFlashSize := 'Flash空间大小';
lang.msgBufferOverflow := '缓冲区溢出';
lang.msgBufferSize := '缓冲区大小';
lang.msgQueryClearStat := '你确定要清除统计结果吗?';
lang.msgUpdateSuccess := '升级成功';
lang.msgUpdateFail := '升级失败';
lang.msgUpdateAbort := '升级中止';
lang.msgSpeed := '速度';
lang.msgTimeElapse := '用时';
lang.msgPackag := '包';
lang.msgData := '数据';
lang.msgRetry := '重试';
lang.msgFmtErr := '文件格式错误';
lang.msgCrcErr := '数据校验错误';
//About
with frmAbout do
begin
Caption := '关于';
lbTranslator.Caption := '语言: 简体中文';
lbTotalRun.Caption := '运行次数';
lbTotalDown.Caption := '总共下载';
lbTotalSucc.Caption := '成功次数';
lbTotalFail.Caption := '失败次数';
lbCurDown.Caption := '本次下载';
lbCurSucc.Caption := '本次成功';
lbCurFail.Caption := '本次失败';
btnOk.Caption := '确定';
btnClearStat.Caption := '清除';
end;
//option
with frmOption do
begin
Caption := '选项';
tsSystem.Caption := '系统';
tsComport.Caption := '串口';
btnFont.Caption := '字体';
btnOk.Caption := '确定';
btnCancel.Caption := '取消';
btnHypertrm.Caption := '超级终端';
btnImport.Caption := '导入';
gpbConnectKey.Caption := '联机密码';
lbFlashSize.Caption := 'Flash空间大小';
lbFlashSizeBytes.Caption := '字节';
lbCommProt.Caption := '通信协议';
lbFrameLen.Caption := '数据帧长';
lbBasicTime.Caption := '基本时间周期';
lbBasicTimeMs.Caption := '毫秒';
lbMaxConCnt.Caption := '最大联机次数';
lbFrameLenBytes.Caption := lbFlashSizeBytes.Caption;
lbComPort.Caption := '串口';
lbBaudRate.Caption := '波特率';
lbDataBits.Caption := '数据位';
lbStopBits.Caption := '停止位';
lbParity.Caption := '校验位';
lbFlowCtrl.Caption := '流量控制';
chkBeepEn.Caption := '扬声器声音提示';
chkSmartMouse.Caption := '智能鼠标模式';
lbFillUnused.Caption := '填充未用空间';
lbSendRST.Caption := '发送复位命令';
lbAutoSize.Caption := '自动判断下载数据长度';
cbbProtocol.Items.Strings[0] := '标准XModem协议';
cbbProtocol.Items.Strings[1] := '简化XModem协议';
end;
//AutoCode
with frmAutoCode do
begin
Caption := '自动代码';
btnHypertrm.Caption := '超级终端';
btnCancel.Caption := '取消';
btnSmallest.Caption := '最小代码';
btnRecover.Caption := '恢复';
btnRecommand.Caption := '推荐';
btnMake.Caption := '创建';
lbRS485PORT.Caption := '端口';
lbRS485PIN.Caption := '引脚';
lbLEDPORT.Caption := '端口';
lbLEDPIN.Caption := '引脚';
lbBOOTPORT.Caption := '端口';
lbBOOTPIN.Caption := '引脚';
lbBOOTLEVEL.Caption := '电平';
cbbCRC.Items := frmOption.cbbProtocol.Items;
cbbBootLevel.Items.Strings[0] := '低';
cbbBootLevel.Items.Strings[1] := '高';
cbbBootMode.Items.Strings[0] := '串口';
cbbBootMode.Items.Strings[1] := '电平';
end;
//Hint
btnMenuFile.Hint := '文件操作';
btnMenuOperate.Hint := '用户操作';
btnMenuOption.Hint := '系统参数设置';
btnMenuHelp.Hint := '帮助信息';
mnLoad.Hint := '载入目标文件到缓冲区';
mnSave.Hint := '保存缓冲区数据到文件';
mnExit.Hint := '退出软件';
mnDownLoad.Hint := '下载数据到单片机';
mnAutoCode.Hint := '自动产生用户配置文件';
mnMCU.Hint := '设置单片机相关参数';
mnSystem.Hint := '设置系统参数';
mnComPortSetup.Hint := '设置串口参数';
mnLanguage.Hint := '选择用户界面语言';
mnAbout.Hint := '显示软件相关信息';
mnHelp.Hint := '显示帮助文件';
btnLoad.Hint := mnLoad.Hint;
btnSave.Hint := mnSave.Hint;
btnDownload.Hint := mnDownLoad.Hint;
btnStop.Hint := '中止下载';
btnOption.Hint := '设置软件参数';
btnAutoCode.Hint := mnAutoCode.Hint;
btnLanguage.Hint := mnLanguage.Hint;
btnAbout.Hint := mnAbout.Hint;
btnExit.Hint := mnExit.Hint;
frmAbout.btnClearStat.Hint := '清除统计信息';
frmOption.btnImport.Hint := '导入用户配置文件bootcfg.h';
frmOption.btnHypertrm.Hint := '设置适合使用超级终端的参数';
frmOption.btnCancel.Hint := '取消参数设置';
frmOption.btnOk.Hint := '保存参数设置';
frmOption.btnFont.Hint := '设置用户界面字体';
frmOption.gpbConnectKey.Hint := '设置单片机的联机密码参数';
frmOption.cbbFlash.Hint := '选择单片机的Flash容量';
frmOption.chkFillUnused.Hint := '填充Flash中没有使用的空间,可以提高抗干扰能力';
frmOption.lbFillUnused.Hint := frmOption.chkFillUnused.Hint;
frmOption.edtFillUnused.Hint := '填充的数据以字(双字节)为单位';
frmOption.chkSendRST.Hint := '发送复位命令,可以不用手工复位单片机。这个功能需要单片机程序支持';
frmOption.lbSendRST.Hint := frmOption.chkSendRST.Hint;
frmOption.edtSendRST.Hint := '复位命令';
frmOption.chkAutoSize.Hint := '自动计算下载数据长度,可以减少下载时间';
frmOption.lbAutoSize.Hint := frmOption.chkAutoSize.Hint;
frmOption.cbbProtocol.Hint := '通信使用的协议,必需和bootcfg.h中定义的一致';
frmOption.cbbFrameLen.Hint := '通信时数据包中数据的长度(不包括控制数据和校验数据)';
frmOption.cbbSendTime.Hint := '发送数据间隔时间,也是数据超时时间';
frmOption.cbbBootCnt.Hint := '发送联机命令最大次数';
frmOption.chkBeepEn.Hint := '允许使用PC机扬声器进行状态提示';
frmOption.chkSmartMouse.Hint := '允许智能鼠标模式,可以减少手指的疲劳程度';
frmAutoCode.btnRecover.Hint := '恢复参数成默认值';
frmAutoCode.btnRecommand.Hint := '正式产品中推荐使用的参数';
frmAutoCode.btnHypertrm.Hint := '适合于使用超级终端时使用的参数';
frmAutoCode.btnSmallest.Hint := '产生最小的Bootloader代码时的参数设置';
frmAutoCode.btnCancel.Hint := '退出自动代码功能';
frmAutoCode.btnMake.Hint := '根据用户选择的参数产生配置文件';
frmAutoCode.chkRS485En.Hint := '使用RS485/RS422模式';
frmAutoCode.lbRS485En.Hint := frmAutoCode.chkRS485En.Hint;
frmAutoCode.chkLED.Hint := '使用LED显示Bootloader的状态';
frmAutoCode.lbLEDEn.Hint := frmAutoCode.chkLED.Hint;
frmAutoCode.cbbFCPU.Hint := '单片机系统的时钟频率';
frmAutoCode.cbbBaudRate.Hint := '选择串口通信使用的波特率';
frmAutoCode.cbbComPortNo.Hint := '选择单片机使用的串口号';
frmAutoCode.cbbBufferSize.Hint := '单片机串口缓冲区长度,与通信协议中数据帧长度对应';
frmAutoCode.cbbTimeClk.Hint := '一次联机命令的超时时间,也是基本时间段';
frmAutoCode.cbbBootCnt.Hint := '最大联机次数';
frmAutoCode.cbbFileCnt.Hint := '等待上位机发送数据的超时时间,也是单片机发送数据C的次数';
frmAutoCode.cbbInitDelay.Hint := '串口初始化后的延时周期数,部分早期单片机需要此参数';
frmAutoCode.cbbBootMode.Hint := 'Bootloader触发模式,默认是串口。选择引脚电平是可以获得更小的代码';
frmAutoCode.cbbBootStart.Hint := '单片机Boot区的起始地址, 设置为0将禁止此功能';
frmAutoCode.cbbCRC.Hint := '通信数据的校验模式';
frmAutoCode.chkChipCheck.Hint := '校验下载的数据,用于提高可靠性。强烈推荐使用这个选项(需要和BootStart一起使用才能有效)';
frmAutoCode.chkWDG.Hint := '使用看门狗,可以提高系统的可靠性';
frmAutoCode.chkVerbose.Hint := '显示更多的提示信息给用户,使用超级终端时需要选择此参数';
//Version
mmoVer.Lines.Text :=
'v3.5 2008.Mar' + #13#
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -