单片机:Single-Chip Microcomputer,单片微型计算机,是一种集成电路芯片
CPU:CPU
内存:SRAM
硬盘:FLASH
主板:外设
仪器仪表:电源/示波器/焊台
家用电器:空调/冰箱/洗衣机
工业控制:机器人/PLC/电梯
汽车电子:GPS/ABS/胎压监测
:数据与程序储存在同一存储器,分时复用
CoreMark分数:https://www.eembc.org/coremark/scores.php
ARM公司官网:https://www.arm.com/
ARM开发者官网:https://developer.arm.com/
STM32:
ST:意法半导体 M:MCU/MPU 32:32位
ST累计推出了:5大类、18个系列、1000多个型号的Cortex内核微控制器
ST中文社区网:https://www.stmcu.org.cn
ST官网: https://www.st.com
正点原子论坛:www.openedv.com/forum.php
STM32 主要分两大块, MCU 和 MPU, MCU 不能跑 Linux,而 MPU可以跑 Linux。
芯片的基本参数:
1,主频/FLASH/SRAM
2,工作电压/最大电流
3,IO引脚接入电压范围
4,单个IO引脚最大电流
获取MDK:
MDK安装 = MDK软件安装 + 器件支持包
MDK软件下载:https://www.keil.com/download/product
器件支持包下载:https://www.keil.com/dd2/pack/
拷贝下载算法到Flash文件夹,如 D:\MDK5.34\ARM\Flash(可选)
安装CH340 USB虚拟串口驱动,数据线插入开发板中
程序在Projects\MDK-ARM中
I/O :表示输入/输出引脚
编译结果看:Build Output窗口
数据类型:占用Flash or SRAM:说明
Code:表示代码大小
RO-Data:表示只读数据所占的空间大小,一般是指 const 修饰的数据大小。
RW-Data:初值为非 0的可读可写数据
ZI-Data:初值为0 的可读可写数据
FLASH占用:Code+RO+RW
SRAM占用:RW+ZI
hex文件在Output中
利用串口给 STM32 下载代码:
USB_UART 通过 USB 线连接电脑->电源灯亮起(蓝色)->USART1的 RXD、PA9,TXD 、PA10通过跳线帽连接->BOOT0、GND,BOOT1、GND通过跳线帽连接->按一下复位按键->使用上位机软件下载代码->双击打开 ATK-XISP->波特率推荐设置为 76800->选择 DTR 的低电平复位,RTS 高电平进 BootLoader->下载成功后,会有“共写入 xxxxKB,进度 100%,耗时 xxxx 毫秒”
使用 DAP 下载与调试程序:
DAP 通过 USB 线连接电脑,通过 20P 灰排线连接开发板->开发板供电->
打开MDK IDE:
魔术棒->Debug->use: CMSIS-DAP Debugger->勾选Run to main->
点击 Settings->Port:SW->Max Clock:8Mhz->
Utilities ->勾选 Use Debug Driver->点击 Settings->选中 Reset and Run->如果没有 flash 算法,点击 Add 按钮自行添加->
F7 ->F8
使用 DAP 仿真调试程序:
Register:寄存器窗口
Disassembly:反汇编窗口,方便从汇编级别查看程序运行状态
Call Stack + Locals:调用关系和局部变量窗口,查看函数调用关系,以及函数的局部变量
Debug 工具条
关闭Disassembly窗口->添加Watch1窗口->双击 Enter expression,将全局变量: g_fac_us (在 delay.c 里面定义)加入 Watch1 窗口->
在 delay_init 函数处放置一个断点->点击执行到该断点处->执行进去->执行过去(g_fac_us值显示出来)->执行进去
从 Call Stack + Locals 窗口看到函数的调用关系,其原则是: 从下往上看,即下一个函数调用了上一个函数
MDK5 使用技巧:
自定义字体颜色:
设置->Encoding:Chinese GB2312(Simplified)->勾选View White Space(编辑器的空格可见)->勾选Insert spaces for tabs(代码对齐)->Tab size:4->
Colors & Fonts 选项卡->C/C++ Editor Files(设置自己的代码的字体和颜色)->
User Keywords 选项卡,设置用户定义关键字
看看某个变量或数组是在哪个地方定义,快速定位:
魔术棒->Output->勾选 Browse Information->编译->
右键->Go to Definition Of
快速注释/消注释块代码的功能->右键->高级(Advanced)->注释选择(Comment Selection)
快速打开头文件:右键->Open Document
define :预处理命令,它用于宏定义
常见的格式:define 标识符 字符串
标识符:宏名。
ifdef 条件编译:条件编译命令最常见的形式为:
#ifdef 标识符
程序段 1
#else
程序段 2
#endif
当标识符已经被定义过(一般是用#define 命令定义),则对程序段 1 进行编译, 否则编译程序段 2。 其中#else 部分也可以没有
extern 外部申明:
extern :置于变量或者函数前,以表示变量或者函数的定义在别的文件中。 extern 申明变量可以多次,但定义只有一次
typedef:为现有类型创建一个新的名字,或称为类型别名,用来简化变量的定义。定义结构体的类型别名和枚举类型。
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
…
} GPIO_TypeDef;
声明结构体类型:
struct 结构体名
{
成员列表;
}变量名列表;
在结构体申明的时候可以定义变量,也可以申明之后定义:struct 结构体名字 结构体变量列表 ;
结构体成员变量的引用方法是:结构体变量名字.成员名
指针:本质是指向一个地址,从而可以访问一片内存区域。
申明指针我们一般以 p 开头:char * p_str = “This is a test!”;
p_num:变量的地址
*p_num:指向的地址所存储的值
&p_num:指针自身的地址
存储器本身是没有地址信息的,存储器分配地址的过程就叫存储器映射。
给寄存器的地址命名的过程就叫寄存器映射。
寄存器的地址=外设基地址+地址偏移量
=总线基地址(BUS_BASE_ADDR)+总线基地址的偏移量(PERIPH_OFFSET)+外设基地址的偏移量(REG_OFFSET)
例如:GPIOB_ODR地址 = AHB1总线基地址 + GPIOB外设偏移量 + 寄存器偏移量
外设基地址在stm32参考手册2.3存储器映射中查看
/*GPIOB_ODR 寄存器的地址为: 0x4002 0414, 假设我们要控制GPIOB 的 16 个 IO 口都输出 1*/
#define GPIOB_ODR *(unsigned int *)(0x40020414)
GPIOB_ODR = 0XFFFF;
/*这个宏定义过程就可以称之为寄存器的映射。*/
新建一个工程框架:
打开 MDK 软件->项目->新的->STM32 型号(要安装对应的器件 pack 才会显示这些内容)->
自动创建了 3 个文件夹:
DebugConfig:调试设置信息文件(.dbgconf),不可删除
Listings:编译过程产生的链接列表等文件
Objects:编译过程产生的调试信息、 .hex、预览、 .lib 文件等->
先把 MDK 自动生成的这两个文件夹(Listings 和 Objects)删除
Heap_Size EQU 0x00000000
; Reset handler
Reset_Handler PROCEXPORT Reset_Handler [WEAK]IMPORT __mainLDR R0, =0xE000ED88 ;使能浮点运算 CP10,CP11LDR R1,[R0]ORR R1,R1,#(0xF << 20)STR R1,[R0];寄存器版本代码,因为没有用到 SystemInit 函数,所以注释掉以下代码为防止报错!;HAL 库版本代码,建议加上这里(外部必须实现 SystemInit 函数),以初始化;stm32 时钟等.;IMPORT SystemInit;LDR R0, =SystemInit;BLX R0LDR R0, =__mainBX R0ENDP
设置使用 FPU:魔术棒->Target1选项卡->Floating Point Hardware:Double Precision
使用 AC6 编译器,Misc Controls : -Wnoinvalid-source-encoding->
添加main.c->添加到分组->编译会报错修改stm32fxx_it.c添加头文件#include "stm32f4xx_hal.h"