本篇讲述BootLoader上位机开发。
源码地址:https://download.csdn.net/download/u010875635/11692122
此上位机采用WPF框架,C#语言开发,支持周立功的CAN设备和ValueCAN。
由于手头上暂时没有硬件,无法实际演示,大家先凑合看示例图。
注意,有很多人操作误区在于,将S19文件选择成了Bootloader,这里应该选择app,就是你自己的应用程序。
Bootloader与App分别占用2个非分页区。
Bootloader: 0xC000-0xFFFF(实际到0xF7FF,保留一个sector给vector table)
Application: 0x4000-0x7FFF,加上其它分页区(转换成全局地址为0x7F4000-0x7FFFF)
若是不知道怎么写App,可参考范例,App Demo源码地址:https://download.csdn.net/download/u010875635/12078243
BootloaderPage.xaml -- Bootloader刷写界面
S19ParseWithText -- 为S19文件解析查看界面,仅用于查看数据,与刷写无关
ClassBootloaderForCAN -- 协议封包解包在
CANCommon -- 通用的CAN连接断开、发送接收的类(实际收发在CANDevices类库,大家也可以添加自己手上以后的CAN设备的API,以便于支持)
VAlueCAN和ZlgCAN.xaml -- CAN配置控件,用于设置各个不同的CAN配置参数,方便转换成通用的例如波特率的参数。
/// /// 更新进度 ///
void UpdateProgress()
{
double percentNoDiv100 = m_CmdCount.SendFrameCount * 100.00 / m_CANSendFrameCount;// e.ProgressPercentage;// m_CmdCount.SendFrameCount * 1.0 / m_CANdataList.Count;
double usedTime = DateTime.Now.Subtract(m_SendDataSartTime).TotalSeconds;
double leftTime = usedTime / percentNoDiv100 * (100 - percentNoDiv100);
//TextBlockChangeMsg("发送进度", "已发送帧数:" + m_CmdCount.SendFrameCount.ToString(), System.Windows.Media.Brushes.Gray);
TextBlockChangeMsg("刷写进度", "已刷写帧数: " + m_CmdCount.ReceiveFrameCount.ToString() + " ,已用时间:" + usedTime.ToString("0.00") + " s ,剩余时间:" + leftTime.ToString("0.00") + " s", System.Windows.Media.Brushes.Gray);
ProcessUpdate(percentNoDiv100);
}
/// /// 开始烧录 ///
void TryBurnS19()
{
//SendData();
//return;
DateTime startTime;
ProcessUpdate(0); //进度清零
TextBlockAddMsg("检查是否已擦除Flash", System.Windows.Media.Brushes.Black);
m_Mtcl1DevelopCmd.SendNormalBytes(m_UpdateAppSendCmdCANID, GetCurrentCANIndex(),m_CanDataParse.CanErasePackage(m_ValidMinGlobalAddr, m_ValidMaxGlobalAddr));
startTime = DateTime.Now; //开始计时
while (m_McuState != McuState.McuFlashErased)
{
uint count = 0;
while (count < 100000)
count++;
if (DateTime.Now.Subtract(startTime).TotalSeconds > 10) //是否超过10s没有接收到
break;
}
if (m_McuState != McuState.McuFlashErased)
{
TextBlockAddMsg("擦除超时", System.Windows.Media.Brushes.Red, 1);
BurnHex();
return;
}
string ts = DateTime.Now.Subtract(startTime).TotalSeconds.ToString();
TextBlockAddMsg("擦除完毕!,总耗时:" + ts + "s", System.Windows.Media.Brushes.Blue);
TextBlockAddMsg("开始发送数据,CAN帧数;" + m_CANSendFrameCount.ToString(), System.Windows.Media.Brushes.Black);
//m_UpdateProgressTimer.Start(); //定时更新UI
SendData(); //发送数据
//m_UpdateProgressTimer.Stop(); //关闭定时更新UI
UpdateProgress();
TextBlockAddMsg("发送数据结束,耗时: " + DateTime.Now.Subtract(m_SendDataSartTime).TotalSeconds.ToString("0.00") + "s", System.Windows.Media.Brushes.Black);
m_Mtcl1DevelopCmd.SendNormalBytes(m_UpdateAppSendCmdCANID, GetCurrentCANIndex(), m_CanDataParse.g_DataEndCmd); //数据结束命令
BurnHex();
}
/// /// 发送后检查是否超时或错误 ///
///
bool CheckAfterSend()
{
if (!SendDataCheck_Wait(ref m_CmdCount.SendFrameCount, ref m_CmdCount.ReceiveFrameCount, 2000)) //发送中断
{
TextBlockAddMsg("发送超时 ", System.Windows.Media.Brushes.Red);
return false;
}
if (m_ReponseState != ClassBootloaderForCAN.ReponseState.CmdRunOK)
return false;
return true;
}
/// /// 发送数据 ///
private void SendData()
{
m_CmdCount.SendLineCount = 0;
m_CmdCount.SendFrameCount = m_CmdCount.ReceiveFrameCount = 0;
m_SendDataSartTime = DateTime.Now; //开始计时
bool isNotBreak = true;
//发送数据
for (int i = 0; i < m_CANAddrList.Count && isNotBreak; i++)
{
m_Mtcl1DevelopCmd.SendNormalBytes(m_UpdateAppSendCmdCANID, GetCurrentCANIndex(), m_CANAddrList[i]); //发送地址命令
m_CmdCount.SendLineCount++;
m_CmdCount.SendFrameCount++;
if (!CheckAfterSend() ) //发送中断
{
isNotBreak = false;
break;
}
for (int j=0;j m_Mtcl1DevelopCmd.SendNormalBytes(m_UpdateAppSendDataCANID, GetCurrentCANIndex(), m_CANdataListList[i][j]); //发送数据 m_CmdCount.SendFrameCount++; if (!CheckAfterSend()) //发送中断 { isNotBreak = false; break; } } if(m_CmdCount.SendLineCount%10==0) UpdateProgress(); } } /// /// 检查接收情况 /// /// bool CheckReceive(ref byte[] datas) { m_ReponseState = ProcessReponseState(ref datas); //获取返回状态 switch (m_ReponseState) { case ClassBootloaderForCAN.ReponseState.AddressChecksumError: case ClassBootloaderForCAN.ReponseState.AddressOverRange:
上一篇:【MPC5744P】FreeMaster上位机配置
下一篇:STM8学习笔记---串口printf函数的实现
推荐阅读最新更新时间:2024-11-10 10:29
设计资源 培训 开发板 精华推荐
- 【航顺训练营】我的世界矿石灯
- DC386A,基于 LTC1876EG 双相高效率 3 路输出电源的演示板,3.3V 至 3.6Vin,2.5V/15A,1.8V/15A 和 5V/100mA
- 高速逻辑兼容、半间距微型扁平光耦合器 MOSFET 级联接口
- 使用 LTC3719 的 42A AMD Hammer 微处理器电源
- 基于 L6902D 的 STEVAL-ISA155V1、1A 恒流 DC/DC 转换器评估板
- AD8625ARUZ单极输出精密放大器典型应用电路
- 使用 STMicroelectronics 的 R5970AD 的参考设计
- DC1525A-D,基于 LTC2172-14、14 位、80Msps、1.8V 四路串行 ADC 的演示板
- 使用 Richtek Technology Corporation 的 RT2596 的参考设计
- TSSOP20EV,基于 PICmicro 微控制器的 SSOP 评估板