STM32入门教程(绪论) 重要的内容写在前面该系列是以up主江协科技的STM32视频教程为基础写下去的大部分内容都参考了老师的课件对于一些个人认为比较重要但是老师仅口述的部分笔者都有用文字的方式记录并标出了重点。文中的图片基本都来源于老师的课件以及开发板和芯片的手册粘贴过来是为了方便阅读。如果有条件的可以先学习一些相关课程再去看STM32的教程学起来会更加轻松不太建议零基础开始直接STM32听起来可能会有点困难可以先学51单片机相关课程有数字电路强烈推荐先学数电不然可能会有很多地方理解起来很困难、模拟电路、计算机组成原理像寄存器、存储器、中断等在这门课里有很详细的介绍、计算机网络等。如有错漏欢迎指出。视频链接[1-1] 课程简介一、STM32基础知识1、STM32概述1STM32是ST公司基于ARM Cortex-M内核开发的32位微控制器STM32常应用在嵌入式领域如智能车、无人机、机器人、无线通信、物联网、工业控制、娱乐电子产品等。STM32功能强大、性能优异、片上资源丰富、功耗低是一款经典的嵌入式微控制器。2ARM既指ARM公司也指ARM处理器内核。ARM公司是全球领先的半导体知识产权IP提供商全世界超过95%的智能手机和平板电脑都采用ARM架构ARM公司设计ARM内核半导体厂商完善内核周边电路并生产芯片。2、STM32F103C8T6介绍1本教程使用的是STM32F103C8T6以下是STM32F103C8T6的一些参数①系列主流系列STM32F1。②内核ARM Cortex-M3。③主频72MHz。④RAM20KSRAM。⑤ROM64KFlash。⑥供电2.0~3.6V标准3.3V。⑦封装LQFP48。2STM32F103C8T6的引脚定义①表中表红色的是电源相关的引脚标蓝色的是最小系统相关的引脚标绿色的是I/O口、功能口引脚对于引脚类型S代表电源I代表输入O代表输出I/O代表输入输出。②I/O电平一列标有“FT”的引脚代表能“容忍”5V的电压未标有“FT”的引脚只能容忍3.3V的电压除非加装电平转换电路。③主功能就是上电后默认的功能一般和引脚名称相同有些引脚除了主功能外还有默认复用功能默认复用功能是I/O口上同时连接的外设功能引脚软件在配置I/O口时需要选择使用通用功能还是复用功能有的引脚甚至还有重定义功能如果有两个功能同时复用在同一个I/O口上而这两个功能又同时都需要实现那么就可以把其中一个复用功能重映射到其它端口上前提是被映射的端口其重定义列表中有对应的功能。④建议优先使用表中加粗的引脚。3、片上资源/外设下表是单片机常有的资源和外设但需要说明的是不是每个系列都有下列全部的资源/外设开发板上的外设会在后面逐一详细介绍这里有个印象即可1NVIC和SYSTick是ARM Cortex-M3内核中的外设剩下的都是内核外的外设。①NVIC是内核中用于管理中断的设备比如配置中断的优先级。②SysTick是内核中的一个定时器主要用来给操作系统提供定时服务可以用这个定时器完成Delay函数的功能Delay函数就是延时函数。2RCC可以对系统的时钟进行配置以及使能各个模块的时钟在STM32中其它外设在刚上电的情况下默认是没有配置时钟的如果不使能各模块相应的时钟那么将无法对外设进行操作。3GPIO是通用的I/O口可以通过GPIO进行点灯、读取按键状态等操作。4AFIO是复用功能输入/输出主要用于管理单片机引脚的多功能分配引脚重映射/中断配置/调试接口开启或关闭。5EXTI是外部中断配置好外部中断后当引脚有电平变化时就可以触发中断让CPU来处理任务。6TIM是定时器它可以说是整个STM32中最常用、功能最多的外设TIM分为高级定时器最复杂、通用定时器最常用和基本定时器三种类型这个定时器不仅可以产生定时中断还可以实现测频率、生成PWM波形、配置成专用的编码器接口等功能。7ADC是模数转换器STM32内置了12位的AD转换器可以直接读取I/O口的模拟电压值无需外部连接AD芯片使用起来更加方便。8DMA全名是直接内存访问它可以帮助CPU完成搬运大量数据的繁杂任务。9USART是同步或者异步串口实际中常用的UART是异步串口。10I2C和SPI是非常常用的两种通信协议STM32内置了它们的硬件收发器可以用硬件来控制时序波形当然用通用I/O口来模拟时序波形也是可以的。11CAN和USB也是非常常用的两种通信协议CAN一般用于汽车领域USB在生活中则更常见。12RTC是实时时钟在STM32内部完成年月日、时分秒的计时功能而且可以接外部供电电池即使单片机掉电也能继续运行一段不短的时间。13CRC是一种数据的校验方式用于判断数据的正确性数据在传输过程中可能会出现错误它能通过硬件完成。14PWR电源控制可以让芯片进入睡眠模式等状态以达到省电的目的。15BKP备份寄存器是一段存储器当系统掉电时仍可在备用电池的支持下保存数据根据需要可以完成一些特殊的功能。16IWDG和WWDG是看门狗当单片机因为电磁干扰而死机或者程序设计不合理而出现死循环时看门狗可以及时复位芯片保证系统的稳定运行。17DAC是数模转换器它可以在I/O口直接输出模拟电压ADC模数转换的逆过程。18SDIO是SD卡接口可以用来读取SD卡。19FSMC是可变静态存储控制器可以用于扩展内存、用于某些硬件的操作或者配置成其它总线协议.20USB OTG是USB主机接口用OTG功能可以让STM32作为USB主机去读取其它USB设备。4、系统结构1下图中左上角的Cortex-M3内核引出了三条总线分别是ICode指令总线、DCode数据总线和System系统总线ICode指令总线和DCode数据总线主要用于连接Flash闪存Flash中存储的就是我们编写的程序ICode指令总线负责加载程序指令DCode数据总线负责加载数据比如常量和调试数据。2AHB先进高性能总线用于挂载主要外设APB先进外设总线用于连接一般的外设。因为AHB和APB的总线协议、总线速度还有数据传送格式存在差异所以二者之间需要加两个桥接来完成数据的转换和缓存。性能比较AHBAPB2APB1APB2和AHB一般同频率都为72MHz而APB1一般是36MHz5、启动配置在STM32F10xxx里可以通过BOOT0和BOOT1引脚选择三种不同的启动模式①主闪存存储器模式是最常用的模式BOOT0置为0BOOT1置为1或0都可以该模式下会正常执行Flash闪存里的程序②需要使用串口下载程序时就配置为系统存储器模式③内置SRAM用于进行程序调试一般使用较少6、最小系统电路原理图二、嵌入式C语言知识基础1、C语言数据类型2、C语言宏定义1关键字#define2用途用一个字符串代替一个数字便于理解防止出错提取程序中经常出现的参数便于快速修改。3定义宏定义#define ABC 123454引用宏定义int a ABC; //等效于int a 12345;3、C语言typedef1关键字typedef2用途将一个比较长的变量类型名换个名字便于使用原来的名字仍可正常使用。3定义typedeftypedef unsigned char uint8_t;4引用typedefuint8_t a; //等效于unsigned char a;4、C语言结构体1关键字struct2用途将数据打包为不同类型变量的集合。3定义结构体变量struct{char x; int y; float z;} StructName;因为结构体变量类型名较长所以通常用typedef更改变量类型名4访问结构体成员StructName.x A; //访问StructName的成员xStructName.y 66; //访问StructName的成员yStructName.z 1.23; //访问StructName的成员z或 pStructName-x A; //访问StructName的成员xpStructName为结构体的地址pStructName-y 66; //访问StructName的成员ypStructName为结构体的地址pStructName-z 1.23; //访问StructName的成员zpStructName为结构体的地址5、C语言枚举1关键字enum2用途定义一个取值受限制的整型变量用于限制变量取值范围。3定义枚举变量enum{FALSE 0, TRUE 1} EnumName;因为枚举变量类型名较长所以通常用typedef更改变量类型名4引用枚举成员EnumName FALSE;EnumName TRUE;三、新建一个工程的步骤1、工程文件建立1打开Keil5软件在“Project”一栏找到“New μVision Project”点击它。2建议在桌面单独为STM32建一个新文件夹在该文件夹中存放不同的项目每个项目再独自命名一个文件夹生成的项目文件放在这个文件夹中项目文件命名建议命为“project”。3点击“保存”后开始选择芯片型号本教程采用的是STM32F103C8T6。4点击“OK”后会弹出一个新建工程小助手目前暂时可以不予理会点击关闭即可。5在工程项目文件夹中新建一个“Start”文件夹然后在资料包的固件库中找到如下文件将它们全部复制到“Start”文件夹中。6继续在固件库里面找到下图所示的三个文件也将它们复制到“Start”文件夹中。7继续在固件库里面找到下图所示的两个文件也将它们复制到“Start”文件夹中。8按照下图所示将其名称修改为“Start”然后根据图片提示往里面添加文件。启动文件有很多个选择哪一个由芯片型号决定本教程按下图选择即可添加结束后的项目文件夹情况如下所示9按照下图所示添加头文件路径否则软件会找不到.h文件。10在项目文件夹中新建文件夹“User”用于存放我们编写的代码文件相应地在Keil的项目中也添加一个同名的组然后在组中添加代码文件添加代码文件时路径要选择“User”。11在main.c文件中添加如下代码然后进行编译一般点击蓝框所示的按钮即可正常情况下是0错误0警告。2、工程测试点灯及库函数的使用1按照下图所示将STM32最小系统版、STLINK用四根杜邦线按照插针附近的标识符接好注意千万不能接错特别是3.3V和GND两个脚否则可能会把芯片烧坏。2配置调试器。下图二中勾上“Reset and Run”是为了方便调试每下载一个程序到开发板上开发板都会自动复位不需要手动去按复位按键注意图二下面还有一个“确定”键没有在图中显示勾选“Reset and Run”要点击确定否则设置不会被保存3单击下图所示按钮可以将程序下载到开发板中目前开发板不会有任何现象。4在main.c文件中写入如下代码然后进行编译将程序下载到开发板中可以看到开发板的一盏LED灯被点亮。#include stm32f10x.h // Device header int main() { //通过直接配置寄存器点灯需要查阅手册确认各寄存器的位定义 RCC-APB2ENR 0x00000010; //打开GPIOC的时钟 GPIOC-CRH 0x00300000; //配置GPIOC的引脚模式为推挽输出速度2MHz GPIOC-ODR 0x00000000; //配置GPIOC的引脚输出电平PC13输出低电平 while (1) { } }附需要查阅手册的地方5可以看到仅仅只是一个点灯操作如果通过直接配置寄存器的方法进行点灯单单是查手册就已经很麻烦了更何况一个寄存器还有32位配置起来也很麻烦这时可以通过库函数的方式进行配置。当然并不是所有单片机都有官方库函数但对于入门而言使用库函数可以屏蔽操作寄存器的细节①在项目文件夹中新建“Library”文件夹然后在固件库资料包中找到“inc”和“src”两个文件夹将里面的.h文件和.c文件全部复制到“Library”中同时在Keil的项目中也添加一个同名的组然后在组中添加刚刚复制过来的全部文件。②接着在STM32配套资料包中找到下图所示的三个文件将它们复制到“User”文件夹中同时把他们添加到Keil的项目的User组中。③接着按照下图所示往Define上写入“USE_STDPERIPH_DRIVER”然后在头文件路径中添加“User”和“Library”点击“OK”至此基于库函数的工程就创建完毕了。6在使用库函数时首先确认函数的名称一般函数的作用和其名称有很大关联然后按照下图所示例子的操作可以直接到达函数体函数体上方有供用户选择的函数参数param它们基本都经过宏定义或者枚举“包装”语意非常直观用户根据名称直接复制使用即可这样既能避免查手册的麻烦还能使代码具有更强的可读性。①使能GPIOC的时钟使用的函数为RCC_APB2PeriphClockCmd。最终根据步骤写出的代码RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);②配置端口模式使用的函数为GPIO_Init其函数参数中有结构体使用该函数时需要先定义一个结构体变量然后再给结构体赋值最后才能调用这个函数。寻找结构体定义的方法和寻找函数定义一致选中结构体类型名后右键跳转即可。GPIO_Init的函数体不短下图没有全部展示结构体中也有自己的参数对于GPIOSpeed_TypeDef以及GPIOMode_TypeDef这种明显是枚举类型的参数可以按照同样的方法进行跳转至枚举的定义很快就能找到供用户选择的参数对于GPIO_Pin这种非枚举类型的参数可以看到右侧的注释中有解释官方已经给各个引脚进行了宏定义要找到宏定义列表可以选中“GPIO_Pins_define”后按下CtrlF点击“Find Next”很快就能找到引脚相关的宏定义这些就是可供选择的引脚参数。一般“ref”后跟着的就是用于搜索的索引最终根据步骤写出的代码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);③点灯使用的函数为GPIO_ResetBits。参照上面的步骤可以写出代码GPIO_ResetBits(GPIOC,GPIO_Pin_13); //将PC13置为低电平3、工程架构示意图