2023-01-16 | 初稿完成 |
2024-05-15 | 增加使用高版本MDK编译工程报错的解决方法 |
- MDK版本:Keil MDK_v5.35
- 标准库版本:STM32F10x_StdPeriph_Lib_v3.5.0
固件库可到 ST 社区下载(stmcu.org.cn 或 http://shequ.stmicroelectronics.cn),不过要下载需注册,有点繁琐。几天前逛网站发现官方已经将标准外设库更新到了3.6.0版本,之前很多人说停止更新了(毕竟有好久没更新了)
新建文件夹
复制相关库文件
新建空工程框架
添加文件到工程
配置工程
以 STM32103RCT6 为例。新建一个文件夹,文件夹名称看个人喜好:
库文件夹名 | 拷贝的文件 | 粘贴位置 |
---|---|---|
CoreSupport | core_cm3.c core_cm3.h | core |
arm | 启动文件 (依据自己具体单片机型号选择) | core |
inc | inc文件夹 | lib |
src | src文件夹 | lib |
STM32F10x | stm32f10x.h system_stm32f10x.c system_stm32f10x.h | user |
STM32F10x_StdPeriph_Template | stm32f10x_conf.h stm32f10x_it.c stm32f10x_it.h main.c(如果不复制就自己建一个) | user |
stm32f10x_it.c
和stm32f10x_it.h
是外设中断函数文件,用来编写中断服务函数,用户可以相应地加入自己的中断程序代码。
stm32f10x_conf.h
是配置文件,里面有很多#include。在建立工程时,可以注释掉一些不用的外设头文件。
关于启动文件:(可能有错,建议百度)
启动文件 | 容量大小 | 例如 |
---|---|---|
startup_stm32f10x_cl.s | 互联型 | STM32F105xx/107xx |
startup_stm32f10x_hd.s | 大容量 | STM32F101xx/102xx/103xx |
startup_stm32f10x_hd_vl.s | 大容量 | STM32F100xx |
startup_stm32f10x_ld.s | 小容量 | STM32F101xx/102xx/103xx |
startup_stm32f10x_ld_vl.s | 小容量 | STM32F100xx |
startup_stm32f10x_md.s | 中容量 | STM32F101xx/102xx/103xx |
startup_stm32f10x_md_vl.s | 中容量 | STM32F100xx |
startup_stm32f10x_xl.s | Flash在512K ~ 1024K字节 | STM32F101xx/102xx/103xx |
cl:互联型产品
vl:超值型产品
xl:超高容量产品,stm32f101/103系列
ld:低容量产品,Flash ≤ 32K
md:中容量产品,64K≤ SFlash ≤128K
hd:高容量产品,256KSFlash
① 点击选择 Manage Project Items 。将图中圈住的两个双击重命名(看自己需求):
② 建分组。在“Groups”追建两个组:core、lib。如下:
③ 给每个组添加库文件。user组、core组、lib组所添加的文件如下:
lib组的文件可以自主选择,只要自己轻车熟路,知道所使用的外设需要哪几个文件就行。
④ 最后点击 OK。
① 设置Output路径。选择自己建的 obj 文件夹。勾选生成hex文件的选项。如下:
如果不设置 Output 路径,则默认的编译中间文件存放在MDK自动生成的Objects文件夹和 Listings文件夹。其实不考虑规范性的话这一步可以不要。
② 配置全局宏定义变量。3.5版本的库函数在配置和选择外设的时候要通过宏定义来选择。可根据你选择的芯片或启动文件修改,STM32F10X_HD(大容量),STM32F10X_MD(中容量),STM32F10X_LD(小容量)。
STM32F10X_HD,USE_STDPERIPH_DRIVER
中的逗号是英文逗号。
③ 点击右边小按钮添加工程引用到的所有头文件的路径。每个头文件所在的文件夹为一条路径,我这里添加了三条路径(user文件夹、core文件夹、inc文件夹)。添加完毕点击 OK。
MDK_5.36 的这里默认使用AC6编译,这里不同的就改成AC5。
打开 user 组里的 main.c,复制下面代码到 main.c 进行编译。不报错并在 obj 文件夹里生成 hex 文件则说明工程无误。(记得在代码的最后一行再加上一个回车,否则会有编译警告,网上说是 MDK的 bug)
强调:给出的代码示例是没有错的。不要再跟我说什么复制的代码的错误,代码哪行有错之类的话了。请检查你的电脑、MDK或工程的配置
#include "stm32f10x.h"
void Delay(u32 count)
{
u32 i=0;
for(;i<count;i++);
}
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//使能PB,PE端口时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//LEDO --> PB.5端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHz
GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化GPIOB.5
GPIO_SetBits(GPIOB,GPIO_Pin_5);//PB.5输出高
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//LED1 --> PE.5推挽输出
GPIO_Init(GPIOE,&GPIO_InitStructure);//初始化GPIO
GPIO_SetBits(GPIOE,GPIO_Pin_5);//PE.5输出高
while(1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_5);
GPIO_SetBits(GPIOE,GPIO_Pin_5);
Delay(3000000);
GPIO_SetBits(GPIOB,GPIO_Pin_5);
GPIO_ResetBits(GPIOE,GPIO_Pin_5);
Delay(3000000);
}
}