完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
线路连接
1、20脚JTAG/SWD调试接口接法: 参考电压信号,用于检测目标板是否供电,直接与目标板VDD相连,并不向外提供输出电压; GND:公共地信号; SWDIO:串行数据输入信号,作为仿真信号的双向数据信号线,建议上拉; SWCLK:串行时钟输入,作为仿真信号的时钟信号线,建议下拉; SWO:串行数据输出,CPU调试接口可通过SWO输出一些调试信息,该引脚可选。 RESET:仿真器输出至目标CPU的系统复位信号;是可选信号 下载完程序并提供电源,Debug模式下,下载完成后依然供电 2、USB转串口 功能:将串口收发数据转换成USB数据,接到电脑USB配合串口调试助手使用,方便检查串口收发信息 驱动:常用驱动CH340,过时驱动 3、开发板电源问题 STM32不能提供5V电压,51似乎可以 新建工程文件常出现的错误 1、缺少启动文件 编译的时候会报错,error: L6236E: No section matches selector - no section to be FIRST/LAST. 查看左边Project目录下Drivers/CMSIS文件下缺少.s 文件。直接从旧的工程里拷贝,右键该文件夹在菜单列表选品字型图标,添加即可。 2、Keil 软件仿真出现 Error: Flash Download failed - “Cortex-M4” 的解决方法 打开KEIL即显示缺少库文件(但已经安装了),强行退出下载界面,编译出现Error: Flash Download failed - "Cortex-M4"错误。依次点击魔法棒、Debug、setting、flash dowmload可以看到缺少flash文件 解决方法:在强行退出的最后一步(创建工程的页面)选择合适的芯片即可 CubeMX配置 时钟树 什么是时钟 时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏,决定cpu速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口,ADC),时钟的重要性不言而喻。 为什么 STM32 要有多个时钟源呢 STM32本身十分复杂,外设非常多 但我们实际使用的时候只会用到有限的几个外设,使用任何外设都需要时钟才能启动,但并不是所有的外设都需要系统时钟那么高的频率,为了兼容不同速度的设备,有些高速,有些低速,如果都用高速时钟,势必造成浪费 并且,同一个电路,时钟越快功耗越快,同时抗电磁干扰能力也就越弱,所以较为复杂的MCU都是采用多时钟源的方法来解决这些问题。所以便有了STM32的时钟系统和时钟 STM32为了低功耗,他将所有的外设时钟都设置为disable(不使能),用到什么外设,只要打开对应外设的时钟就可以, 其他的没用到的可以还是disable(不使能),这样耗能就会减少。 这就是为什么不管你配置什么功能都需要先打开对应的时钟的原因 STM32的时钟系统框图 乍一看很吓人,但其实很好理解,我们看系统时钟SYSCLK 的左边 系统时钟有很多种选择,而左边的部分就是设置系统时钟使用那个时钟源, 系统时钟SYSCLK 的右边,则是系统时钟通过AHB预分频器,给相对应的外设设置相对应的时钟频率 从左到右可以简单理解为 各个时钟源—>系统时钟来源的设置—>各个外设时钟的设置 时钟系统 各个时钟源 (左边的部分) STM32 有4个独立时钟源:HSI、HSE、LSI、LSE。 ①、HSI是高速内部时钟,RC振荡器,频率为8MHz,精度不高。 ②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。 ③、LSI是低速内部时钟,RC振荡器,频率为40kHz,提供低功耗时钟。 ④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。 其中LSI是作为IWDGCLK(独立看门狗)时钟源和RTC时钟源 而独立使用 而HSI高速内部时钟 HSE高速外部时钟 LSI低速内部时钟 这三个经过分频或者倍频 作为系统时钟来使用 PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。 通过倍频之后作为系统时钟的时钟源 HAL 库 __weak 修饰符 “weak” 顾名思义是“弱”的意思,所以如果函数名称前面加上weak 修饰符,我们一般称这个函数为“弱函数”。 加上了weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak 声明的函数,并且编译器不会报错。 举个例子: 我们打开工程模板,找到并打开文件stm32f4xx_hal.c 文件,里面定义了一个函数 HAL_MspInit,定义如下: __weak void HAL_MspInit(void) { __IO uint32_t tmpreg = 0x00; UNUSED(tmpreg); } // 可以看出,HAL_MspInit 函数前面有加修饰符__weak。同时,在该文件的前面有定义函数HAL_Init,并且 HAL_Init 函数中调用了函数 HAL_MspInit。 HAL_StatusTypeDef HAL_Init(void) { …//此处省略部分代码 HAL_MspInit(); return HAL_OK; } 如果我们没有在工程中其他地方重新定义 HAL_MspInit()函数,那么 HAL_Init 初始化函数执行的时候,会默认执行 stm32f4xx_hal.c 文件中定义的 HAL_MspInit 函数,而这个函数没有任何控制逻辑。 如果用户在工程中重新定义函数 HAL_MspInit,那么调用 HAL_Init 之后,会执行用户自己定义的 HAL_MspInit 函数而不会执行 stm32f4xx_hal.c 默认定义的函数。也就是说,表面上我们看到函数 HAL_MspInit 被定义了两次,但是因为有一次定义是弱函数,使用了__weak修饰符,所以编译器不会报错。 总结: weak 在回调函数的时候经常用到。这样的好处是,系统默认定义了一个空的回调函数,保证编译器不会报错。同时,如果用户自己要定义用户回调函数,那么只需要重新定义即可,不需要考虑函数重复定义的问题,使用非常方便,在 HAL 库中weak 关键字被广泛使用。 |
|
|
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 04:40 , Processed in 1.162090 second(s), Total 83, Slave 63 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号