STMCU小助手
发布时间:2022-5-23 22:00
|
今日接手用stm32f100xx芯片开发的项目,以前用的是stm8s 和stm32f103xx芯片;因为在别人的项目代码的基础上做2次开发,但是发现那个代码main函数中没有对系统时钟的设置的相关函数,一直纳闷,但也没有深究,直至昨日 调试时出现串口收发数据出错,源代码在原项目的板子上串口发送、接收数据正常,同样程序在项目板子上收发的数据不正确, 两块板子芯片一样,串口收发管脚一样,最后发现原来板子外部晶振是8MHZ ,新板子外部晶振是12MHZ; 而在STM32固件库中,默认的外部晶振是8MHZ,由于时钟源不正确,导致波特率不正确,当然收发的数据也不正确了.....我勒个去!都怪自己平时看问题“不求甚解”。 (波特率与时钟源关系公式:IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate))) 为了深入思考,我提出了一些疑问,通过解答这些问题更深入的了解时钟; 问题一:对系统时钟的设置的相关函数,在main函数中找不到,那在哪里?还是说根本没有对系统时钟进行配置? 问题二:既然用了外部晶振做系统时钟,那为什么没看到启动外部晶振的操作? 问题三:串口的时钟源是什么?串口时钟源跟系统时钟的关系? 问题四:程序中串口时钟源是怎样实现对波特率的关系的? 现附上我找到上面3个问题答案做的一张框架图:希望博友参考此图理解我后面的内容: 在进入主题之前我们先了解一些必要的基础知识----stm32系列芯片的种类和型号: startup_stm32f10x_cl.s 互联型的器件,STM32F105xx,STM32F107xx startup_stm32f10x_hd.s 大容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_hd_vl.s 大容量的STM32F100xx startup_stm32f10x_ld.s 小容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_ld_vl.s 小容量的STM32F100xx startup_stm32f10x_md.s 中容量的STM32F101xx,STM32F102xx,STM32F103xx startup_stm32f10x_md_vl.s 中容量的STM32F100xx (我项目中用的是此款芯片 stm32f100CB) startup_stm32f10x_xl.s FLASH在512K到1024K字节的STM32F101xx,STM32F102xx,STM32F103xx cl:互联型产品,stm32f105/107系列 vl:超值型产品,stm32f100系列 xl:超高密度产品,stm32f101/103系列 ld:低密度产品,FLASH小于64K md:中等密度产品,FLASH=64 or 128 hd:高密度产品,FLASH大于128 (下图中的startup_stm32f10_ld.s应改为:startup_stm32f10x_md_vl.s)
问题一:对系统时钟的设置的相关函数,在main函数中找不到,那在哪里?还是说根本没有对系统时钟进行配置? 解答:高人指点,我看了一下启动文件startup_stm32f10x_md_vl.s,其中有一段汇编: <strong>; Reset handler routine Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit LDR R0, =<span style="color:#ff0000;">SystemInit </span> BLX R0 LDR R0, =__main BX R0 ENDP </strong> 其中, IMPORT __main IMPORT SystemInit //IMPORT 声明了需要引用C语言中的main函数、systeminit函数, LDR R0, = systeminint //把systeminit 函数地址放到r0 寄存器; BLX R0 //跳到到R0 寄存器中的地址执行; 所以,在跳到main函数执行前,已经在SystemInit 函数中把系统时钟给设置好了; 问题二:既然用了外部晶振做系统时钟,那为什么没看到启动外部晶振的操作? 我们在解答这个问题前,先到SystemInit函数里面做更深入的了解:
我们进入setsysclock()函数,看其中作了哪些操作:
我项目中用的是此款芯片 stm32f100CB,内部晶振是24MHZ, 所以应进入执行SetSysClockTo24() 函数:
解析: void SetSysClockTo24函数中主要做了下面几件事:(不同颜色功能分别对应上面对应颜色代码部分) 1.启动外部晶振作为系统时钟源; 2.等待外部晶振起振; 3.(起振后)对系统时钟源进行分频:(默认外部是HSE--8MHZ晶振) PLL configuration: = (HSE / 2) * 6 = 24 MHz 4. 配置HCLK、PCLK1、PCLK2 与系统时钟源的关系; 问题三:串口的时钟源是什么?串口时钟源跟系统时钟的关系? 回答这个问题前,我们先来看stm32f100芯片手册数据图(第12页):
从图里面我们可看出串口1的时钟源是PCLK1; 上面问题2的代码中我们看到PCLK1是时钟源24MHZ的1分频,即还是24MHZ; 问题四:程序中串口时钟源是怎样实现对波特率的关系的? 由问题3我们知道串口时钟源是24mhz,依据公式:IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate))) 库中自动设置IntegerDivider 存入寄存器中; (1) 在KEIL下可以在项目的选项C/C++/PREPROMCESSOR symbols的Define栏里定义,比如STM32F10X_CL 也可以在STM32F10X.H里用宏定义 #if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL) #define STM32F10X_HD #endif (2) 如果芯片更换,除了做如上所述的更改外,还需以下几步 第一步 system_stm32f10x.c的系统主频率,依实际情况修改 #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) #define SYSCLK_FREQ_24MHz 24000000 #else #define SYSCLK_FREQ_72MHz 72000000 #endif 另外外部时钟在文件:stm32f10x.h 依实际修改 第二步 定时器的参数依系统主时钟做适当修改 第三步 flash地址misc.h中的NVIC_VectTab_Flash 0x08000000 要与KEIL选项target的IROM1的地址一致,如果是IAP程序,依ISP程序占用大小,APP的FLASH地址向后延,比如0X8002000,那么KEIL选项target的IROM1的地址也要就0x8002000,SIZE因为ISP占用了2000,所以就为0x40000-0x2000,即只能填写0X3E000 ISP程序与APP程序连接 打开 User 选项卡 在 Run User Programs Before Build/Rebuild 中,勾选 Run#1,并在 其中填入 D:\Keil\ARM\BIN40\fromelf.exe --bin -o ./obj/Project.bin ./obj/Project.axf 其中,Project.bin 和 Project.axf 要和 Output 选项卡中的 Name of Executable 的名字 IAP我的总结 1 先FLASH_Unlock(); 2 小于或等于128K的STM每页为1k bytes,大于128K的每页为2K BYTES,减去从地址0x8002000占用的0x2000后,算出页数,比如IAP占用8K,则64K的MD的STM32F系列用for(i=0;i<(64-8);i++) FLASH_ErasePage(0x8002000+0x400*i);循环按页擦除FLASH 3 按从外部串口获取到的数据,FLASH_ProgramWord(address,dat);//注意是按4字节方式写入的 if (*(uint32_t*)address!= dat)//字编程后校验 |
【经验分享】STM32 HAL库移植FreeModbus详细步骤
【逢7发帖赢大礼】STM32开发之IC门禁卡UID读取方法!
实战经验 | Keil工程使用NEAI库的异常问题
经验分享 | FDCAN数据段波特率增加后发送失败的问题分析
STM32几种流行开发环境的优缺点
好用软件推荐-TouchGFX Designer
OpenSTLinux 6.1发布:M33-TD加持+安全升级,STM32MPU开发效率翻倍!
【经验分享】STM32CubeIDE汉化
手把手教你VSCode搭建STM32开发环境
RTOS在STM32中的应用
微信公众号
手机版