STM32F103C8T6板子使用说明
第一章 计算机体系结构(了解)
后续在板子上开发的时候,需要考虑是否有操作系统
- 方式一:有操作系统,通过c库通过os api操作硬件
- 方式二:无操作系统, 通过c库通过固件库操作硬件
第二章 STM32开发板概述
板子/开发板:pcb版,把众多元器件集中到一个板子上面管理
1. 基础概念
Cortex-M系列是ARM针对微控制器应用推出的内核,STM32系列芯片是STMicroelectronics(意法半导体)公司推出的32位ARM Cortex-M微控制器系列产品
STM32系列芯片基于ARM Cortex-M内核,包括Cortex-M0、M0+、M3、M4和M7等多种类型。这些内核提供了不同的性能级别,以满足从低功耗设备到高性能应用的各种需求
2. 产品分类
STM32F0系列
-
定位:入门级微控制器,适合初学者和简单嵌入式应用。
-
性能:基于ARM Cortex-M0内核,主频范围为20-64MHz,提供实时性能和低功耗。
-
应用场景:家居自动化、小型设备控制等。
STM32F1系列
-
定位:经典中坚力量,广泛应用的系列。
-
性能:采用Cortex-M3内核,主频可达72MHz,性能稳定。
-
应用场景:消费电子、小型设备等。
STM32F2系列
-
定位:高性能与低功耗的结合。
-
性能:基于Cortex-M3内核,主频高达120MHz,平衡了高性能和低功耗。
-
应用场景:通信设备、物联网设备等。
STM32F3系列
-
定位:高度集成数字模拟功能。
-
性能:搭载Cortex-M4内核,最高主频可达72MHz,具有丰富的数字模拟外设资源。
-
应用场景:电源管理、电机控制等需要高度集成模拟功能的应用。
STM32F4系列
-
定位:高性能数字信号处理之选。
-
性能:基于Cortex-M4内核,主频可高达180MHz,具备硬件浮点单元(FPU),支持DSP指令集,适合处理复杂数字信号和高速数据流。
-
应用场景:航空航天、工业自动化等。
STM32F7系列
-
定位:引领行业新标准。
-
性能:采用Cortex-M7内核,最高主频达到216MHz,具备高级的缓存架构和双精度浮点单元(FPU)。
-
应用场景:高性能图形显示、多媒体处理等领域。
STM32H7系列
-
定位:顶级性能系列。
-
性能:基于Cortex-M7内核,最高主频可达480MHz,是STM32家族中性能最高的系列。具备丰富的存储资源和高速接口。
-
应用场景:运行复杂的实时操作系统(RTOS)和高级图形界面。
3. STM32芯片命名与规则
比如等下会介绍的:STM32F103C8T6
4. 嵌入式操作系统
4.1 为什么需要操作系统
有的嵌入式系统没有操作系统。只能调用芯片产品提供一下私有库文件来操作。
优点:性能高, 缺点:通用性非常差。
有操作系统,就有操作系统封装了硬件的不一致。 只需要调用操作系统的api就OK了
4.2 嵌入式操作系统的分类
手机平台: android,ios,鸿蒙等
其他平台:
- rtos(实时操作系统): freertos,rtthread,uccos,qnx等 芯片不是很强
- 通用性: 嵌入式linux(经过裁剪),鸿蒙
5. 外设与硬件接口
5.1 常见的外设
传感器 执行器 显示屏 通信接口 存储设备 输入设备 音频设备 ADC/DAC
ADC/DAC:模拟数字转换器(ADC)和数字模拟转换器(DAC)在模拟和数字信号之间进行转换,这在嵌入式系统中非常有用,特别是当需要处理模拟信号时
5.2 芯片的硬件接口
嵌入式系统中的硬件接口是连接微控制器或其他处理器与外部设备的桥梁,它们允许数据和控制信号的传输
通信的概念
- 通信指的是CPU和外部设备之间或者计算机与计算机之间的数据交互
通信的种类
并行通信
- 传输原理:数据各个位同时进行传输(以字节或字节的倍数进行传输)
- 优点:传输速度快
- 缺点:占用引脚资源、传输成本高、传输距离近、抗干扰能力弱(串扰)
- 应用领域:一般大量数据传输,并且传输距离较近 如计算机总线
串行通信
- 传输原理:数据按位依次顺序传输(每一位都占据固定的时间长度)
- 优点:节约引脚资源(最少一根线)、传输成本低、传输距离远
- 缺点:传输速度慢
- 应用领域:一般用于工控设备、测量设备、少部分通信设备 USB COM
第三章 STM32F103C8T6开发板认识
1. 核心参数
STM32F103C8T6是一款基于ARM Cortex-M3 内核STM32系列的32位的微控制器,程序存储器容量是64KB,需要电压2V~3.6V,工作温度为-40°C ~ 85°C。
STM32F103C8T6芯片的基本参数:
- 类别:集成电路(IC);
- 家族:嵌入式-微控制器;
- 总线宽度:32-位;
- 速度:72MHz;
- 外围设备:DMA,电机控制PWM,PWM,温度传感器;
- 输入/输出数:37;
- 程序存储器容量:64KB (64K x 8);
- 程序存储器类型:FLASH;
- RAM容量:20K x 8;
- 电压-电源(Vcc/Vdd):2 V ~ 3.6 V;
- 模数转换器:A/D 10x12b;
- 振荡器型:内部;
- 工作温度:-40°C ~ 85°C;
- 封装/外壳:48-LQFP。
2. 安装驱动
判断安装完成
3. 普中 STM32F103C8T6启动方式
STM32三种启动模式对应的存储介质均是芯片内置的,它们是:
- 用户闪存=芯片内置的Flash。
- SRAM=芯片内置的RAM区,就是内存啦。
- 系统存储器=芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段Bootloader,就是通常说的ISP程序。这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个ROM区。
BOOT1=xBOOT0=0从用户闪存启动,这是正常的工作模式
BOOT1=0BOOT0=1从系统存储器启动,这种模式启动的程序功能由厂家设置。 BOOT1=1BOOT0=1从内置SRAM启动,这种模式可以用于调试
第四章 环境搭建
之后我们就要在这个STM32F103C8T6开发板,烧录程序,就需要先搭建各种环境
1. KEIL5 软件安装
2. 安装 STM32 芯片包
3. 破解KEIL5 软件
KEIL5 安装到这里电脑桌面上会有一个快捷方式,如下所示: 首先以管理员模式打开 KEIL5 软件
- 之后再把得到的序列号,拷贝回去就可以了
4. 固件库的使用
STM32的开发方式有三种:寄存器开发 + 函数库开发 + 图形界面开发
寄存器开发: STM32属于32位的MCU,STM32内部的资源十分丰富,就导致寄存器的数量和复杂度都增大了,就要求开发人员对底层的知识掌握的非常扎实。
函数库开发:相比于寄存器开发,使用库函数开发的程序的运行效率稍微低一些,大概低10%~15%左右,但是对于一些实时性要求不高的产品来说,可以忽略不计。ST公司针对STM32开发了两套库(标准外设库 + HAL库),国内大多数的公司还是在采用标准外设库开发(更稳定、资料更多、容易维护)。
图形界面开发:图形界面开发使用了STM32CubeMX工具
我们学习的事主流的开发方式,使用标准固件库,也就是函数库开发
4.1 CMSIS 标准
什 么 是 CMSIS 标 准 ? CMSIS 标 准 英 文 全 称 是 Cortex MicroControllerSoftware Interface Standard,翻译为中文意思就是ARM Cortex 微控制器软件接口标准。由于基于 Cortex 核的芯片厂商很多,不只是ST 公司,为了解决不同厂家的 Cortex 核芯片软件兼容的问题,ARM 和这些厂家就建立了这套CMSIS标准。
我们可以通过一个基于 CMSIS 标准的应用程序框图来看其重要性。如下图所示:
4.2 建立模块工程
step1: 创建模版工程存放路径
step2: 建立三个文件夹(User、Lib、Obj)
Obj 文件夹:用于存放编译产生的 c/汇编/链接的列表清单、调试信息、hex文件、预览信息、封装库等文件。
User 文件夹:用于存放用户编写的 main.c、stm32f10x.h 头文件、stm32f10x_conf.h配置文件、stm32f10x_it.c和stm32f10x_it.h中断函数文件。
Lib 文件夹:用于存放 CMSIS 标准和 STM32 外设驱动文件
step3: 建立自己原始的Lib文件库
- 注意:startup_stm32f10x_md.s根据我们使用芯片来决定(c8t6属于中等容量,所以使用_md.s)
step4: User: 根据固件库的模板添加
4.3 创建工程
4.4 配置工程文件夹
使用工程管理图标(Manager Project Items)添加文件夹,添加文件
说明一下:
- User下面添加Main.c入口程序,以及中断文件stm32f10x_it.c,后面还可以添加我们的功能性文件;
- Startup添加启动文件,startup_stm32f10x_md.s,(找不到可能是因为文件类型)
- StdPeriph_Driver标准库外设驱动文件,一般先添加常用的外设驱动文件(gpio常用外设、rcc时钟相关文件)
- CMSIS添加两个内核文件
4.5 工程参数设置
4.6 启动测试
- 走到这里就表示都配置完了,之后使用就通过每次的
5. 烧录程序到板子上
开始烧录程序
说明一下:
- 这个TestLED.hex是一个控制这个板子上灯的程序
- 这一排灯会从左向右的,依次闪烁
说明一下:
- st-lib.hex 就是我们刚才写的生成,什么都没做,就是一个死循环
- 由于重新烧录了一遍,所以原来的那个灯又被覆盖了
第五章 第一个LED灯- D2(重点)
1. 找到物理位置
2. 找到电路位置
刚才我们已经看到了LED灯的物理位置,且这个版在核心版上叫D2, 接下来就是要看一下核心版的原理图
说明一下:
- 在原理图中D2的左边有个电阻和一个VCC3.3,这个VCC3.3表示电源为3.3V的正电压
- 而想要一个元件通电,就必须要有电流通过这个元件,而电流的形成又需要通过电势差,电势差又需要从高电压到低电压,
- 简单来说,PC13这根必须表示为负电压(说人话是这样的)
- 专业一定是让这个芯片给PC13引脚输出一个信号,然后让它形成低电压
3. STM32 芯片的 GPIO
在 STM32 芯片中,GPIO 是 General Purpose Input/Output 的缩写,中文叫做“通用输入输出口”。它是 STM32 微控制器上用来与外部设备(如按钮、LED、传感器、继电器等)进行通信的基本接口之一
4. PC13引脚
PC13 是 STM32 微控制器中端口 C 的第 13 号 GPIO 引脚,常用于控制板载 LED
引脚是微控制器(如 STM32)与外部世界进行电气连接的金属脚位,用于输入输出信号
在 STM32 微控制器中,所有的 GPIO 引脚都有一个命名规则,比如:
-
P 代表 Port(端口)
-
C 是端口的字母名(Port C)
-
13 是该端口上的第 13 个引脚
所以,PC13 就是 端口 C 的第 13 个引脚。
STM32 通常有多个 GPIO 端口(A、B、C、D 等),每个端口包含若干个引脚,比如 PA0、PB5、PC13 等。
对了我这个STM32F103C8T6是有48组引脚
5. step1:给APB2 GPIO C进行时钟使能
5.1 时钟使能
时钟使能就是给某个外设通电并启动它的工作时钟,让它能正常运行。
在 STM32 中,比如你要用 GPIOC,就必须先“时钟使能”,也就是打开 GPIOC 的时钟,不然它就不会工作
- STM32 的时钟来自内部振荡器或外部晶振,经过 RCC 分配,你必须手动“打开”才能让外设工作
5.2 GPIO C - PC
GPIOC 是一个端口,PC13 是它的一个引脚(第13号)
简单对比:
-
GPIOC:表示整个 C 端口,包括 PC0 ~ PC15 共 16 个引脚。
-
PC13:是 GPIOC 中的第 13 个引脚,是 GPIOC 的一部分。
5.3 APB2
要说这个东西,又要看参考手册中的系统架构 ,去看看内部的线路是怎么走的
- APB2 是 STM32 芯片内部的一个外设总线,GPIOC 就挂载在这条总线上。
详细但简洁地说:
STM32 内部有多个总线(像交通道路),负责把时钟和数据传给各个外设,常见的有:
总线名 | 全称 | 挂载的外设 |
---|---|---|
AHB | Advanced High Bus | 内存、DMA、FSMC 等 |
APB1 | Advanced Peripheral Bus 1 | 比如 USART2、TIM2、I2C1 等 |
APB2 | Advanced Peripheral Bus 2 | GPIOA/B/C、AFIO、USART1、ADC1等 |
5.4 参考手册6.2 RCC寄存器描述
我这个板子是STM32,32就是32个bit位,每一个bit位的功能都不一样,
说明一下:
- 保留的意思是这个bit位还没有用(这里是始终为0),也就是0,不启动
- 如果要开启某个功能,就设置为1
每个bit位的功能
5.5 参考手册 6.3.4 APB2 外设复位寄存器 (RCC_APB2RSTR)
首先明确目标:我们在这一步要做的是开启APB2 GPIOC的时钟使能
这个IOPCRST就是GPIOC,把这个bit位打开了,就是把PC那个一堆引脚都打开了,其中自然就有PC13
所以接下来我们把这个寄存器中的第四个bit位置成1就可以了,也就是0....10000(二进制) = 16(十进制) , 这时我们就得到了一个关键数字16
接下来就需要思考,这个16给谁能,换句话说16给那个地址呢
5.6 参考手册 2.3 存储器映像
所有寄存器的起始地址如下:
起始地址
而我们想要的其实是这个:AHB总线上的-> 复位和时钟控制(RCC) -> 0x4002 1000
5.6 参考手册6.3.11 RCC寄存器地址映像
偏移量
说明一下
- IOPCEN就是GPIOC,GPIOC其中就有PC13
- 这时,我们就得到了一个重要数字018h,也就是0x18(十六进制)
5.7 最终代码
此时我们有了寄存器起始地址(0x4002 1000),寄存器偏移量(0x18),还有个值(16),则最终代码如下:
//1.给APB2 GPIO C进行时钟使能
*(uint32_t *)(0x40021000+0x18)=16;
6. step2 : 找GPIOC 第13个引脚 输出一个低电平
6.1 参考手册 8.1 GPIO功能描述
我们需要思考GPIOC的第13根线,怎么工作,也就是选择那个工作模式?
要考虑的东西有点多,直接说结论: 选择推挽输出
6.2 推挽输出模式
简单来说:就是输入输出模式
说明一下:
- VDD是正,VSS是负
- 当我们给输出控制为1时,表示接通VDD,此时里面为正,外面为负,电流从内到外,推模式
- 当我们给输出控制为0时,表示接通VSS,此时里面为负,外面为正,电流从外到内,挽模式
6.3 参考手册 8.2.2 端口配置高寄存器(GPIOx_CRH) (x=A..E)
每个端口配置需要用4个bit位,但要16根线,一共需要64位,则STM32中的32bit位是不够的,其实端口配置是分了低寄存器,和高寄存器的,每个8根线
其实这里是有2个寄存器的,但我们这里就只看高寄存器,也就是后面8根线
为什么用4个bit为才能搞定这件事呢?
说明一下:
- 后2个bit位标识MODE8[1:0],也就是0和1的组合
- 前2个bit为标识CNFy[1:0] ,也是0和1的组合
- 当我们将第是三根线上的MODEy[1:0]设置为11时,表示最大速率wei50MHZ的输出模式
- 而我们选择的工作模式是推挽输出模式,且此时的MODEy[1:0]>00,则CNFy[1:0]为00
则这个寄存器中的二进制为 0000 0000 0011 0000 0000 0000 0000 0000 也就是
这时我们得到了一个数字0x300000(十六进制)
6.4 参考手册 2.3 存储器映像
在这一步中,我们也需要到GPIOC的起始地址,偏移量,然后才能把刚才那个数字存到寄存器中
起始地址
- 此时我们得到了GPIOC的起始地址为0x4001 1000
偏移量
- 通过查询手册,我们可发现这个寄存器的偏移地址为0x04
6.5 最终代码
此时我们有了寄存器起始地址(0x4001 1000),寄存器偏移量(0x04 ),还有个值(0x300000),则最终代码如下:
//2. 设置模式-推挽输出模式 50mhz
*(uint32_t *)(0x40011000+0x04)=0x300000;
7. step3: 给PC13输出一个低电平
简单来说:就是找到对应的端口13引脚 赋值为0 低电平
7.1 参考手册 8.5 GPIO 和AFIO寄存器地址映象
每一组引脚有16根线,GPIOA有16根线,GPIOB有16根线,所以一组数据用不到高16位,则保留
说明一下:
- 我们要做的就是让PC这个根线上的第13位设置为0,其他为1
所以:我们要让PC13输出一个低电平,就是给它一个值为0xDFFF
ODR的偏移量
- 通过查询手册发现这个偏移量为0x0c
ODR的起始地址
- 这个寄存器的起始地址和上面那个相同都是0x4001 1000,就只是偏移量不同
7.2 最终代码
此时我们有了寄存器起始地址(0x4001 1000),寄存器偏移量(0x0C ),还有个值(0xDFFF),则最终代码如下:
//3.给PC13输出一个低电平
*(uint32_t *)(0x40011000+0x0C)=0xDFFF;
8. 完整代码
#include "stm32f10x.h"
#include "led.h"
int main()
{//1.给APB2 GPIO C进行时钟使能*(uint32_t *)(0x40021000+0x18)=16;//2. 设置模式-推挽输出模式 50mhz*(uint32_t *)(0x40011000+0x04)=0x300000;//3.给PC13输出一个低电平*(uint32_t *)(0x40011000+0x0C)=0xDFFF;while(1){}return 0;
}