打印
[应用相关]

STM32F103C8T6 cubeMX HAL库 从环境到开发 正点原子工程移植 freeRTOS

[复制链接]
4003|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
正常安装cubeMX后点击软件的这里添加包支持,我需要开发STM32F103C8T6。

使用特权

评论回复
沙发
xiaoqizi|  楼主 | 2021-7-5 14:04 | 只看该作者
1 闪烁PC13的小灯

1.1 新建工程


使用特权

评论回复
板凳
xiaoqizi|  楼主 | 2021-7-5 14:05 | 只看该作者
1.2 找到芯片,开始配置。顺便一提,这里可以看到芯片的的特性、资源图、手册,真是不要太perfect。

使用特权

评论回复
地板
xiaoqizi|  楼主 | 2021-7-5 14:05 | 只看该作者
1.3 熟悉配置界面
RCC时钟外部输入打开,实物板子的外部时钟有8MHZ和32768HZ,外部8MHZ可以使得时钟达到最高的72MHZ,没有外部8MHZ内部时钟最高能调到64MHZ。没有外部32768HZ,内部的RTC模块工作不正常。下图是打开了的。一些情况下,设置外部时钟输入这不是必须的。


使用特权

评论回复
5
xiaoqizi|  楼主 | 2021-7-5 14:05 | 只看该作者
一定要做的事情,设置debug方式,我用的STLINK 2线下载,SWDIO SWCLK下载,设置为这个。

使用特权

评论回复
6
xiaoqizi|  楼主 | 2021-7-5 14:05 | 只看该作者
配置PC13端口为输出。左键点击引脚设置即可。

使用特权

评论回复
7
xiaoqizi|  楼主 | 2021-7-5 14:05 | 只看该作者

时钟配置中有芯片时钟的详细配置,非常详细。我没开外部晶振输入,用的内部的,图里有颜色的就是线路,可见RTC没打开,内部40KHZ工作不工作无所谓。点击HCLK可以自己设置一个时钟,我设置为16MHZ。


使用特权

评论回复
8
xiaoqizi|  楼主 | 2021-7-5 14:05 | 只看该作者
工程名字写好后,创建代码。

使用特权

评论回复
9
xiaoqizi|  楼主 | 2021-7-5 14:06 | 只看该作者

直接打开。


加逻辑代码:

HAL_Delay(1000);HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
  • 1
  • 2


使用特权

评论回复
10
xiaoqizi|  楼主 | 2021-7-5 14:06 | 只看该作者
设置debug

下载后即可运行。

使用特权

评论回复
11
xiaoqizi|  楼主 | 2021-7-5 14:06 | 只看该作者
2 正点原子工程移植 注意点以及细节
cubeMX缺点就是没printf、没delay_us,而且实际开发需要一些传感器,自己去搞就是重复造轮子,所以需要正点原子的例子支持。

过程简单粗暴,RCC中打开2个外部时钟输入,打开SYS中debug(!!注意,如果关了调试端口后不然下次只能串口下载了,很烦人),SYS中使用sysTick,使能USART1(这样cubeMX能把h啥的HAL依赖加进来,后面就不用自己加了,比较舒服,cubeMX把这些初始化,我们一样可以在keil里把初始化删了,不影响骚操作。其他的资源同理,比如需要ADC1就cube里加了再说,后面不想要就自己keil里删除)。


使用特权

评论回复
12
xiaoqizi|  楼主 | 2021-7-5 14:07 | 只看该作者
得到的keil工程,直接把原子的下面6个文件复制到.\Core\Src(main.c也在这里)中。

使用特权

评论回复
13
xiaoqizi|  楼主 | 2021-7-5 14:07 | 只看该作者
keil中添加上c文件,会得到下面这样的结构。

使用特权

评论回复
14
xiaoqizi|  楼主 | 2021-7-5 14:07 | 只看该作者
在main.c中添加包含

#include "sys.h"
#include "delay.h"
#include "usart.h"



然后修改main(),删除UART初始化函数(声明、定义、调用都删除),删除时钟初始化函数(声明、定义、调用都删除),全部用原子的。

Stm32_Clock_Init( RCC_PLL_MUL9 );                                                               /* 设置时钟,72M */
        delay_init( 72 );                                                                               /* 初始化延时函数 */
        uart_init( 115200 );                                                                            /* 初始化串口 */




