下载
Keil 编译例程
编译两个按钮,一个向下是部分编译,两个向下箭头是全部编译。对于未编译文件两个按钮等效。
点击编译后,linking 是链接,结果里面的几个数据的意义代表大小:
数据类型 | 占用Flash or SRAM | 说明 |
---|---|---|
Code | Flash | 代码 (占用 FLASH 的大小) |
RO-Data | Flash | 只读数据,一般是指 const 修饰的数据 |
RW-Data | Flash and SRAM | 初值为非0的可读可写数据 |
ZI-Data | SRAM | 初值为0 的可读可写数据 |
前三项加起来是 FLASH 占用,后两个是 SRAM 占用。
双击项目名,会打开一个 .map 的文件,文件末尾也显示了上面各项的大小和 FLASH SRAM 占用大小。
基于寄存器的方式:和51单片机一样方法,程序直接控制寄存器,底层方法。但是 STM32 寄存器太多,不宜用此方法。
基于库函数:STM32 自己封装好的库函数。有利于提高开发效率。
基于 HAL 库的方式:可以通过图形化界面开发。但是隐藏了底层逻辑。
基于寄存器
我们用和 51单片机一样的方法新建工程文件后,是不能直接使用的。需要添加启动文件。
添加好启动文件和头文件后,新建 User 文件夹,代码模板如下:
#include "stm32f10x.h" // Device header
int main(){
while(1){
}
}
Configration 中编码设置为 UTF-8 防止中文乱码。
魔术棒-Debug-Use 改为 STLink 下载方式。右侧 Setting-Flash Download- 勾选 Reset and Run,这样每次下载后都会重新自动复位运行。
STLINK 接上对应线后应该是电源灯常亮,测试灯闪烁。
Build 并 Load 后,板子上的测试灯应该不闪烁了。因为程序中目前什么也没有。
下面尝试点亮灯。需要三个寄存器。
- RCC 寄存器。RCC 外设时钟使能寄存器翻阅手册可知是 APB2 的外设,在 RCC_APB2ENR 中配置。
4 IOPC EN 使能即打开 GPIOC 时钟。即赋值:0000 0000 0001 0000=0x00000010
- PC13 口。MODE13 就是配置 PC13 口的。
CNF13 要设置为推挽输出模式,即00. MODE 要配置为输出模式,最大速度 50MHZ 11。所以寄存器赋值 0x0030 0000
- 端口输出寄存器写入数据。13 号口设置为低电平点亮。即:0x00000000. 0x0000 2000 就会熄灭。
#include "stm32f10x.h" // Device header
int main(){
RCC->APB2ENR=0X00000010;
GPIOC->CRH=0X00300000;
GPIOC->ODR=0X00000000;
while(1){
}
}
可以看出,基于寄存器的程序编写非常麻烦!要不断的查手册,而且我们还不能影响到其他位,不能这样直接赋值,要通过 & | 确保其他位不受影响。
基于库函数
新建 Library 文件夹,添加老师给出的库函数文件。再在 MDK 中添加组。
再打开 STM32F10X.H 文件,其中有一句:
#ifdef USE_STDPERIPH_DRIVER
#include "stm32f10x_conf.h"
#endif
也就是说我们要定义这个东西,才能包含这个头文件。再手动定义一下。
记得还要 include path。有钥匙标志的是只读文件。
#include "stm32f10x.h" // Device header
int main(){
//查询函数的通用方法:右键-转到定义查看,如果详细信息在注释里,复制注释关键词 crtl f 搜索。
//enable clk
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//第一个参数:外设;第二个参数:新的状态。
//set PC13 pin
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//通用推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
//set e level of PC13
GPIO_SetBits(GPIOC,GPIO_Pin_13);//high level
//GPIO_ResetBits(GPIOC,GPIO_Pin_13);//low level
while(1){
}
}
寄存器部分自己查找引脚写的内容在库函数中被封装,我们只需要查询使用。
启动文件具体选择哪个?STM32F100 是超值系列,选择带 VL 的启动文件,再根据 FLASH 大小选择 LD MD HD。STM32F101/102/103 选择 D 结尾的。STM32F105/107 选择 CL 的。
总结新建工程套路:
- 新建 project,选择对应芯片型号。
- 新建 start library 文件夹,复制相关配置文件。
- 工程里新建对应的文件夹,添加相应配置文件。
- include relevant path 头文件。
- define 内定义 USE_STDPERIPH_DRIVER
- debug 中选择对应调试器(STLINK),settings-flash download-reset and run 勾选。
当然以后也可以建立自己风格的项目。
启动程序的原理:
复位中断:程序入口。复位时启动,会调用 system_xx.c (我们的程序中是 init)和 main.c,然后就结束了。
其他中断也在其中被初始化。定义在 stm32f10x_it.c 中。自己如果想定义中断系统建议写在 stm32f10x.c 中的 PPP_IRQHandler 处。
init 设置微控制器的启动,初始化闪存接口等,仅在复位后需要调用。
然后自己写的用户文件也在紫色部分初始化。有利于程序模块化。
右侧是被动执行的资源。右上角:外设、内核外设。右下角:封装的库函数文件。conf 头文件包含了所有头文件,又被 stm32f10x.h 所包含。
GPIO 通用 IO
General Purpose Input Output.
可配置为8种输入输出模式。通常0~3.3V,部分引脚允许 5V。
串口下载
flymcu 软件。
配置如下,一定要一模一样(串口可以不一样)。我就因为低电平复位没看清一直没成功。
F1 波特率最大可以460800. F4 可以是76800.
启动模式(M3 M4)
BOOT1 BOOT0 对应 x0:从主闪存存储器启动。
01:系统存储器开始启动(ISP 下载)。
11:内置 SRAM 开始启动。
运行还是要配置成 x0 存到主闪存中。为什么我们的电路可以只连接一次 00 就能下载到主存储器中?
如果不靠一键下载电路,我们就要像上面的步骤一样,先 01 再 x0。
DAP 下载
暂时先空一下。因为博主没有买仿真器。