一、内部核心功能
-
ARM内核
-
存储器
-
Flash:硬盘
-
SRAM:内存
-
时钟
实时时钟:RTC
-
振荡器HSE/HSI
-
RC振荡器
-
晶体振荡器
-
分频器
-
实现震荡频率翻倍
-
用锁相环实现,称PLL
-
复位
-
电源管理
-
备用电源输入
-
端口输入输出
-
逻辑电源输入
-
模拟电源输入
二、内部重要功能
-
低功耗模式
-
睡眠模式:
-
停机模式
关ARM内核 |
---|
关闭所有内部功能 |
关闭PLL分频器,HSE振荡器 |
-
待机模式
关ARM内核 |
---|
关闭所有内部功能 |
关闭PLL分频器,HSE振荡器 |
SRAM内容消失 |
-
ADC:模数转换器
-
DMA:帮CPU传递数据
-
I/O:(I/O的集合也就是GPIO)
总共有5组端口,一组有16个I/O口
每个端口有8个工作状态:
-
AIN 模拟输入
-
IN_FLOATING 浮空输入
-
IPD 下拉输入
-
IPU 上拉输入
-
Out_PP 推挽输出
-
AF_PP 复用推挽输出
-
Out_OD 开漏输出
-
AF_OD 复用开漏输出
-
调试模式
-
JTAG:仿真调试接口(这是一个协议,可以代指用这个协议的接口)
-
SWD:简化版JTAG
-
定时器
-
定时器:利用系统时钟计数,本质计数器
-
看门狗定时器:在定时时间让单片机复位,拯救死机的单片机
-
滴答定时器:用于实时操作系统中任务的切换,可当普通定时器用
三、内部通信功能
-
I2C总线
-
板级总线:只能在PCB上近距离通信
-
分主从设备
-
低速稳定,简单易学,超100kHz不稳定
-
常用于EEPROM存储器、温度传感器、RTC时钟、气压传感器
-
F103中有2个I2C控制器
-
USART串口
-
全称同步收发器
-
没有地址概念,没有主从设备
-
用于Wi-Fi模块、GPS模块、蓝牙模块、单片机与计算机间通信
[工业中应用] 计算机与PLC(工业控制常用的可编程控制器)之间通信用RS232或RS485
-
F103中有3个USART串口
-
SPI总线
-
有主从设备之分,单片机为主
-
板级总线:只能在PCB上近距离通信
-
高速稳定,没有地址概念
-
全双工:同时收发
-
挂接从设备数量有限
-
CAN总线
-
每个设备既可为主设备,又可为从设备
-
远程通信
-
有标识符
-
F103中有1个CAN接口,但需要外加一片CAN收发器芯片才能用
-
USB接口
-
有主从关系
四、硬件电路和ISP下载
内部功能 | 说明 | 引脚数 | 引脚定义 |
---|---|---|---|
ARM内核 | 用于运算,只有内部总线,没有向外的接口 | 0 | |
存储器 | 用于存储,只有内部总线,没有向外的接口 | 0 | |
时钟 | 向外接一个高速晶振一个低速晶振,每个晶振要2个引脚,共4个 | 4 | OSC32_IN、OSC32_OUT、OSC_IN、OSC_OUT |
复位 | 向外引出1个外部复位引脚 | 1 | NRST |
电源管理 | 要引出1组模拟电源和3组逻辑电源,每组电源有正负极两个引脚,共8个引脚 | 8 | VDDA、VSSA、VDD_1、VSS_1、VDD_2、VSS_2、VDD_3、VSS_3 |
低耗能 | 要引出1个外部唤醒接口,还要用到RTC走时以及备用存储器保持数据的 备用电池的正极引脚(负极与逻辑电源负极共用) | 2 | WKUP、VBAT |
ADC | 有16个输入通道,需要引出16个引脚 | 16 | ADC12_IN0~16 |
DMA | 用于内部数据传递,没有向外的接口 | 0 | |
GPIO | 共有5组GPIO接口,每组有16个I/O端口 | 80 | PA0~15、PB0~15、PC0~15、PD0~15、PE0~15 |
调试模式 | JTAG接口需要5个接口 | 5 | NJTRST、JTDO、JTDI、JTCK、JTMS |
定时器 | 共有三个普通定时器和1个高级定时器(共21个接口) | 21 | TIM1_CH1~4、TIM_CH1N~3N、TIM1_BKIN、TIM1_ETR、TIM2_CH1~4、TIM3_CH1~4、TIM4_CH1~4 |
看门狗 | 没有向外的接口 | 0 | |
滴答定时器 | 没有向外的接口 | 0 | |
I2C总线 | 共有2组I2C总线,每组2个接口,共需要6个接口。(SCL是I2C的时钟线;SDA是数据线;SMBA是SMBus总线的报警信号,在I2C通信中不会用到) | 6 | I2C1~2_SCL、I2C1~2_SDA、I2C1~2_SMBA |
USART串口 | 共有3组全功能串口,每组内需要5个接口(在一般的串口通信中智慧用到TX和RX两个接口) | 15 | USART1~3_CK、USART1~3_TX、USART1~3_RX、USART1~3_CTS、USART1~3_RTS |
SPI总线 | 有2组SPI总线,每组又有数据收、数据发、时钟线、使能线4个接口。 | 8 | SPI1~2_MOSI、SPI1~2_MISO、SPI1~2_SCK、SPI1~2_NSS |
CAN总线 | 有数据发送和数据接收,共两个引脚 | 2 | CAN_TX、CAN_RX |
USB接口 | USB接口只有2条数据线 | 2 | USBDP、USBDM |
CRC校验 | 没有向外的接口 | 0 | |
芯片ID | 没有向外的接口 | 0 |
1.单片机、核心板、开发板
-
STM32单片机:搭载ARM内核,是实现内部功能和程序的部分,通过引脚和核心板连接
-
核心板(最小系统):是维持单片机正常工作的最基础的电路,通过排针和开发板连接
[常用扩展功能] 串口、LED、按键、蜂鸣器
-
开发板:是针对单片机项目开发中最常见、最值得学习的内容做了扩展
[面包板] 用于扩展装外设元件以及电路的一块搭载平台
2.ISP程序下载
写入程序的方法:JTAG调试下载&串口ISP下载
-
JTAG调试下载:
-
通过J-LINK仿真调试器完成
-
连接JTAG接口与电脑USB接口
-
可与Keil配合实现在线仿真
-
-
串口ISP下载:
-
通过USART串口功能实现
-
涉及BOOT0和BOOT1引脚上开关的反复拨动
-
ASP功能:涉及1个MODE按键和1个ASP指示灯
-
单击:单击MODE可开关开发板电源,指示灯相应点亮熄灭
-
双击:开启或关闭自动下载功能
-
长按:切换下载模式,有Flash ISP 和 RAM ISP 两种模式
-
-
需要下载ISP软件:比如FlyMcu
-
串口通信的波特率:115200(bps)
-
使用的文件后缀是.HEX
-
3.最小系统电路图分析
基本组成:
1个高速晶振、一个低速晶振、1个复位按键、1个备用电池、6个滤波电容,以及ISP下载电路(由S1、S2开关及USB转TTL电平电路组成)
[S1、S2] 就是单片机上的BOOT0和BOOT1两个启动模式接口
启动模式(ISP下载的工作原理):
BOOT1(S2) | BOOT0(S1) | 启动模式 | 说明 |
---|---|---|---|
X | 0 | 主闪存存储器Flash ISP | 单片机再次复位后会运行Flash里面的用户程序 |
0 | 1 | 系统存储器Bootloader | Bootloader程序是ST公司写入单片机的,用户不能修改的是一段ISP下载辅助程序 |
1 | 1 | 内置SRAM RAM ISP | 多用于开发过程中的程序调试 |
[注] S1断开为0闭合为1,S2断开为1闭合为0
五、开发平台的建立
1.下载Keil5
在Keil官网下载,然后安装好.pack后缀的芯片包
2.建立工程
为了方便以后的每次工程创建操作,我们可以创建一个“工程模板”
关于固体库:
固体库:操作功能配置寄存器的官方函数库
下载固体库:在ST官网,需要找到一个叫STM32F10X_StdPeriph_Lib_V3.5.0 的文件夹,这个就是固体库
工程子文件说明:
文件夹名 | 存放类型 | 说明 |
---|---|---|
CMSIS | 内核驱动程序 | 用来存放跟内核和单片机系统有关的内容 |
Lib | 内部功能函数库 | 用来存放操作功能配置寄存器的各功能的固体库函数 |
Startup | 单片机启动程序 | 用来存放单片机启动时进行初步设置的程序 |
User | 用户程序 | 用来存放主函数、中断处理函数、报错处理函数等 |
Basic | 内部功能驱动程序 | 用来存放用户自己编写的内部功能的驱动程序 |
Handware | 外部硬件驱动程序 | 用来存放用户自己编写的硬件电路驱动程序 |
六、C语言基础知识总结
1. 关于字符:
-
标识符:不能以数字开头,标识符的第一个字母必须是字母或下划线
-
c语言允许换行编写:换行时刻加入符号 “ \ ” 或者什么都不加,但在 #define 宏定义中的换行必须加 “ \ ”
2. 函数
-
延时函数
-
定时器初始化函数
-
中断处理函数:中断函数里调用的函数不要在被main函数调用,不然会出现数据错乱
-
ADC_READ函数
模板如下:
返回值 函数名(参数){ 函数内部程序语句 }
PS:返回值和参数都是void表示没有返回值或参数
3. 数据
(1)常量
-
Keil软件不支持二进制数的表达方式,一般以0b或0B开头的表示二进制数
-
十六进制(BCD码)是单片机编程中最常用的数值表示方法(A10,B11,C12,D13,E14,F15)
(2)浮点数
-
Keil编译器一般不支持,需要浮点数库文件才能使用
(3)变量
数据类型 | 定义语句 | 简写 | 占用空间 | 数值范围 | 使用频率 |
---|---|---|---|---|---|
32位无符号变量 | unsigned long | u32 | 4字节 | 上十亿 | 高 |
16位无符号变量 | unsigned short | u16 | 2字节 | 上万 | 极高 |
8位无符号变量 | unsigned char | u8 | 1字节 | 0~255 | 极高 |
易变的8位无符号变量 | volatile unsigned char | vu8 | 1字节 | 0~255 | 高 |
只读的8位无符号变量 | unsigned char const | uc8 | 1字节 | 0~255 | 高 |
要注意数据溢出的问题(即变量用着用着结果赋值的数超过了最初定义的范围)
(4)数组
/**********定义数组的方法************/ u8 b[8]; //定义8个字节8位数组变量 const u8 t[4]={1,2,3,4}; //定义4个8位固定数据的数组 const u8 y[2][3]={{1,2,3},{4,5,6}}; //定义2行每组3个固定数据的二维数组
注意:数据存入数组是从第0个位置开始存的!!
/***********数组的调用方法***********/ a = t[0]; //即t的第一个数据 a = y[0][2]; //即y的第一行第3个数据 a = t[i]; //这里i是变量,可以在这句上面写关于i的运算式子
(5)枚举
是一种数据类型,指一组有共同特性(特性是自定义的)的数据的集合
作用:限制数据范围
格式:
enum 枚举名{ 标识符=整形常数, 标识符=整形常数, 标识符=整形常数 }枚举变量;
如果没给标识符赋值:
它的值就等于上一个标识符的值加1
如果第一个标识符没赋值:
系统默认它的值是0
例子:
enum phonenum_book{ papa = 13907727651, mama = 13825578263, me = 17665376286 }phonenum;
使用:
phonenum = papa; //结果:phonenum=13907727651
拓:stm32f10x.gpio.h文件的枚举定义
typedef enum { GPIO_Mode_AIN = 0X0, GPIO_Mode_IN_FLOATING = 0X04, GPIO_Mode_IPD = 0X28, GPIO_Mode_Out_OD = 0X14, GPIO_Mode_Out_PP = 0x10, GPIO_Mode_AF_OD = 0X1C, GPIO_Mode_AF_PP = 0X18 }GPIOMode_TypeDef;
(6)结构体
结构体和枚举的区别:
-
枚举是同一类型数据的集合
-
结构体是不同类型数据的集合
格式:
struct 结构体名{ 结构体成员; 结构体成员; }结构体变量;
1.普通结构体的定义、写入、调用
/************定义**********/ struct name{ int a; char b; float c; }x; /************写入**********/ x.a = 1; x.b = 2; x.c = 0x30; /************调用**********/ if(x.a>1){ z = x.b; }
2.typedef前缀的结构体定义、写入、调用
/***********定义***********/ typedef struct{ int a; char b; float c; }x; /***********写入************/ x y; y.a = 1; y.b = 2; y.c = 0x30; /************调用***********/ if(y.a>1){ z = y.b; }
typedef前缀的结构体里定义的x是一种数据类型,y是变量
(7)指针
单片机程序的运行依靠的就是一个叫PC指针的东西
PC指针:
-
一种特殊的寄存器
-
用来存放地址
基本操作:
//定义 u8 *a; //写入 *a = 100; //移动指针 a = a+6; //数据调用 b = *a;
4.位操作
单片机运算是以字节为单位的,要进行位操作需要位操作符。
符号 | 说明 | 举例 |
---|---|---|
& | 按位与 | a&b |
| | 按位或 | a|b |
^ | 按位异或 | a^b |
~ | 按位取反 | ~a |
<< | 位左移 | a<<2 |
>> | 位右移 | a>>2 |
5.指令
一般是用#include指令引用其他文件
格式:
#include "xxxxx.h"
6.宏定义
STM32中常用的宏定义语句有7个
宏定义 | 说明或举例 |
---|---|
#define 代替名 原名 | 如#define n 5 指的就是定义n为5,且下面的操作无法修改n的值 |
#undef 代替名 | 撤销宏定义 |
#ifdef 代替名 | 使能编译或防止重复定义头文件 |
#if 表达式 | 使能编译,如果判断 |
#elif 表达式 | 使能编译,否则如果判断 |
#else | 使能编译,否则判断 |
#endif | 结束#ifdef或#if |
格式:
#ifdef __DELAY_H #define __DELAY_H /*程序正文*/ #endif __DELAY_H //结束宏 /*-------------------------*/ #if 1 a = 1; #elif 1 a = 2; #else a = 3; #endif //结束宏
7. 辅助工具
-
undo(撤销):Ctrl+Z
-
redo(重做):Ctrl+Y (撤回之后发现又没错时使用)
-
Find:Ctrl+F
-
Replace:Ctrl+H
-
标记功能:第二行菜单栏的红旗状图标(第一个:添加标记,第二个:跳转到上个标记,第三个:跳转到下一个标记,第四个:删除标记)
-
缩进功能:在红旗图标右边,有向左或向右缩进
-
注释与解注释功能:在缩进功能右边