DarkPill使用非8MHz晶振
预备知识
STM32的启动模式
RM0008:P33
DarkPill的BOOT0,BOOT1,Reset
DarkPill的BOOT0默认下拉,按下开关为高电平,BOOT1为串100K悬空(悬空是低电平),Reset默认上拉,按下开关复位
STM32的刷机方式
三种最常用的:
串口芯片刷机
RM0008: P60
“The values on the BOOT pins are lated on the 4th rising edge of SYSCLK after a reset(复位后,BOOT0引脚和nBOOT1位上的值在SYSCLK的第4个上升沿被锁存)”
SWD刷机
SWD接口直接连接Cortex-M3内核,无需复位操作,直接接上ST-LINK烧录
DFU刷机
外部高速晶振(HSE)与USB总线时钟
P1:
P12:
stm32f103支持晶振频率的范围为4-16Mhz的任意整数,要使USBCLK正常工作在48MHz,必须要使能HSE(外部高速时钟)和PLL,根据时钟树的顺序,可以得出下表,可见只要主频SYSCLK一样USB时钟频率就一样,72MHz主频下使用不同晶振只需修改PLL倍数(PLLMUL)
HSE频率(MHz) | PLLMUL | SYCLK(MHz) | 2xPLLCLK | USB预分频器 | USB时钟频率(MHz) |
---|---|---|---|---|---|
8 | x9 | 72 | 144 | /3 | 48 |
12 | x6 | 72 | 144 | /3 | 48 |
16 | x4 | 72 | 144 | /3 | 48 |
DFU的两种编程模式
关键词: ISP模式,IAP模式,自举驱动程序
“对于STM32F1系列,只有互联型子系列STM32 F105/STM32F107支持通过DFU方式实现ISP编程, 所谓ISP模式就是指MCU芯片出厂时内部已集成了DFU相关自举驱动代码,利用它并借助USB接口即可将用户应用程序下载进芯片。而其它STM32F1芯片即使带USB模块,若想利用DFU方式编程就只能自行编写DFU自举驱动,即通过IAP模式实现用户程序的下载或升级...” 👉 原文轻戳
在Aduino IDE下使用
Arduino_STM32
按照wiki里的Installation步骤(下载安装开发板包,安装Due开发板以间接安装g++工具链)
arduino环境支持的三种常见的烧录方式已经在DarkPill的README.md中演示
我们来说说使用stm32duino-bootloader实现USB-C烧录F103:
STM32duino-bootloader
作者是罗杰·克拉克(澳洲),他将maple-bootloader改良,让更多的F103开发板能以IAP模式实现DFU烧录程序,这么好的东西DarkPill是不是可以直接用呢?但经过测试发现,他老人家仓库里编译的二进制文件仅适用于板载8MHz晶振的F103,而我的目前DarkPill板载是3225 12Mhz晶振(大真空3225 8Mhz晶振刚下单,逃)
烧录stm32duino-bootloader
连接
ch340/FT232 | stm32f103 |
---|---|
RX | PA9 |
TX | PA10 |
GND | GND |
烧录
烧录的STM32duino-bootloader与3225晶振频率的对应表:
HSE | bin |
---|---|
8MHz | generic_boot20_pc13.binor generic_boot20_pc13_8MHz.bin |
12MHz | generic_boot20_pc13_12MHz.bin |
16MHz | generic_boot20_pc13_16MHz.bin |
以上bootloader文件在DarkPill github仓库的“STM32duino-bootloader for DarkPill”文件夹里,如何编译请看解决stm32duino-bootloader晶振频率不匹配
将正确的bootloader复制到arduino-1.8.10\hardware\Arduino_STM32\tools\win的目录下,在这个目录有stm32flash.exe烧写工具,我们接下来要使用它
在目录栏直接输入cmd
回车唤出黑白命令框
执行stm32flash.exe -w generic_boot20_pc13.bin -v -g 0x0 COM23
注:上方命令最后的COM后的数字取决于你串口烧录器的端口号
使用CH340正常烧录:
1 | D:\arduino-1.8.10\hardware\Arduino_STM32\tools\win>stm32flash.exe -w generic_boot20_pc13.bin -v -g 0x0 COM23 |
烧录后,需要按一次reset,会执行stm32duino-bootloader自带的例程:PC13的LED飞速闪烁几下
打开设备和管理器,可以看到Maple DFU:
但它还没有被win10识别为COM端口,所以还要安装驱动程序,到arduino-1.8.10\hardware\Arduino_STM32\drivers\win目录下,以管理员身份先后运行install_drivers.bat和install_STM_COM_drivers.bat批处理程序,等待驱动安装,提示如下:
install_drivers.bat | install_STM_COM_drivers.bat |
---|---|
之后,你发现安装完成后STM32F103还是没有被识别为COM号,所以请继续:
打开arduino ide,选择一个基础例程程序,在COM为灰色的情况下上传,ide会自动识别Maple DFU
然后下次就能正常识别为COM了
若晶振频率不匹配
Arduino IDE默认的Generic STM32FC series的Crystal默认是8Mhz,如果Darkpill的HSE为12MHz或16MHz,那么Blink程序闪烁速度会比8Mhz快,串口波特率也同理(会收不到信息或者乱码),所以,需要修改开发包里的HSE或者PLL的值
那么,我们开始找吧!
在Arduino_STM32\STM32F1\core\maple下的boards.h文件里有以下两行代码:
即:
1 |
那么我们在boards.h文件文件包含的头文件里找找CYCLES_PER_MICROSECOND这个宏
1 |
找了一圈,锁定了board.h文件(注意与boards.h不同),board.h文件有很多个,找到在开发板管理器里选用的gerneric_stmf103c的board.h打开:
打开后,文件里有以下一行代码:
可见CYCLES_PER_MICROSECOND由F_CPU定义,我们再去找F_CPU,然鹅,board.h没有包含头文件,我们到其根目录去找找:
在Arduino_STM32、STM32F1\variants\generic_stm32f103c\wirish的boards_setup.cpp里找到了处理F_CPU的宏,可见50到64行代码是根据预设的F_CPU的值来定义PLL倍频值,与常见的先定义倍频再定义主频相反😳
那么在到他包含的头文件里找。。。。
算了看看这个issue:F_CPU在什么时候定义?,这个issue也不是,它是Arduino_Core_STM32的F_CPU
我们直接到STM32duino的仓库找吧,下面是F1和F4的,在一个txt文件里定义,估计是脚本程序运行的,知识的盲区😳
既然这样,直接把72MHz PLL的倍频改为12MHz下的倍数不就行了😢
还是打开STM32F1\variants\generic_stm32f103c\wirish的boards_setup.cpp文件,修改为6即可:
测试5秒的Blink程序修改前后对比,修改后正常了,串口也正常了
在Keil MDK环境下使用
下载最新版的MDK5.31
下载对应stm32系列的MDK5 Software Packs包
MDK5.29,5.30,5.31和各种软件包镜像下载(2020-07-03)
配置MDK工程模板
配置过程中与视频中正点原子战舰的区别
DarlPill使用F103C8T6,战舰使用F103ZET6,工程模板仅仅芯片闪存MD与HD的区别,有以下两处:
启动文件
F103C8T6使用startup_stm32f10x_md.s
F103ZET6使用startup_stm32f10x_hd.s
全局宏定义
Option for target的C/C++栏里的preprocesor symbols的define:
F103C8T6使用STM32F10X_MD,USE_STDPERIPH_DRIVER
F103ZET6使用STM32F10X_HD,USE_STDPERIPH_DRIVER
首次编译问题
按照原子哥的教程配置好工程模板后,编译,最前面前几句报错:
1 | ../CORE/core_cm3.c(445): error: non-ASM statement in naked function is not supported |
问题解决:
修改后,再次编译没问题了:"..\OBJ\Temp.axf" - 0 Error(s), 0 Warning(s).✅
编译视频最后的原子哥的闪烁程序,用FlyMCU上传,第0~5部步骤如下:
上图第5步后,FLyMCU会显示开始连接,这时,按住boot0不放,按一次Reset,FlyMCU会上传,测试OK(我用D1 mini的CH340上传的)
如果没有在OBJ目录找到编译生成的hex文件,看看视频里勾选生成hex那步是不是忘了
晶振及倍频修改
STM32系列修改外部晶振以及代码的修改
解决stm32duino-bootloader晶振频率不匹配
折腾了好久,发现烧录了maple mini bootloader的stm32win10就是不识别设备,估计是外部晶振的频率是12Mhz造成的,几经辗转,看到了STM32duino的社区里帖子STM32F103上将时钟设置为72Mhz,这位使用F103的老外用16Mhz的晶振代替8MHz的晶振,然后使用maple mini的bootloader USB就是发现不了F103, 伯恩特» 2018年10月5日星期五上午11:39的回答截取了maple mini 定义USB总线时钟频率的一段代码,可以知道由PLL倍频器的值定义:
那么他的USB不识别肯定由于16MHz晶振导致USB的时钟不在协议频率范围里了,巧了,在该帖的最下面发现了STM32duino-bootloader的作者罗杰·克拉克的回答,看来USB频率不对实锤了:
那么,现在我们有用的信息是,maple mini bootloader的代码中定义了USB的驱动,根据PLL的值与外部晶振的频率定义了USB的时钟,我用12MHz的晶振导致USB时钟的速度比8MHz快1.5倍,我们可以列出下表:
开发板 | CPU频率(MHz) | 晶振频率(MHz) | USB时钟频率(MHz) | PLL倍频 | USB时钟频率为晶振的多少倍? |
---|---|---|---|---|---|
BluePill(正确) | 72 | 8 | 48 | 9 | 6 |
DarkPill(错误) | 108 | 12 | 72 | 9 | 6 |
DarkPill(正确) | 72 | 12 | 48 | 6 | 4 |
拓展阅读:USB时钟为什么是48MHz?
重新编译stm32duino-bootloader
先把STM32duino-bootloader的整个git仓库下载下来,解压
你会发现这个stm32工程使用Makfile管理编译,别怕,我们先Win10下搭建STM32开发环境,将make和gnu_arm嵌入式工具链装好,能在PowerShell中唤出版本信息即可:
然后请粗略了解一下Linux 下 Make 命令如何工作的?中的“规则“概念
在PowerShell里进入解压的STM32duino-bootloader的目录,先来个make命令,看看报什么错
看来是抛出了config.h里的#error
在config.h里加一句黄色框内的
,再次编译,执行
- make clean
- make
OK不报错了,但是build文件夹里bin文件是0KB咋回事?
打开Makefile看看,因为make后不带参数默认执行make all,然而我们发现Makefile里的all规则默认啥也不执行:
所以我们要执行
- make clean
- make generic-pc13
实例如下:
Ok,build文件夹里的maple_boot.bin大小正常了:
那么,接下来,修改USBCLK的频率,在github里搜索整个仓库,发现上文伯恩特提到的setuoCLK()在hardware.c里定义:
打开harware.c,发现作者还很贴心:
若HSE为12MHz,我们直接在 #elif defined TARGET_GENERIC_F103_PC13下加一句#define XTAL12M即可,若为16MHz,则加#define XTAL16M
最后执行
- make clean
- make generic-pc13
完工!
参考:
STM32F103C8T6 使用DFU
- 本文链接: http://oldgerman.github.io/201e530f/
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!