使用特权

评论回复
15
xiaoqizi|  楼主 | 2021-7-5 14:07 | 只看该作者
点编译会出现下面这结果,就是说重复定义了,因为开始的时候用了cubeMX生成了UART1的东西和院子的重复了。

Build target 'DDDDD'
compiling main.c...
linking...
DDDDD\DDDDD.axf: Error: L6200E: Symbol USART1_IRQHandler multiply defined (by stm32f1xx_it.o and usart.o).
DDDDD\DDDDD.axf: Error: L6200E: Symbol HAL_UART_MspInit multiply defined (by stm32f1xx_hal_msp.o and usart.o).
Not enough information to list image symbols.
Not enough information to list the image map.
Finished: 2 information, 0 warning and 2 error messages.
"DDDDD\DDDDD.axf" - 2 Error(s), 0 Warning(s).
Target not created.
Build Time Elapsed:  00:00:01


使用特权

评论回复
16
xiaoqizi|  楼主 | 2021-7-5 14:08 | 只看该作者
打开.\stm32f1xx_hal_msp.c找到void HAL_UART_MspInit(UART_HandleTypeDef* huart),然后可以直接把这个函数删除掉,或者像下图这样添加__weak关键字,keil发现有2处相同定义时优先用没带__weak关键字的定义,自然就用原子的定义了。



使用特权

评论回复
17
xiaoqizi|  楼主 | 2021-7-5 14:08 | 只看该作者
打开…/Core/Src/stm32f1xx_it.c,同样修饰一下定义void USART1_IRQHandler(void)
打开…/Core/Src/stm32f1xx_it.h去修饰一下声明__weak void USART1_IRQHandler(void);这个操作无所谓,声明而已,可以不修饰。



__weak void USART1_IRQHandler(void);


再次编译就不会有错了。


使用特权

评论回复
18
xiaoqizi|  楼主 | 2021-7-5 14:09 | 只看该作者
一些细节:
细节1:原子的CORE文件和cubeMX的CMSIS效果一样的。
图1 原子的CORE文件

cubeMX的CMSIS

使用特权

评论回复
19
xiaoqizi|  楼主 | 2021-7-5 14:09 | 只看该作者
细节2:
stm32f1xx_it.c/stm32f1xx_it.h里面是中断服务函数的定义和声明,除了SysTick_Handler和USART1_IRQHandler,其他的基本都是单片机发生异常后进入中断就再也出不去了(死机),比如发生数值溢出,keil编译的时候是不可预知这种错误的,单片机靠这个机制让自己”死掉“。

void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
__weak void USART1_IRQHandler(void);


使用特权

评论回复
20
xiaoqizi|  楼主 | 2021-7-5 14:09 | 只看该作者
细节3:
stm32f1xx_hal_msp.c 文件,这文件是ST公司推出HAL的主要目的,弱化硬件配置难度,下面一段话引用自原子书籍。

MSP,全称为 MCU support package,关于怎么理解 MSP,我们后面在讲解程序运行流程的时
候会给大家举例详细讲解,这里大家只需要知道,函数名字中带有 MspInit 的函数,它们
的作用是进行 MCU 级别硬件初始化设置,并且它们通常会被上一层的初始化函数所调用,
这样做的目的是为了把MCU相关的硬件初始化剥夺出来,方便用户代码在不同型号的MCU
上移植。stm32f1xx_hal_msp.c 文件定义了两个函数 HAL_MspInit 和 HAL_MspDeInit。这两个
函数分别被文件 stm32f1xx_hal.c 中的 HAL_Init 和 HAL_DeInit 所调用。HAL_MspInit 函数的
主要作用是进行 MCU 相关的硬件初始化操作。例如我们要初始化某些硬件,我们可以硬
件相关的初始化配置写在 HAL_MspDeinit 函数中。这样的话,在系统启动后调用了 HAL_Init
之 后 , 会 自 动 调 用 硬 件 初 始 化 函 数 。 实 际 上 , 我 们 在 工 程 模 板 中 直 接 删 掉
stm32f1xx_hal_msp.c 文件也不会对程序运行产生任何影响。对于这个文件存在的意义,我
们在后面讲解完程序运行流程之后,大家会有更加清晰的理解。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

85

主题

4090

帖子

3

粉丝