>我们用的开发板和书上的不一样,另外开发环境不太一样,因此这一章内容我们主要介绍开发板和开发环境。 [TOC] # 1. STM32微处理器概述 ## 1.1. Cortex-M 家族 ![image-20240831110223219](./img/image-20240831110223219.png) 使用ARM Cortex-M 内核,由意法半导体生产的STM32F1系列。STM32被广泛应用于各种消费电子产品、工业控制、汽车领域,有完善的产品线和开发工具。 ## 1.2. STM32F103C8T6 - Arm® 32-bit Cortex ®-M3 CPU core - Memories - 64 or 128 Kbytes of Flash memory - 20 Kbytes of SRAM - 2x 12-bit, 1 μs A/D converters (up to 16 channels) - DMA - 7-channel DMA controller - Peripherals supported: timers, ADC, SPIs, - I2Cs and USARTs - Up to 80 fast I/O ports - Debug mode – Serial wire debug (SWD) and JTAG - Seven timers - Three 16-bit timers, each with up to 4 IC/OC/PWM or pulse counter and quadrature (incremental) encoder input - 16-bit, motor control PWM timer with dead-time generation and emergency stop - Two watchdog timers (independent and window) - SysTick timer 24-bit downcounter - Up to nine communication interfaces - Up to two I2C interfaces (SMBus/PMBus®) - Up to three USARTs (ISO 7816 interface, - LIN, IrDA capability, modem control) - Up to two SPIs (18 Mbit/s) - CAN interface (2.0B Active) - USB 2.0 full-speed interface ### 1.2.1. 封装 ![image-20240831135822412](./img/image-20240831135822412.png) ### 1.2.2. 芯片引脚(p17) ![image-20240831135846786](./img/image-20240831135846786.png) - 电源:VDD、VSS;VDDA、VSSA - 复位:NRST - 时钟:OSC,高速和低速,高速8M;低速32.768K,主要用于时钟 - 调试:JATG(下面分析开发板时会标出) - 通用:GPIO 参考资料: - [如何在STM32中获得最佳ADC精度](<../../STM32官方手册/AN2834 - 如何在STM32中获得最佳ADC精度.pdf>) - [STM32中文参考手册](../../STM32%E5%AE%98%E6%96%B9%E6%89%8B%E5%86%8C/STM32%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C.pdf) - [STM32CubeIDE入门指南](../../STM32%E5%AE%98%E6%96%B9%E6%89%8B%E5%86%8C/STM32CubeIDE%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97.pdf) - [STM32CubeMX用户手册](../../STM32%E5%AE%98%E6%96%B9%E6%89%8B%E5%86%8C/STM32CubeMX%E7%94%A8%E6%88%B7%E6%89%8B%E5%86%8C.pdf) - [STM32F1xxHAL库与LL库手册(英文)](../../STM32%E5%AE%98%E6%96%B9%E6%89%8B%E5%86%8C/STM32F1xxHAL%E5%BA%93%E4%B8%8ELL%E5%BA%93%E6%89%8B%E5%86%8C(%E8%8B%B1%E6%96%87).pdf) - [STM32F10xx硬件开发应用笔记](../../STM32%E5%AE%98%E6%96%B9%E6%89%8B%E5%86%8C/STM32F10xx%E7%A1%AC%E4%BB%B6%E5%BC%80%E5%8F%91%E5%BA%94%E7%94%A8%E7%AC%94%E8%AE%B0.pdf) - [STM32F103中文参考手册](../../STM32%E5%AE%98%E6%96%B9%E6%89%8B%E5%86%8C/STM32F103%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C.pdf) - [STM32F103C8规格书](../../STM32%E5%AE%98%E6%96%B9%E6%89%8B%E5%86%8C/STM32F103C8%E8%A7%84%E6%A0%BC%E4%B9%A6.pdf) - [STM32国产替代者](https://www.eeworld.com.cn/mcu/eic676433.html) # 2. KeysKing开发板 两个刚毕业的大学生做的项目,非常适合教学使用,有丰富的扩展。[有视频教材](https://www.bilibili.com/video/BV12v4y1y7uV/?spm_id_from=333.999.0.0&vd_source=3c8e333d6657680a469ddf0238f01d6a)。 ![Alt text](../../%E5%BC%80%E5%8F%91%E6%9D%BF%E8%B5%84%E6%96%99/%E6%8A%98%E9%A1%B5%E5%B0%81%E9%9D%A2%E5%B0%81%E5%BA%95.png) - 自己负责自己的硬件,损坏需要赔偿 - 每个盒子中有一张表格,请核对表格仔细检查附件 - 领用与归还都需要在表格签字 - 大多情况下不需要使用附件,如果要使用附件,请确保电源不要接错烧板子 - B站有视频,有兴趣的朋友可以看视频做更多的实验 ![Alt text](../../%E5%BC%80%E5%8F%91%E6%9D%BF%E8%B5%84%E6%96%99/%E6%8A%98%E9%A1%B5%E5%86%85%E9%9D%A2.png) ## 2.1. 开发板硬件简单解析 [学习板原理图](../../%E5%BC%80%E5%8F%91%E6%9D%BF%E8%B5%84%E6%96%99/%E5%AD%A6%E4%B9%A0%E6%9D%BF%E5%8E%9F%E7%90%86%E5%9B%BE.pdf) 如何看懂电路图?简单,标号一样的就是一样的,或者是相连接的。 ### 2.1.1. 供电 ![image-20240831141714077](./img/image-20240831141714077.png) AP2112是一个线性稳压器件,把5V降压成3.3V为MCU供电。因此开发板有两套电压,5V和3.3V,请注意区分。5V电压哪里来? 通过TYPE-C接口,接计算机的USB接口,其中的VBUS就是5V; ![image-20240831142937858](./img/image-20240831142937858.png) TYPE-C连接到 CH343P (USB转串口),为计算机提供了一个串口,该串口与MCU的PA2、PA3连接,为计算机和开发板的串口建立了通信。 ![image-20240831142857969](./img/image-20240831142857969.png) 另外,调试接口的SWD中的VSWD也是计算机USB的5V。 ![image-20240831143434835](./img/image-20240831143434835.png) 最后看一下电流防倒灌电路: ![image-20240831143539169](./img/image-20240831143539169.png) VBUS是TYPE-C的5V,VSWD是调试接口SWD的5V,通过防倒灌电路使得这两路电源都进入AP2112线性稳压的5V端口,为开发板提供3.3V电压。防倒灌电路等效为一个二极管,使得两个5V电源可以不干扰(同时供电)。 ### 2.1.2. 时钟和复位 ![image-20240831143931440](./img/image-20240831143931440.png) 1的位置是两个时钟,低速(32.768k)和高速(8M)。其中32.768k 是为计时提供精确的脉冲;8M高速通过MCU内部倍频后,可以为MCU内部提供高达72M的核心时钟。 > 为什么需要32.768k的时钟? 2位置是复位电路(低有效),很简单,该端口有个电容,为MCU上电的瞬间提供一个低电位,使得MCU复位;如果按下按钮,该端口被拉低,MCU强制复位。 > 复位电容的工作原理是什么? > > 为什么复位会用低电位,而不用高电位复位? 上述是开发板的主要核心电路分析,后面的课程当中对用到的电路进行分析。要学会看电路的原理图。 # 3. 开发环境 [视频:安装stm32CubeIDE](https://www.bilibili.com/video/BV1HM411b78E/?spm_id_from=333.788&vd_source=3c8e333d6657680a469ddf0238f01d6a) 书上介绍的开发环境是Keil开发环境,这个在51中也使用过,但是该软件是属于商业软件,需要购买。因此我们使用意法半导体提供的免费开发环境stm32cubeide,其开发过程与书上讲的几乎完全一致,且集成度更好,更便于使用。 下载 [stm32cubeide](https://www.st.com.cn/zh/development-tools/stm32cubeide.html) 。 另外,后续的开发中会使用到串口,推荐开源的 xtools 下载 [xtools](https://gitee.com/x-tools-author/x-tools) 。 > 注意,虽然下载不需要用户,但是使用需要登录!否则无法下载相应的芯片资源,无法进行编译!在下图中 MyST 菜单中登录后才能进行相应的开发。 STM32CubeIDE集成了:STM32CubeMX:芯片选型、配置、代码生产等,生成的框架可以供多种IDE使用基于Eclipse的集成开发环境。安装完成后,界面如下: ![image-20240831152413351](./img/image-20240831152413351.png) 一般的开发流程如下: 1. 目标选择 2. 引脚分配 3. 外设配置 4. 时钟配置 5. 工程配置 6. 程序编写 ## 3.1. 升级STLink固件 STLink 调试器版本需更新,否则可能无法下载程序和进行调试。 1. 把调试器插入计算机任何一个USB口; 2. 在Help菜单中找到 ST-Link 更新,出现以下界面: ![image-20240901080238419](./img/image-20240901080238419.png) 3. Refresh Device List 的左边应该出现 ST-LINK/V2 的选项,然后点击1所示的位置,出现2位置的信息,最后点击3位置更新固件。 ## 3.2. 示例:LED闪烁 ### 3.2.1. 新建项目 File->New->STM32 Project 出现以下界面: ![image-20240831155148005](./img/image-20240831155148005.png) 在1位置输入 103C8T6 后,会在2位置出现芯片选择,选择第一个就好,然后点击3位置的Next。 ![image-20240831155320004](./img/image-20240831155320004.png) 在1位置输入项目名称,然后在2位置点击 Next。 ![image-20240831155431546](./img/image-20240831155431546.png) 选择开发固件(其实就是函数编程的接口版本,类似C开发中使用的三方库),一般不用更改,直接点击2位置的Finish完成。如果遇到下图对话框,选择Yes。 ### 3.2.2. 硬件配置 ![image-20240831155740992](./img/image-20240831155740992.png) 上图是说IDE试图打开设备配置的配置方案,询问你是否需要打开。然后下面的界面对芯片进行配置。 ![image-20240831160349011](./img/image-20240831160349011.png) 查看RGB硬件的端口,暂时使用PA6作为需要闪烁的LED。鼠标点击PA6 选择“GPIO_Output”,让PA6作为输出端口;接下来,鼠标右键点击PA6,选择Enter User Label。注意,User Label 是给端口起一个更清晰的别名,这个别名在编程的时候被当成是常量,因此,名字需要符合C语言常量的规则。 ![image-20240831160214958](./img/image-20240831160214958.png) 好了,目前我们的芯片看起来是这样: ![image-20240831163313326](./img/image-20240831163313326.png) PA6变绿,并且有个图钉,表示这个端口已经被配置和占用。使用ctl+s 保存更改,IDE会询问是否生成代码框架,当然选择Yes。 ### 3.2.3. 加入代码 打开 main.c 大约在101 行左右,输入以下代码。注意,注释代码是IDE自动生成的,不要删除! ```c while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_Delay(1000); HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); } /* USER CODE END 3 */ } ``` 代码一定需要在 /* USER CODE BEGIN 3 */ 和 /* USER CODE END 3 */ 之间,因为IDE自动维护代码,否则下一次你重新配置硬件后重新生成代码,你自己的代码有可能丢失,因此请仔细阅读注释文件。 接下来点击运行按钮: ![image-20240831192436902](./img/image-20240831192436902.png) 可能会出现运行配置的界面: ![image-20240831164008506](./img/image-20240831164008506.png) 注意接口应该是SWD,一般不用修改,直接OK后观察开发板的效果。 ### 3.2.4. 调试 如下图,选择编译模式为Debug ![image-20240901113700464](./img/image-20240901113700464.png) 在main.c 中,加入的代码前面双击,会出现一个蓝点,这就是程序运行后中断等待的地方。 ![image-20240901115734594](./img/image-20240901115734594.png) 下图中,点击一个小虫子的图标进行调试: ![image-20240901115845776](./img/image-20240901115845776.png) 程序开始会在 HAL_Init(); 处中断,下图是调试工具: ![image-20240901120232151](./img/image-20240901120232151.png) 依次是: 1. 重新开始调试; 2. 继续(F8); 3. 暂停 4. 停止(ctl+F2) 5. 端口连接 6. 进入到函数(F5) 7. 跳过函数(F6) 8. 跳出函数(F7) 使用 F8 继续,在刚刚的断点处中断: ![image-20240901120618240](./img/image-20240901120618240.png) 继续按F8,间隔1秒以上,观察蓝色LED的变化。 # 4. 开发环境详解 Stm32CubeIDE 其实是由多个工具所构成: - Stm32Cube:该工具是一个独立的工具,可以嵌入到 Stm32CubeIDE 中进行工作。就是在本章 3.2.1 中新建项目用到的这个工具。这个工具包含了芯片选择、芯片配置、芯片相关开发资源下在与更新、代码框架生成和更新等功能。可以这么说,这是STM32开发工具的核心,IDE只是更容易编程和调试而已。 - hEclipse CDT IDE:这是基于Eclipse的C/C++开发环境,用于便捷的代码开发和调试。 - GCC for ARM:C/C++交叉编译环境,用于生成目标代码。 - ST-Link 工具:下载和调试工具,用于把目标代码下载到开发板,或者与Eclipse协同对代码进行调试。 ## 4.1. Stm32Cube 该工具是整个STM32开发的核心,在IDE中,有个后缀为ioc的文件: ![image-20240901084133705](./img/image-20240901084133705.png) 这就是Stm32Cube所维护的文件,该文件中有当前MCU的所有配置信息、项目所依赖的软件功能配置、代码生成控制等信息。通过该工具,最终目的是生成一个代码框架,我们只需要在代码框架下加入我们的业务逻辑就好了。这样就避免了繁琐的芯片初始化、配置等过程,这些工具都给你做好了。 在IDE中,双击后缀为ioc的文件就会打开 Stm32Cube 的界面,如果进行了修改,保存的时候会询问是否重新生成代码框架。 这个工具还有一个功能是维护 MCU Packages 就是不同系列MCU的底层框架代码和一些附加功能代码(网络、USB、操作系统等)。通过 Help 菜单中的 Manage Embedded Software Packages 功能可以打开。可以看到,支持的MCU系列的相关软件包。 ![image-20240901084639078](./img/image-20240901084639078.png) ## 4.2. 编译下载过程 ![Alt text](img/%E7%BC%96%E8%AF%91%E8%BF%87%E7%A8%8B.drawio.png) 上面就是整个的开发的流程,STM32Cube在配置方面减少了开发者大量复杂且容易出错的芯片配置和初始化工作,使得开发者可以专注自己的业务逻辑实现。 接下来我们来看看STM32Cube帮助我们做了些什么,我们的代码结构如下: ![image-20240901091010047](./img/image-20240901091010047.png) - Binaries 是编译后的目标文件; - Includes 是引用的 Embedded Software Packages 中的头文件,主要实现芯片初始化、外设配置、操作系统、网络协议栈等功能。这些功能都准备好了,只需要配置和使用就可以了; - Core 用户的核心代码在这里; - Drivers 硬件抽象层的代码在这里,包括各种外围硬件驱动,操作系统配置等; - Debug/Release 和传统C/C++一样,编译的中间代码; - Blink.ioc 工程文件,被 Stm32Cube 所维护; - 其他文件。。。 其实,大部分时间,开发者只需要维护 Core 中的部分代码即可。 ## 4.3. 代码分析 ![image-20240901091716720](./img/image-20240901091716720.png) 这里重点看 main.h 和 main.c 这两个文件。 main.h 中重点看看 60 行左右: ```c /* Private defines -----------------------------------------------------------*/ #define LED_Pin GPIO_PIN_6 #define LED_GPIO_Port GPIOA ``` 这两行宏定义是因为刚刚把 PA6 定义了一个Label叫做LED。框架在生成代码的时候会自动生成相应的常量(注意常量的生成规则),以后在使用的时候,就可以使用这些常量了。 在main.c的 **static** **void** **MX_GPIO_Init**(**void**) 函数中,大约 150 行 ```c /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : LED_Pin */ GPIO_InitStruct.Pin = LED_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct); ``` 生成的代码对PA5端口进行了初始化。以上的代码都是自动生成的,一般不用去关心,框架简化了我们的开发工作。 用户逻辑代码,在main.c 大约100行左右: ```c while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_Delay(1000); HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); } /* USER CODE END 3 */ } ``` 注意用户代码必须在 /* USER CODE BEGIN 3 */ 和 /* USER CODE END 3 */ 之间!否则重新生成代码的时候会被删除。 HAL_Delay(1000); 表示使用延时1000毫秒; HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); 两个参数,第一个代表端口,就是上面的常量定义的LED端口;第二个代表具体的引脚,就是LED的端口。 > 其实框架还生成了很多工作,包括MCU的时钟初始化、总线初始化、内存初始化等工作。这些工作都使用 Stm32Cube 的配置进行,代码是自动生成的,一般不用关心。在后续的工作当中,我们还会用到很多Stm32Cube的配置功能。 ## Stm32Cube 基本功能 ![image-20240901123125992](./img/image-20240901123125992.png) 该工具四大功能: 1. Pinout & Configuartion:端口,外设和中间件(操作系统、网络协议栈、USB驱动等)配置; 2. Clock Configuration:时钟配置; 3. Project Manager:项目配置,主要用于代码生成的一些偏好设置,一般不用关心; 4. Tools:工具,主要是能耗分析等。 一般最常用的就是 Pinout & Configuartion 和 Clock Configuration