参照 百度网盘中的 “STM32开发指南V1.0 库函数版本.pdf”
参照 Keil4编译原子哥的SYSTEM出现错误error: #1113: Inline assembler not permitted when generating Thumb code
需要 "百度网盘中的文件 mdk380a--keil3.rar"
需要 "百度网盘中的文件 STM32F10x_StdPeriph_Lib_V3.5.0.zip"
需要 "百度网盘中的文件 mcuisp.exe"
有时候 STM32F103zet6_Template_prj 简写为 _Template_prj
0. 格式约定:
如下格式
复制 : 来源目录/ ---到-> 目标目录/
来源目录中的文件1 来源目录中的文件2 ...
简写为:
: 来源目录/: --> 目标目录/
来源目录中的文件1 来源目录中的文件2 ...
1.新建项目目录结构 并 从 STM32F10x_StdPeriph_Lib_V3.5.0.zip 中复制相关文件
1.1 新建项目目录
新建项目目录 stm32f103zet6_template_prj/: (其下新建以下目录)
CORE USER STM32_FWLIB OBJ
1.2 复制文件到STM32_FWLIB
: STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/: ----> stm32f103zet6_template_prj/STM32_FWLIB
inc src
1.3 复制文件Libraries/CMSIS/CM3/CoreSupport/core_cm3.*到CORE
STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport/: ----> stm32f103zet6_template_prj/CORE
core_cm3.c core_cm3.h
1.4 复制文件Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/arm/*.s到CORE
-
因为是 stm32f103zet6 512k的FLASH , 选 startup_stm32f10x_hd.s hd是大容量
-
如果是 stm32f103rct6 128k的FLASH , 选 startup_stm32f10x_md.s md是中等容量
-
......... ld是小容量
: STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/arm/: ----> stm32f103zet6_template_prj/CORE
*.s
1.5 复制文件Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/:stm32f10x.h,system_stm32f10x.* 到USER
: STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/: ---> stm32f103zet6_template_prj/USER
stm32f10x.h system_stm32f10x.c system_stm32f10x.h
1.6 复制文件Project/STM32F10x_StdPeriph_Template/:main.c,stm32f10x_conf.h,stm32f10x_it.*到USER
:STM32F10x_StdPeriph_Lib_V3.5.0/Project/STM32F10x_StdPeriph_Template/: -> stm32f103zet6_template_prj/USER
main.c stm32f10x_conf.h stm32f10x_it.c stm32f10x_it.h system_stm32f10x.c 不要此文件
2. MDK3 (keil3) 新建项目
2.0 安装 MDK380a.exe
安装 "百度网盘中的文件 mdk380a--keil3.rar"/MDK380a.exe
2.1 新建项目
MDK3新建项目,项目文件放在 stm32f103zet6_template_prj/USER/ 下
"Copy STM32 Startup Code to Project Folder and Add File to Project ?" No 因为刚刚已经复制过启动代码了
2.2 项目中添加 步骤1 中建立的目录 USER , CORE , STM32_FWLIB
本节 简写 STM32F103zet6_Template_prj 为 _Template_prj Target 1 , 右键, Manage Component
Target 1 -> STM32F103zet6_Template Groups:
USER <--Add Files-- _Template_prj /USER/:main.c,stm32f10x_it.c,system_stm32f10x.c CORE <--Add Files-- _Template_prj /CORE:core_cm3.c,startup_stm32f10x_hd.s FWLIB <--Add Files-- _Template_prj /STM32_FWLIB/src/*
3 通过宏指定一些选项、添加头文件路径
3.1 定义宏: STM32F10X_HD,USE_STDPERIPH_DRIVER
"Options for Target stm32f103zet6_template_prj 魔术棒" -> c++
"Proprocessor Symbols".Define :
STM32F10X_HD,USE_STDPERIPH_DRIVER
3.2 添加头文件路径: ..\CORE;..\STM32_FWLIB\inc;..\USER
"Options for Target stm32f103zet6_template_prj 魔术棒" -> c++
"Include Paths":
..\CORE;..\STM32_FWLIB\inc;..\USER
4 main.c替换为led灯闪烁程序
#include "stm32f10x.h"
void Delay(u32 count)
{
u32 i=0;
for(;i<count;i++);
}
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_5);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_5);
while(1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_5); //端口PB5
GPIO_SetBits(GPIOE,GPIO_Pin_5); //端口PE5
Delay(3000000);
GPIO_SetBits(GPIOB,GPIO_Pin_5); //端口PB5
GPIO_ResetBits(GPIOE,GPIO_Pin_5); //端口PE5
Delay(3000000);
}
}
5. xxx??? (??usb转串口驱动??) 驱动安装
安装百度网盘中的驱动文件: "USB转485驱动.zip"
usb线插在有ch340芯片的那个口上, 可以正常识别出 "USB-SERIAL CH340 (COM4) "
6. 编译
6.1 编译输出目录设置为 stm32f103zet6_template_prj/OBJ/
keil3 , "魔术棒", Output, "Select Folder for Objects", 选择目录stm32f103zet6_template_prj/OBJ/
6.2 设置编译时需要生成 ".hex"文件
keil3 , "魔术棒", Output, 勾选"Create HEX File"
6.3 编译
点击 keil 的 build 以编译产生 stm32f103zet6_template_prj/OBJ/stm32f103zet6_template_prj.hex
7. 烧写程序 并 运行程序
打开 mcuisp.exe
EnumPort 找到上面安装好串口驱动时出现的串口 "USB-SERIAL CH340 (COM4) "
勾选"Run After ISP complete"
选择 “Reset@DTR Low(<-3v),ISP @RTS High”
点击"Start ISP", 以 写入刚的编译结果 stm32f103zet6_template_prj/OBJ/stm32f103zet6_template_prj.hex
写入程序后,所连接的开发板会立即执行程序
所以看到开发板的 端口PE5连的LED灯 、 端口PB5连的LED灯 都闪烁了 。
8. 加入SYSTEM目录
8.1 找一个例子项目
百度网盘中找一个演示例子项目,比如 "3,F103ZE例程-库函数版本.rar"/3,标准例程-库函数版本/例1 跑马灯/
8.2 例子项目中的SYSTEM目录如下
"3,F103ZE例程-库函数版本.rar"/3,标准例程-库函数版本/例1 跑马灯/SYSTEM/:
delay/: delay.c , delay.h sys/: sys.c , sys.h usart/: usart.c , usart.h
8.3 复制 例子项目中的SYSTEM目录到 stm32f103zet6_template_prj/下
形如 stm32f103zet6_template_prj/SYSTEM/delay,sys,usart/ : *.c, *.h
8.4 项目中添加 SYSTEM目录
8.4.1 项目中添加 SYSTEM目录中的*.c文件
和 步骤 2.2 类似
STM32F103zet6_Template , 右键, Manage Component
Groups:
SYSTEM <--Add Files-- stm32f103zet6_template_prj/SYSTEM/delay,sys,usart/ : *.c
8.4.2 项目中添加 SYSTEM目录中的*.h文件所在直接目录
和 3.2 类似
"Options for Target stm32f103zet6_template_prj 魔术棒" -> c++
"Include Paths": (追加以下内容)
;..\SYSTEM\delay;..\SYSTEM\sys;..\SYSTEM\usart
至此 完整的 "Include Paths": 是
..\CORE;..\STM32_FWLIB\inc;..\USER;..\SYSTEM\delay;..\SYSTEM\sys;..\SYSTEM\usart
8.5 SYSTEM目录下的".c ,.h"文件编码是gbk, 改为utf-8
8.6 弃用keil uvision3, 并改用keil uvision5
keil uvision3 没地方设置编码为utf-8, 但keil uvision5可以设置编码为utf-8, 故而只能弃用keil uvision3, 并改用keil uvision5
8.7 编译SYSTEM/sys/sys.c 报错,将其改写如下
8.7.1 原来的写法 报错
//原来的写法 报错
#include "sys.h"
//////////////////////////////////////////////////////////////////////////////////
//STM32F103ZE核心板
//系统中断分组设置化
//********************************************************************************
//THUMB指令不支持汇编内联
//采用如下方法实现执行汇编指令WFI
void WFI_SET(void)
{
__ASM volatile("wfi");
}
//关闭所有中断
void INTX_DISABLE(void)
{
__ASM volatile("cpsid i");
}
//开启所有中断
void INTX_ENABLE(void)
{
__ASM volatile("cpsie i");
}
//设置栈顶地址
//addr:栈顶地址
__asm void MSR_MSP(u32 addr)
{
MSR MSP, r0 //set Main Stack value
BX r14
}
8.7.2 改后的写法 不报错
//改后的写法 不报错
#include "sys.h"
//////////////////////////////////////////////////////////////////////////////////
//STM32F103ZE核心板
//系统中断分组设置化
//********************************************************************************
//THUMB指令不支持汇编内联
//采用如下方法实现执行汇编指令WFI
__asm void WFI_SET(void)
{
WFI;
}
//关闭所有中断
__asm void INTX_DISABLE(void)
{
CPSID I;
}
//开启所有中断
__asm void INTX_ENABLE(void)
{
CPSIE I;
}
//设置栈顶地址
//addr:栈顶地址
__asm void MSR_MSP(u32 addr)
{
MSR MSP, r0 //set Main Stack value
BX r14
}