C制作STM32上位机升级工具(完整教程)
9hr思路很简单,C制作一个上位机工具,将读取的bin文件通过串口下发至单片机,一帧数据包含:7字节的Modbus协议帧头200字节数据更新包(最后一帧少于等于200字节)2字节的CRC校验码。单片机在boot中解析协议,协议解析无误后,将数据更新包写入Flash中,然后返回特定的数据。上位机根据返回的数据判断本次数据是否写入成功,如果写入成功继续下发新的更新包,如果写入失败重复发送本次更新包。通讯间隔100ms。
开发环境:VisioStudio2015
一。新建windows窗体应用程序:
二。绘制基本界面:
在工具箱中的公共控件下找到以下三个控件Label、ComboBox、Button,拖拽到Form中。鼠标点击控件后可以在属性栏中修改控件的相应属性。
选中修改串口波特率对应的CommboBox控件,点击Items属性,输入相应的波特率值,保存。其他控件的属性就是改改名字,外形大小、颜色等。
然后再放两个TextBox控件显示加载信息等,以及几个按钮。最后界面如下:
三。添加串口控件以及文件对话框:
在工具箱中找打组件下的SerialPort控件,也就是串口控件;对话框下的OpenFileDialog控件,拖拽到Form下的空区域中
现在所用到的控件都已经加到窗体中了,基本工作已经完成了。接下来开始撸代码了。
四。代码撸起来
1。搜索可用串口,并显示在CommboBox中显示串口名称。双击搜索端口按钮,会自动跳转到代码编辑处,在buttonClik事件函数下添加更新端口的函数。privatevoidbutton2Click(objectsender,EventArgse){string〔〕ArryPortSystem。IO。Ports。SerialPort。GetPortNames();comboBox2。Items。Clear();for(inti0;iArryPort。Length;i){comboBox2。Items。Add(ArryPort〔i〕);}}
2。打开关闭串口。双击启用端口按钮,加入以下代码。privatevoidbutton1Click(objectsender,EventArgse){if(button1。Text启用端口){try{serialPort1。PortNamecomboBox2。Text;serialPort1。Open();comboBox2。Enabledfalse;button2。Enabledfalse;button1。Text关闭端口;}catch{System。Media。SystemSounds。Beep。Play();MessageBox。Show(端口打开失败,错误);}}else{try{serialPort1。Close();button2。Enabledtrue;comboBox2。Enabledtrue;button1。Text启用端口;}catch{System。Media。SystemSounds。Beep。Play();MessageBox。Show(关闭串口失败,错误);}}}
3。修改串口波特率。双击串口波特率对应的CommboBox,加入以下代码。privatevoidcomboBox1SelectedIndexChanged(objectsender,EventArgse){serialPort1。BaudRateConvert。ToInt32(comboBox1。Text);}
4。在Form1Load中创建串口接收线程,并且初始化串口波特率,串口的其他参数配置使用默认即可。串口接收也可以使用数据接收事假,类似于STM32的串口接收中断。下面的代码是创建串口接收线程,以线程的方式接收串口数据。privatevoidForm1Load(objectsender,EventArgse){serialPort1。BaudRate115200;comboBox1。Text115200;ThreadReadSerialPortnewThread(newParameterizedThreadStart(SerialPortReadThread));ReadSerialPort。IsBackgroundtrue;ReadSerialPort。Start();}
如果使用事件的方式接收数据,按一下步骤操作即可:
嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!
无偿分享大家一个资料包,差不多150多G。里面学习路线、面经、项目都比较新也比较全面!某鱼上买估计至少要好几十。
点击这里找小助理0元领取:嵌入式物联网学习资料(头条)
5。打开。bin文件。双击文件按钮,加入以下代码:stringBinText;OpenFileDialogMyFileDialog;privatevoidbutton7Click(objectsender,EventArgse){BinText;MyFileDialognewOpenFileDialog();MyFileDialog。InitialDirectoryEnvironment。GetFolderPath(Environment。SpecialFolder。DesktopDirectory);MyFileDialog。Filter。bin;if(MyFileDialog。ShowDialog()DialogResult。OK){stringfilePathMyFileDialog。FileName;FileStreamMyfilenewFileStream(filePath,FileMode。Open,FileAccess。Read);BinaryReaderbinreadernewBinaryReader(Myfile);MyPublicPara。FileLength(int)Myfile。Length;获取bin文件长度MyPublicPara。Bincharbinreader。ReadBytes((int)Myfile。Length);textBox4。TextMyFileDialog。SafeFileName;textBox4。TextMyfile。LengthByterr;}}
到这一步,我们已经可以打开串口、打开指定的bin文件了,接下来就是通过串口把bin文件发出去。
6。发送bin文件。
点击开始更新按钮,加入以下代码:publicdelegatevoidClearProgressValue();ProgressprogressForm;ListProgressListFormnewListProgress();创建窗体集合privatevoidbutton8Click(objectsender,EventArgse){byte〔〕SysRestarCMD{0x01,0x10,0x36,0x51,0x00,0x02,0x04,0x13,0x52,0x00,0x62,0x00,0x00};ushortcrcvalueModbusCRC16(SysRestarCMD,13);SysRestarCMD〔11〕(byte)((crcvalue8)0xff);SysRestarCMD〔12〕(byte)(crcvalue0xff);if(serialPort1。IsOpen)serialPort1。Write(SysRestarCMD,0,13);textBox5。Text;BinText;MyPublicPara。UpdataCount0;progressFormnewProgress();progressForm。StartPositionFormStartPosition。CenterScreen;if(ListForm。Count!0){ListForm〔0〕。Close();ListForm。Clear();}progressForm。Show();ListForm。Add(progressForm);将更新进度窗体加入集合中button8。Enabledfalse;Delay(2000);if((MyPublicPara。FileLength10000)(MyPublicPara。FileLength100000)(serialPort1。IsOpen)){ThreadSendReadFilenewThread(newParameterizedThreadStart(SendBinFileThread));创建下发更新文件线程SendReadFile。IsBackgroundtrue;SendReadFile。Start();启动线程}}
开始更新后,先下发一个复位指令,让单片机复位进入boot程序,延迟2s后创建下发bin文件的线程,开始更新。指令格式按照modbus协议,不清楚modbus协议的百度之。这里提供一个modbus的16位CRC校验计算公式,可以用来计算或者校验一帧数据的CRC,如下:publicstaticushortModbusCRC16(byte〔〕data,intlength){intlenlength2;ushortcrcvalue0xFFFF;for(inti0;ilen;i){crcvalue(ushort)data〔i〕;for(intj8;j!0;j){if((crcvalue0x0001)!0){crcvalue1;crcvalue0xA001;}else{crcvalue1;}}}returncrcvalue(ushort)(((crcvalue0x00ff)8)((crcvalue0xff00)8));}
7。开始下发bin文件。函数名称:Updata(objectlength)描述:下发。BIN文件输入:无输出:无publicdelegatevoidSendBin();publicvoidUpdata(){intTxCount0;inti0;byte〔〕UpdataCMDnewbyte〔256〕;UpdataCMD〔TxCount〕0x01;UpdataCMD〔TxCount〕0x10;UpdataCMD〔TxCount〕0x26;UpdataCMD〔TxCount〕0X54;UpdataCMD〔TxCount〕0x00;if(MyPublicPara。UpdataCount(MyPublicPara。FileLength200)){UpdataCMD〔TxCount〕0X64;UpdataCMD〔TxCount〕0xC8;for(i0;i200;i){UpdataCMD〔TxCount〕MyPublicPara。Binchar〔MyPublicPara。UpdataCount200i〕;}}elseif(MyPublicPara。UpdataCount(MyPublicPara。FileLength200)){UpdataCMD〔TxCount〕(byte)((MyPublicPara。FileLength200MyPublicPara。UpdataCount)2);UpdataCMD〔TxCount〕(byte)(UpdataCMD〔5〕2);for(i0;i(MyPublicPara。FileLength(MyPublicPara。FileLength200)200);i){UpdataCMD〔TxCount〕MyPublicPara。Binchar〔MyPublicPara。UpdataCount200i〕;}MyPublicPara。UpdataCount(MyPublicPara。FileLength200)1;已经更新到最后一帧}ushortcrcvalueModbusCRC16(UpdataCMD,TxCount);UpdataCMD〔TxCount〕(byte)((crcvalue8)0xff);UpdataCMD〔TxCount〕(byte)(crcvalue0xff);if(serialPort1。IsOpen)serialPort1。Write(UpdataCMD,0,TxCount);CMDTOSEND(ushort)command。UPDATACMD;for(i0;iTxCount;i){BinTextUpdataCMD〔i〕。ToString(X2);}UpdataMessageToShow(BinTextr);BinText;}函数名称:SendBinFileThread(objectlength)描述:下发更新固件线程输入:无输出:无publicdelegatevoidButton8Click();privatevoidButton8Enable(){button8。Enabledtrue;}publicvoidSendBinFileThread(objectlength){while(MyPublicPara。UpdataCount((MyPublicPara。FileLength200))){this。Invoke(newSendBin(Updata));Thread。Sleep(100);}this。Invoke(newButton8Click(Button8Enable));MyPublicPara。UpdataCount0;}
前面说了,下发bin文件时在线程中完成的,点击开始更新按钮时创建了一个下发bin文件的线程。为了在下发更新文件时不影响界面的流程度,我们使用了线程委托的方式publicdelegatevoidSendBin()。
8。有发有回。
STM32更新固件一定要小心,有一个字节写入错误就可能导致更新失败,更新完毕后死机等等。所以必须上位机必须校验单片机的返回数据,只有返回数据校验正确后,才继续下发新的更新内容,否则一直下发本次更新内容,直至校验正取。加入串口读取并解析的线程:函数名称:SerialPortRead()描述:读取串口函数输入:无输出:无publicdelegatevoidSerialPortReDelegate();publicdelegatevoidaddProgress();publicvoidSerialPortRead(){if(serialPort1。IsOpen){intRxLengthserialPort1。BytesToRead;byte〔〕ReceiveDatanewbyte〔RxLength〕;serialPort1。Read(ReceiveData,0,RxLength);ushortcrcvalueModbusCRC16(ReceiveData,RxLength);if((RxLength8)(crcvalue((ushort)(ReceiveData〔RxLength2〕8)ReceiveData〔RxLength1〕))){if(CMDTOSEND(UInt16)command。UPDATACMD){MyPublicPara。UpdataCount;CMDTOSEND(UInt16)command。OK;this。Invoke(newaddProgress(progressForm。AddProgress));}}RxLength0;}}函数名称:SerialPortReadThred()描述:串口读取线程输入:无输出:无publicvoidSerialPortReadThread(objectlength){while(true){this。Invoke(newSerialPortReDelegate(SerialPortRead));Thread。Sleep(1);}}
C中使用指针不是很方便,所以程序中用MyPublicPara。UpDataCount这个变量代替指针指向bin文件中的元素,只有在本次更新成功后,MyPublicPara。UpDataCount才指向下一待更新的数据包,每次更新更新的数据包大小为200字节,如果最后一包数据不够200字节就把剩下的数据作为1包发送出去,选用200字节的大小,因为stm32在写入flash时是以字或半字写入的,所以数据包大小必须为4的整数倍。
到这儿这个小工具基本完成了,最后还可以再添加一个ProgressBar控件用来指示当前的更新进度。
9。指示当前更新进度。
右键添加新建项,选择window窗体。
在这个窗体中加入一个ProgressBar控件,和一个Label控件,用于显示更新进度,如下:
双击窗体,在load时间中加入以下代码,就是设置ProgressBar的最大值bin文件长度200,因为我们是以200字节大小下发一次更新数据的,所以ProgressBar最大值就是更大的更新次数。privatevoidProgressLoad(objectsender,EventArgse){label1。Text0;progressBar1。MaximumForm1。MyPublicPara。FileLength200;Form1。MyPublicPara。ProgressOpened1;}
在Progress命名空间下加入以下代码:privatedelegatevoidLabel1SetText(stringtext);privatevoidlabelSetText(stringtext){if(this。label1。InvokeRequired){Label1SetTextdnewLabel1SetText(labelSetText);this。Invoke(d,newobject〔〕{text});}else{this。label1。Texttext;}}publicvoidAddProgress(){if(progressBar1。ValueprogressBar1。Maximum){progressBar1。Value;}labelSetText(((progressBar1。Value100)progressBar1。Maximum)。ToString());}
为了避免ProgressBar控件再载入的过程中影响界面的流畅度,同样使用了委托来更新Label的值和ProgressBar的进度。
到这儿,基本完成了小工具的制作,下面就可以愉快的更新啦。
以上为作者原帖内容。
小编的话:该工具和传统的串口下载工具(flymcu)不太一样,升级过程需要下位机程序配合,所以想玩程序升级的朋友,还需要研究下BOOT启动、程序升级等内容
原文链接:C制作STM32上位机升级工具(完整教程)
转载自;单片机爱好者
原文链接:https:mp。weixin。qq。comskPVWYGRE1TEAP2XjNp6jVg
版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除
画眼妆的步骤大眼妆的画法步骤图我们平时化妆都会经常化眼妆,眼妆是很重要的一个化妆步骤,很多人都觉得自己的眼睛不够大不够有神,化眼妆能够很好的解决掉这个问题,大眼妆是每个人都很感兴趣的。画眼妆的步骤ST……
被造谣住院因流产,张常宁怒了我不在乎,不代表你可以为所欲为10月31日早晨,中国女排现役名将张常宁在个人社交媒体上写道:早上醒来,还没睡醒,看到朋友发的信息有点无语,我一直认为,造谣止于智者,却没想到‘傻子’这么多,是我高估了,……
悦诗风吟防晒乳为啥油物理防晒剂很多对于九十年代后出生的仙女们一定都对悦诗风吟怀有很深的感情这个来自韩国但是国内火爆的韩系品牌定位于年轻彩妆市场,利用靓丽的外包装设计和新颖的配方吸引大家购买,下面5号网小编带大家……
黑眼圈有几种类型黑眼圈遮瑕怎么选色号黑眼圈比较明显的人简直就是熊猫侠,有黑眼圈的人总是给人一种睡不醒的感觉,那么黑眼圈有几种类型,黑眼圈遮瑕怎么选色号。黑眼圈有几种类型1、青色的血管型黑眼圈该情况因为……
iQOONeo5骁龙87066W快充OIS光学防抖,价格降至iQOONeo系列和红米K系列一直都是针尖对麦芒,二者都是极致性价比的代言人。最近,iQOONeo5已开启了促销模式,在某平台开启了团购模式,最终秒杀价格低至2269元。iQO……
iPhone14爆料信息,将搭载4nm芯片和4800万三摄模根据海外知名博主爆料信息来看,下一代iPhone搭载的芯片将基于4nm制程工艺,比iPhone13所使用的5nm工艺相比,该芯片更胜一筹,下面我们就来简单地说一下大家最关心的配……
法甲1近4轮仅1胜北京时间1月30日凌晨3点45分,202223赛季法甲联赛第20轮迎来一场焦点战,卫冕冠军巴黎圣日耳曼坐镇主场王子公园球场对阵兰斯。上半场,巴黎遭到对手压制,两队都没有进球;下……
完美日记107是什么颜色完美日记107口红适合黄皮吗完美日记口碑真的很好,而且东西做得很有档次,加上价格非常亲民,因此很多人都喜欢购买她家的彩妆,完美日记107是最近很红的限量色,一起来看看试色吧。完美日记107是什么颜色……
可爱妆容怎么化改变五官的神奇彩妆术彩妆的力量真的很了不起,只要加点简单的技巧,就能创造出整形级的效果!除了留意单品的选择,技巧也需要多加练习。趁着新年长假,赶快把能瞬间提升可爱度的秘密技巧学起来吧!创造看……
伊芳妮素颜霜怎么样?伊芳妮素颜霜好吗?素颜霜是懒人打底必备单品,因此,很多女生都会备一瓶,出门约会随便一擦都可以美美的。那么,素颜霜哪个牌子好呢?伊芳妮素颜霜怎么样呢?伊芳妮素颜霜怎么样伊芳妮雪肌v7素……
美国紧凑型X射线光源成功发射第一束X射线2023年2月2日晚,位于美国亚利桑那州立大学的紧凑型X射线光源(CXLS)成功发射了第一束X射线,它将有望让科学家们在原子水平上观察各种关键的化学反应与生物结构。为了产……
可可妆怎么画baby仿妆化妆品推荐虽然酸民总是说Angelababy的演技辣眼睛,但她真的好漂亮啊!而且她的彩妆也很值得模仿~例如她最近常画的可可妆,不但能深邃五官,看起来又酷又可爱,无论上班画或是聚会画,回头……
素颜霜是隔离吗用素颜霜需要隔离吗素颜霜是一种市面上经常能见到的化妆品,很多女生都使用过素颜霜,而很多人会将素颜霜认作是隔离,那么我们便要了解一下素颜霜是隔离吗?用素颜霜需要隔离吗?素颜霜是隔离吗隔离霜是……
假睫毛是不是一次性的假睫毛是什么材料做的假睫毛也是化妆中很重要的一步,因为睫毛够多的话,就会显得眼睛很好看,于是有的姐妹就会贴假睫毛。那么假睫毛是不是一次性的呢?假睫毛是不是一次性的不是。假睫毛不是一次性的,可……
一加Ace2和iQOONeo7竞速版来袭,一加Ace沦为百元OPPO明确了一加的定位后,一加的产品策略也就很明显了,那就是向红米学习,死磕性价比,实际上除了一加这么干,vivo那边的iQOO差不多也是这个套路,那么这两位谁学习红米学得更……
过去的20年,产生了哪些汉语新词语?《汉语新词语词典(20002020)》侯敏编著一部多年本新词语词典。正文收录了2000年至2020年间产生的汉字开头的新词语4200余条,尤其关注人工智能、信……
气虚乏力,不可一味补气,气血同调是为上工之法我们中医中的气,有元气、精气、阳气、正气、宗气等。气的功能很多,可推动循环、加速代谢、温煦调节、固摄防御、消化运化、气化生育、导浊排泄等。一旦气虚证发生,身体的许多……
bb霜用洗面奶洗的掉吗bb霜用卸妆水吗晚上回家想要卸妆的时候发现卸妆水没有了,脸上就涂了bb和口红,用洗面奶洗应该可以吧?卸bb霜一定要用卸妆水吗?bb霜用洗面奶洗的掉吗洗面奶不能卸bb霜。要想彻底卸除bb霜……
最泰安新闻早报1月27日【市内】春节假期第六天我市旅游热度不减!接待游客30。3784万人次,同比增长109。21寅虎旧岁除,卯兔新春归。1月26日是农历正月初五,春节假期第六天,虽然假期已近尾……
美甲贴片是一次性的吗贴片美甲怎么样美甲是现在日常非常受欢迎的,很多女生都非常喜欢做美甲,同时美甲贴片也是很多女生都使用过的,那么我们便了解一下美甲贴片是一次性的吗?贴片美甲怎么样?美甲贴片是一次性的吗美甲……
2023年这些旗舰手机值得入手,三四年没有换机烦恼2022年已经划上句号,2023年重新启航,新老交替也是手机圈一贯传统,尤其是第二代骁龙8处理器的出现,各大手机厂商一个劲推新机,抢占市场,机圈也因此迎来了一波升级小高潮,涌现……
小米12发布日期基本确定,联想感谢雷总由于到了年底智能手机领域的大事从手机本身转移到了供应链上游,因为它关乎着2022年整体智能手机领域的发展与进步。所以高通骁龙8Gen1、联发科天玑9000就是行业讨论最多的话题……
塞拉斯埃里克戈登在我们落后时稳定局面这就是老将的存在直播吧2月2日讯火箭今日112106力克雷霆,取得两连胜。赛后,火箭主帅塞拉斯接受采访时称赞了队中老将埃里克戈登,后者拿到全场最高的25分。埃里克戈登今天如此稳定,当我们……
美甲延长胶好还是甲片好美甲延长怎么做通常大多数的女生都是非常爱美的,所以很多女生都非常喜欢美甲,而有些女生的指甲不够长,就会使用做延长,那么我们便了解一下美甲延长胶好还是甲片好?美甲延长怎么做?美甲延长胶好还是甲……