01-1软件开发与2-1新建工程
参考STM32PCB设计物联网手牵手带你从零开始画板子写代码https://www.bilibili.com/video/BV18arkYjEuLSTM32入门教程-2023版 细致讲解 中文字幕https://www.bilibili.com/video/BV1th411z7sn【已完结STM32】–自学江协科技笔记汇总https://blog.csdn.net/2301_81011494/article/details/1470691641.1课程简介https://www.bilibili.com/video/BV1th411z7sn/2-1软件开发安装过程见00-Keil与STLINK与CH340安装2-2新建工程1.新建文件夹新建工程的文件夹d:\stm32pro\打开Keil5软件–选择Project—New uVision Project --选择d:\stm32pro\然后选择刚刚我们新建的文件夹在 新建文件夹 里面再建一个文件夹d:\stm32pro\2-1STM32工程模板进入d:\stm32pro\2-1STM32工程模板输入工程文件名Project然后点击保存工程接下来就是选择芯片型号我们的芯片型号是STM32F103C8T6。用来存放本次工程。点击OK弹出来的是新建工程小助手这个可以帮助我们快速新建工程我们暂时用不到这个直接选择叉掉。这样就新建好一个工程但是还不完整还需要添加文件此时的工程目录如下2.start启动文件添加文件到本地的Start目录下工程建好之后 还需要添加一些库文件首先在工程文件夹下新建一个Start启动文件然后打开固件库文件夹D:\BaiduNetdiskDownload\STM32入门教程资料\固件库\固件库\STM32F10x_StdPeriph_Lib_V3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\找到启动文件D:\BaiduNetdiskDownload\STM32入门教程资料\固件库\固件库\STM32F10x_StdPeriph_Lib_V3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm固件库文件来自b站江科大可自行下载见固件库的下载方式将arm里面的启动文件全部复制到工程模板文件夹Start文件夹下接着回到STM32F10x文件夹找到STM32头文件和配置时钟文件也复制到Star文件夹下接着还需要添加内核寄存器的描述文件打开文件路径D:\BaiduNetdiskDownload\STM32入门教程资料\固件库\固件库\STM32F10x_StdPeriph_Lib_V3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport\同样复制到Start文件夹下把本地Start目录下的文件添加到Keil5工程中接着回到Kile5把刚才复制到的文件添加到工程里单击Source Group 1可将其改为Start然后右键单击Start选择AddExisting Files to Group ‘Start’弹出的页面默认只添加.c文件选择文件类型中的所有类型可以看到所有文件这里只需要添加后缀为md.s的启动文件就可以了 选择add然后单击close然后把 本地Start目录中剩下的的.c和.h文件都要添加进来3、添加头文件路径最后还需要在工程选项添加头文件路径首先确定ARM 的Compiler 选择version5右键Keil5中左侧选择Options for Target ‘Target1’弹出的选项界面中选择C/C选项然后选择Include Paths选择新建new选择三个点的图标选择头文件的目录按照要求选择目录即可4、 测试工程测试工程是否可行在工程本地文件夹下新建一个User文件用来存放main函数进来Kile5右击Target1添加组并将其改名为User然后右击User添加新项目到组里选择文件类型设置文件名文件的路径单击确定即可这样工程文件夹里面就可以看到有一个main文件了插入头文件并编写一个main函数注意代码最后一行必须空行否则会报警告#include stm32f10x.h // Device header int main(void) { while(1) { } }以上配置就可以用寄存器开发32单片机了。当然用寄存器开发STM32不太适合初学者后面还要添加库函数。现在进行build 编译通过0错误0警告就证明工程建立成功5、连接下载器ST-LINK注意事项ST-LINK通过杜邦线链接最小系统版注意接线插上后会出现一个灯亮表示电源链接在PC13的灯默认是闪烁状态这是芯片里的一个测试程序插上下载器ST-LINK,点击魔术棒找到Debug选择ST-Link 然后选择Flash Download为自动复位然后选择工程的build编译成功后单击load如果load成功Keil会提示同时最小系统版的灯不再闪烁因为load进去的代码没有操作6、测试点灯基于寄存器配置测试点灯程序 最小系统板上的的灯是低电平点亮的0x00002000是灯灭0x00000000是灯亮打开D:\BaiduNetdiskDownload\STM32入门教程资料\参考文档\参考文档\STM32F10xxx参考手册中文.pdf7.3.7 APB2外设时钟使能寄存器(RCC_APB2ENR)GPIO都是APB2的外设,在7.3.7 APB2外设时钟使能寄存器(RCC_APB2ENR)00000000 00000000 00000000 00010000 00 00 00 10 0X00000010#include stm32f10x.h // Device header int main(void) { // 使能GPIOC RCC-APB2ENR 0X00000010; while(1) { } }在8.2.2端口配置寄存器(GPIOx_CRH)(xA…E)这样如果给GPIOC的13设置为通用推挽 输出模式设置为50MHz21:20位为 11输出模式设置为50MHz 2322位为00通用推挽模式 00000000 00110000 00000000 00000000 00 30 00 00 00300000代码如下#include stm32f10x.h // Device header int main(void) { // 使能GPIOC RCC-APB2ENR 0X00000010; // 设置GPIOC 推挽与50MHz GPIOC-CRH0X00300000; while(1) { } }在8.2.4端口输出寄存器(GPIOx_ODR)(xA…E)可以看到如果想给PC13上的灯点亮低电平点亮给ODR设置为0可以都设置为0,即GPIOC-ODR0X00000000 表示灯亮给GPIOC-ODR0X00002000表示灯灭二进制和十六进制为00000000 00000000 00100000 00000000 00 00 20 00 00002000 00000000 00000000 00100000 00000000 00 00 20 00 00002000#include stm32f10x.h // Device header int main(void) { // 使能GPIOC RCC-APB2ENR 0X00000010; // 设置GPIOC 推挽与50MHz GPIOC-CRH0X00300000; // 设置灯亮 GPIOC-ODR0X00000000; // 设置灯灭 //GPIOC-ODR0X00002000; while(1) { } }实现闪烁#include stm32f10x.h // Device header int main(void){ RCC-APB2ENR 0x00000010; // 设置GPIOC 推挽与50MHz GPIOC-CRH0X00300000; while(1){ uint32_t i, j; // 在循环外声明变量兼容C90标准 for(i 0; i 3000; i) for(j 0; j 3600; j); // 大约1ms的延时 GPIOC-ODR0X00000000 ;//表示灯亮 for(i 0; i 3000; i) for( j 0; j 3600; j); // 大约1ms的延时 GPIOC-ODR0X00002000 ;//表示灯灭 } }循环版本#include stm32f10x.h // Device header // 延时函数大约延时ms毫秒 void Delay_ms(uint32_t ms) { uint32_t i, j; // 简单的软件延时具体值需要根据实际系统时钟校准 for(i 0; i ms; i) for(j 0; j 7200; j); // 大约1ms的延时 } int main(void){ //RCC-APB2ENR0X00000010; // 使能GPIOC RCC-APB2ENR 0X00000010; // 设置GPIOC 推挽与50MHz GPIOC-CRH0X00300000; while(1){ // 设置灯亮 GPIOC-ODR0X00000000; Delay_ms(3000); // 延时3秒 // 设置灯灭 GPIOC-ODR0X00002000; Delay_ms(3000); // 延时3秒 } }7.添加库函数上面的方式需要经常查看手册的寄存器采用库函数可以解决这个问题打开工程文件夹新建一个文件夹Library用来存放库函数打开固件库文件找内核库函数源文件路径D:\BaiduNetdiskDownload\STM32入门教程资料\固件库\固件库\STM32F10x_StdPeriph_Lib_V3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver\src打开固件库文件找内核库函数头文件路径D:\BaiduNetdiskDownload\STM32入门教程资料\固件库\固件库\STM32F10x_StdPeriph_Lib_V3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\STM32F10x_StdPeriph_Driver\inc然后Ctrla全选复制刚刚新建的到工程文件夹下Library文件夹下回到Kile5右击Target1添加组并命名为Library右击Library添加存在的文件,将库函数源文件和头文件全部添加进来至此库函数还不能直接使用还需要再添加一个文件。接着打开固件库文件D:\BaiduNetdiskDownload\STM32入门教程资料\固件库\固件库\STM32F10x_StdPeriph_Lib_V3.5.0\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Template\把stm32f10x_it.h stm32f10x_it.c stm32f10x_conf.h复制到User目录下接着回到Kile5把刚刚的三个文件添加到User组里最后我们还需要一个宏定义跳转到头文件stm32f10x.h下滑到最后找到 USE_STDPERIPH_DRIVER然后选择魔法棒–选择C将USE_STDPERIPH_DRIVER复制到Define ,同时在include中添加User和Library目录最后编译一下0错误0警告说明工程建立成功8.用库函数点灯RCC_APB2PeriphClockCmd函数通过右键RCC_APB2PeriphClockCmd()跳转到定义的位置第一个参数选择 RCC_APB2Periph_GPIOC第二个参数ENABLE// #define RCC_APB2Periph_GPIOC ((uint32_t)0x00000010)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);GPIO_Init函数通过右键RCC_APB2PeriphClockCmd()跳转到定义的位置第一个参数为GPIO_TypeDef* GPIOx, 第二个参数为GPIO_InitTypeDef* GPIO_InitStruct参数需要一个结构体就需要先定义一个结构体// 定义GPIO的结构体通过.设置结构体的属性 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode GPIO_InitStructure.GPIO_Pin GPIO_InitStructure.GPIO_Speed 右键GPIO_Mode可以看到定义的位置注释中的无法跳转选择GPIOMode_TypeDef然后复制查找可以看到GPIOMode_TypeDef是一个枚举可以把GPIO_Mode_Out_PP设置给结构体// 定义GPIO的结构体通过.设置结构体的属性 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin GPIO_InitStructure.GPIO_Speed 右键GPIO_Pin查看定义出现左下角的多个定义选择member跳转到选择注释中的GPIO_pins_definectrlf可以快速查找选择Find Next复制 GPIO_Pin_13 到GPIO_Pin// 定义GPIO的结构体通过.设置结构体的属性 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin GPIO_Pin_13; GPIO_InitStructure.GPIO_Speed 右键跳转在注释中ctrlf查找可以看到是一个枚举类型选择GPIO_Speed_50MHz复制GPIO_Speed_50MHz到 GPIO_InitStructure.GPIO_Speed如下// 定义GPIO的结构体通过.设置结构体的属性 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函数// 定义GPIO的结构体通过.设置结构体的属性 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; // 初始化GPIOC // 第一个参数为GPIO_TypeDef* GPIOx, 第二个参数为GPIO_InitTypeDef* GPIO_InitStruct // 先在上面初始化一个GPIO_InitTypeDef结构体 变量名为 GPIO_InitStructure GPIO_Init(GPIOC,GPIO_InitStructure);编译下出现如下问题问题13编译时出现错误declaration may not appear after executable statement in block可以把GPIO_InitTypeDef GPIO_InitStructure;放在句首也可以在c/c选项卡在勾选C99 Mode就可以在 在函数的可执行语句之后定义变量了。GPIO_SetBits和GPIO_ResetBits函数// 给GPIOC的13端口设置高电平 //GPIO_SetBits(GPIOC,GPIO_Pin_13); // 给GPIOC的13端口设置低电平 GPIO_ResetBits(GPIOC,GPIO_Pin_13);编译下然后load 就出现灯亮了9.新建工程步骤建立工程文件夹Keil中新建工程选择型号工程文件夹里建立Start、Library、User等文件夹复制固件库里面的文件到工程文件夹工程里对应建立Start、Library、User等同名称的分组然后将文件夹内的文件添加到工程分组里工程选项C/CInclude Paths内声明所有包含头文件的文件夹工程选项C/CDefine内定义USE_STDPERIPH_DRIVER工程选项Debug下拉列表选择对应调试器SettingsFlash Download里勾选Reset and Run10.工程结构所以复位键后程序后重新启动单片机的程序最后为一个死循环永远不会结束SystemInit的函数定义在system开头.c的里了拓展固件库的下载方式进入官网意法半导体官网 | ST官网 - STMicroelectronics选择产品–微处理器选择主流MCU,选择F1系列选择STM32F103选择工具与软件选择嵌入式软件中的MCU and MPU embedded software,选择STM32 Standard Peripheral Libraries选择STSW-STM32054选择打开Open software page选择对应的版本这里选择的是3.5选择版本后谈成是否接受界面单击接受后进入登录或访客下载页面登录或访客都可以进入版本选择并选择版本边上的下载按钮即完成下载的功能下载后的压缩包与提供的压缩包内容一致。拓展固件库的目录说明STM32 标准外设库StdPeriph Library是 ST 官方为简化开发提供的工具包其目录结构分工明确。以下结合典型目录以 STM32F1 系列为例解析核心目录的作用一、核心目录Libraries驱动库核心是外设库的底层支撑包含CMSIS 内核抽象层和STM32 外设驱动层让开发者无需直接操作寄存器即可控制硬件。1.CMSIS 文件夹Cortex-M 软件接口标准作用实现 Cortex-M 内核与芯片外设的解耦让代码兼容不同厂商的 Cortex-M 芯片同时简化内核相关操作如中断、调试。子目录分解Core_Supportcore_cm3.c/h对应 Cortex-M3 内核M4/M7 内核则为core_cm4.c/h等定义内核寄存器的操作函数如配置 NVIC 中断优先级、系统滴答定时器实现内核外设如 SysTick、NVIC的驱动。这些文件是 ARM 官方提供的通用代码与 STM32 芯片无关只负责内核层面的抽象。Device/ST/STM32F1xx启动文件如startup_stm32f10x_h/m/ld.s汇编编写芯片上电后第一步执行的代码负责初始化栈指针、复制全局变量到 RAM、跳转到main函数。不同容量的芯片小/中/大容量对应不同启动文件如hd代表大容量。system_stm32f10x.c/h定义SystemInit()函数初始化系统时钟配置 HSE、HSI、PLL 等设置 AHB/APB 总线分频是启动流程的关键步骤。 STM32主频是72MHz就是这个文件中配置的stm32f10x.h外设寄存器的映射文件通过宏和结构体如GPIO_TypeDef定义所有外设的寄存器地址如GPIOA-CRL对应 GPIOA 的配置寄存器是库函数操作硬件的基础。类似Reg51.h ,描述有哪些寄存器和地址有些类似域名与ip地址的关系2.STM32F10x_StdPeriph_Driver 文件夹外设驱动层作用为 STM32 的每个外设GPIO、UART、SPI 等提供封装好的库函数开发者通过调用函数即可配置外设无需深入寄存器细节。子目录分解inc 文件夹存放外设的头文件如stm32f10x_gpio.h、stm32f10x_usart.h定义初始化结构体如GPIO_InitTypeDef包含引脚模式、速度、上下拉等参数。声明库函数如GPIO_Init()、USART_SendData()。定义寄存器的位掩码如GPIO_Mode_Out_PP代表推挽输出模式。src 文件夹存放外设的源文件如stm32f10x_gpio.c、stm32f10x_usart.c实现inc中声明的函数内部通过操作stm32f10x.h的寄存器完成功能如GPIO_Init()会修改GPIOx-CRL/CRH寄存器。每个外设的功能如 GPIO 翻转、UART 发送数据都通过这里的函数封装。特殊文件misc.c/h提供对**内核 NVIC中断控制器**的操作函数如NVIC_Init()配置中断优先级、NVIC_EnableIRQ()使能中断因为 NVIC 属于内核外设需与芯片外设的中断配合使用。二、辅助目录项目开发相关1.Project 文件夹作用提供官方示例工程和编译器模板快速上手开发。内容STM32F10x_StdPeriph_Examples按外设分类的示例如 GPIO 翻转、UART 通信、SPI 传输可直接导入 Keil/IAR 编译学习外设的典型用法。Templates针对不同编译器Keil、IAR的工程模板包含最小化的文件结构已关联库路径、包含必要头文件开发者可在此基础上扩展功能。2.Utilities 文件夹作用存放 ST 官方评估板如 STM32 Discovery、Eval 板的专用驱动和示例。内容评估板上的扩展硬件如显示屏、传感器、按键的驱动代码如stm32_eval_led.c。若使用通用开发板这部分可忽略但其中的驱动设计思路如分层封装、状态机可借鉴。3.根目录文件stm32f10x_stdperiph_lib_um.chm库函数帮助文档CHM 格式详细说明每个库函数的参数、功能、使用示例如USART_Config()如何配置波特率、校验位是开发时的核心参考。Release_Notes.html版本说明记录库的更新内容、支持的芯片型号、已知问题用于确认库的兼容性。三、目录协作关系与开发流程底层支撑Libraries/CMSIS负责内核和芯片的基础初始化启动、时钟、寄存器映射。外设控制Libraries/STM32F10x_StdPeriph_Driver提供外设的库函数开发者通过调用这些函数配置硬件如GPIO_Init()设置引脚模式。快速验证Project中的示例和模板可直接复用减少搭建工程的时间。参考学习Utilities中的评估板代码和chm文档辅助理解外设用法。通过合理利用这些目录开发者可跳过寄存器级的繁琐操作专注于应用层逻辑大幅提升开发效率。若需深入底层也可通过stm32f10x.h和core_cm3.h查看寄存器定义实现库函数的扩展或自定义。拓展GPIO 与 APB2在STM32微控制器中这句话描述的是GPIO通用输入/输出端口与系统总线架构中APB2总线的连接关系以下从微控制器的总线架构、APB2总线特点、GPIO作为外设的属性这几个方面来深入理解微控制器的总线架构STM32微控制器采用了先进的总线架构以实现不同功能模块之间高效的数据传输和控制。其中常见的总线有AHBAdvanced High-performance Bus高级高性能总线和APBAdvanced Peripheral Bus高级外设总线 。AHB总线主要用于连接高性能、高数据传输速率的模块如CPU内核、存储器、DMA控制器等。它能够支持高速的数据传输满足对带宽要求较高的设备之间的数据交互。APB总线则是用于连接低带宽的外设模块为这些外设提供了一种相对简单且低功耗的通信方式。APB又分为APB1和APB2它们的主要区别在于工作频率和所连接的外设类型。APB2总线特点APB2总线相较于APB1总线通常具有更高的工作频率。这意味着连接到APB2总线上的外设可以在更快的时钟信号驱动下工作从而具备更高的数据传输速率和响应速度。在STM32系列中APB2总线通常用于连接那些对速度要求相对较高的外设。GPIO作为APB2的外设GPIO功能简介GPIO是STM32中非常重要且常用的外设它允许用户通过软件灵活地配置引脚的功能如设置为输入模式来读取外部信号像按键状态或者设置为输出模式来控制外部设备如点亮LED灯。连接关系原因GPIO在工作时有时需要快速地响应外部信号的变化或者及时输出控制信号比如在驱动高速通信接口的使能引脚或者快速切换LED灯的亮灭状态来实现高频闪烁效果等场景下就对数据传输和处理速度有一定要求。将GPIO连接到APB2总线上利用APB2相对较高的工作频率能够满足GPIO在这些快速操作场景下的性能需求。不过需要注意并不是所有STM32系列微控制器的GPIO都是APB2的外设 。不同型号的STM32其外设与总线的连接情况会根据芯片的设计和定位有所差异。比如一些低功耗或低成本的STM32型号其GPIO可能会连接到APB1总线上以平衡性能和功耗等方面的需求。拓展RCC_APB2ENR在STM32微控制器中RCC_APB2ENR是一个寄存器它是复位和时钟控制Reset and Clock ControlRCC模块的一部分全称为APB2外设时钟使能寄存器Advanced Peripheral Bus 2 Peripheral Clock Enable Register主要用于控制连接在APB2总线上的外设时钟的开启和关闭。以下从寄存器基本概念、作用原理以及使用方式这几个方面来理解它寄存器基本概念寄存器是微控制器内部的一组存储单元每个寄存器都被分配了特定的地址。通过对这些地址进行读写操作就可以访问和修改寄存器中的值进而实现对微控制器不同功能模块的配置和控制。RCC_APB2ENR寄存器也是如此它在内存中占据特定的地址空间用户可以通过编程来读写这个寄存器。作用原理时钟控制机制在STM32中为了降低功耗以及对不同外设进行灵活管理并不是所有外设的时钟在系统上电后都处于开启状态。每个外设都有对应的时钟使能位当该位被设置为1时相应外设的时钟才会被打开外设才能正常工作如果设置为0 外设时钟被关闭此时外设处于低功耗状态无法执行数据处理等操作。与APB2总线外设关联APB2总线上连接着一些对速度要求相对较高的外设比如GPIO端口部分STM32型号、ADC模拟数字转换器、SPI1串行外设接口1等。RCC_APB2ENR寄存器中的每一位都对应着一个连接在APB2总线上的外设。例如在STM32F103系列中RCC_APB2ENR寄存器的第2位对应着IOPAENGPIOA时钟使能位第3位对应着IOPBENGPIOB时钟使能位等。当要使用某个APB2外设时就需要将该外设对应的时钟使能位置1 为其提供时钟信号外设才能按照设定的功能运行。具体使用方式以STM32F103为例基于标准外设库头文件包含在使用与RCC_APB2ENR相关的功能之前需要在代码中包含对应的头文件如stm32f10x.h该头文件中定义了RCC_APB2ENR寄存器以及相关的宏定义。#includestm32f10x.h使能外设时钟比如要使用GPIOA端口就需要使能GPIOA的时钟示例代码如下// 使能GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);在上述代码中RCC_APB2PeriphClockCmd是标准外设库中提供的函数它的第一个参数指定要使能时钟的外设这里是RCC_APB2Periph_GPIOA对应RCC_APB2ENR寄存器中的IOPAEN位第二个参数ENABLE表示使能该外设时钟其本质就是对RCC_APB2ENR寄存器中对应的位进行置1操作。关闭外设时钟当某个外设不再使用时为了降低功耗可以关闭其时钟示例代码如下// 关闭GPIOA时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,DISABLE);这里的DISABLE参数会将RCC_APB2ENR寄存器中IOPAEN位清0从而关闭GPIOA的时钟。总之RCC_APB2ENR寄存器是STM32中管理APB2总线上外设时钟的关键部件合理地配置它能够有效地控制外设的工作状态实现对系统功耗和性能的优化。拓展GPIOx_CRH寄存器在STM32微控制器中配置完RCC_APB2ENR使能GPIO时钟后还需要配置端口配置寄存器GPIOx_CRHx A..E这是因为两者承担着不同且互补的功能具体如下时钟使能是基础前提RCC_APB2ENR寄存器用于使能连接在APB2总线上的外设时钟对于GPIO端口而言使能其时钟是必不可少的准备工作。只有当GPIO对应的时钟使能位例如RCC_APB2ENR中与GPIOA对应的IOPAEN位被置1 GPIO端口才能正常工作。这就好比给一个工厂供电只有先接通电源工厂里的机器GPIO外设才有可能运转起来 但仅接通电源机器并不会自动按照我们期望的方式工作还需要对其进行功能设定。GPIOx_CRH决定端口具体功能GPIOx_CRH寄存器是GPIO端口的配置寄存器高8位配置寄存器对应引脚GPIOx_8 - GPIOx_15低8位配置寄存器是GPIOx_CRL对应引脚GPIOx_0 - GPIOx_7它的作用是详细设定GPIO引脚的工作模式和输出速度等关键参数具体如下1. 配置引脚工作模式GPIO引脚可以配置为多种工作模式以满足不同的应用需求GPIOx_CRH中的相关位用于选择这些模式输入模式浮空输入IN_FLOATING引脚的电平状态完全由外部输入决定内部没有上拉或下拉电阻常用于读取外部信号如按键输入。上拉输入IPU引脚内部连接了上拉电阻默认情况下引脚被拉高为高电平当外部连接低电平信号时引脚电平被拉低适用于按键等外部信号常态为高电平的场景。下拉输入IPD与上拉输入相反引脚内部连接下拉电阻默认被拉低为低电平用于外部信号常态为低电平的情况。模拟输入AIN引脚用于连接模拟信号源关闭施密特触发器一种用于波形整形的电路直接将外部模拟信号接入内部ADC模拟数字转换器用于模拟量采集。输出模式通用推挽输出GPIO_Mode_Out_PP引脚可以输出高电平或低电平驱动能力较强常用于驱动LED灯、继电器等需要较大电流的负载。通用开漏输出GPIO_Mode_Out_OD引脚只能输出低电平输出高电平时需要外部上拉电阻将引脚拉高适用于需要“线与”逻辑多个开漏输出引脚连接在一起只要有一个输出低电平整体就为低电平的场景或者用于电平转换。复用推挽输出GPIO_Mode_AF_PP引脚用于复用功能如SPI、USART等外设的引脚由外设模块控制引脚的输出信号同样具有较强的驱动能力。复用开漏输出GPIO_Mode_AF_OD与复用推挽输出类似但输出高电平时需要外部上拉电阻常用于I2C等需要“线与”逻辑的复用功能场景。2. 配置输出速度在输出模式下还可以通过GPIOx_CRH设置引脚的输出速度常见的有2MHz、10MHz、50MHz等选项。 输出速度决定了引脚电平翻转的速率合理选择输出速度可以避免信号干扰和电磁兼容性EMC问题。例如驱动LED灯时较低的输出速度如2MHz即可满足要求而在高速通信接口如SPI中可能就需要选择较高的输出速度如50MHz以满足数据传输速率的要求。两者配合实现完整功能配置RCC_APB2ENR打开GPIO时钟是让GPIO模块能够正常工作而配置GPIOx_CRH和GPIOx_CRL则是告诉GPIO模块具体要做什么比如某个引脚是用于输入按键信号还是用于输出驱动LED的信号以及以什么样的速度和方式进行输入输出操作。只有这两步配置都正确完成GPIO引脚才能按照开发者的预期在电路中发挥作用实现与外部设备的有效交互。拓展stm32f10x_it.h和stm32f10x_it.c和stm32f10x_conf.h作用在STM32F10x系列的标准外设库项目中stm32f10x_it.h、stm32f10x_it.c和stm32f10x_conf.h是三个具有特定功能的核心文件分别承担中断服务程序管理和库配置的作用具体解析如下1.stm32f10x_it.h和stm32f10x_it.c中断服务程序ISR的集中管理这两个文件是中断服务程序的专用存放地用于定义和实现STM32的所有中断处理函数是系统响应外部事件如GPIO触发、定时器溢出、串口接收等的核心逻辑载体。核心作用中断函数声明与实现分离stm32f10x_it.h声明所有中断服务函数的原型如EXTI0_IRQHandler()、TIM2_IRQHandler()供其他模块调用或引用。stm32f10x_it.c实现这些中断服务函数的具体逻辑例如在外部中断触发时读取GPIO状态、在定时器中断中更新变量等。统一管理中断向量表映射STM32的中断向量表启动文件中定义会将硬件中断信号映射到stm32f10x_it.c中对应的函数。例如当外部中断线0EXTI0触发时系统会自动跳转到EXTI0_IRQHandler()函数执行。避免中断函数命名冲突中断服务函数的名称是固定的由芯片硬件决定如USART1_IRQHandler对应串口1中断将其集中放在这两个文件中可避免与其他模块的函数命名冲突规范代码结构。示例场景当需要处理按键触发的外部中断如PA0引脚连接按键触发EXTI0中断时会在stm32f10x_it.c中实现voidEXTI0_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line0)!RESET){// 处理中断逻辑如点亮LED、更新标志位GPIO_SetBits(GPIOC,GPIO_Pin_13);// 清除中断标志位必须操作否则会持续触发中断EXTI_ClearITPendingBit(EXTI_Line0);}}而stm32f10x_it.h中会声明该函数voidEXTI0_IRQHandler(void);2.stm32f10x_conf.h外设库的配置开关该文件是标准外设库的“配置中心”通过宏定义控制是否启用特定外设的驱动文件、中断向量和调试信息用于裁剪项目代码、减少编译体积。核心作用选择性包含外设驱动头文件文件中通过#define宏控制是否包含某个外设的头文件。例如#defineUSE_STDPERIPH_DRIVER// 启用标准外设库#includestm32f10x_gpio.h// 包含GPIO驱动#includestm32f10x_usart.h// 包含USART驱动// #include stm32f10x_adc.h // 注释掉则不启用ADC驱动未被包含的外设驱动不会被编译从而减少固件体积。控制中断向量的使能部分外设的中断向量需要通过该文件间接控制结合stm32f10x_it.c。例如若不启用ADC则可注释掉#include stm32f10x_adc.h避免ADC相关的中断函数被编译。定义库函数的调试输出开关部分库函数如assert_param()参数检查的调试信息输出可通过该文件中的宏如USE_FULL_ASSERT控制是否启用便于开发阶段调试和量产阶段关闭冗余输出。典型配置示例// 启用参数检查开发阶段用量产可关闭#defineUSE_FULL_ASSERT// 包含需要使用的外设驱动#includestm32f10x_rcc.h// 时钟控制#includestm32f10x_gpio.h// GPIO控制#includestm32f10x_tim.h// 定时器控制// 不包含SPI和I2C驱动项目中用不到// #include stm32f10x_spi.h// #include stm32f10x_i2c.h三者的协作关系stm32f10x_conf.h决定项目中启用哪些外设驱动为中断处理和其他功能提供基础支持。当外设触发中断时中断向量表会引导系统执行stm32f10x_it.c中对应的中断服务函数而这些函数的声明在stm32f10x_it.h中。三者共同构成了STM32中断系统和外设管理的核心框架确保中断响应的规范性和代码的可维护性。void);#### 2. stm32f10x_conf.h外设库的配置开关 该文件是**标准外设库的“配置中心”**通过宏定义控制是否启用特定外设的驱动文件、中断向量和调试信息用于裁剪项目代码、减少编译体积。 ##### 核心作用 - **选择性包含外设驱动头文件** 文件中通过#define宏控制是否包含某个外设的头文件。例如 c #define USE_STDPERIPH_DRIVER // 启用标准外设库 #include stm32f10x_gpio.h // 包含GPIO驱动 #include stm32f10x_usart.h // 包含USART驱动 // #include stm32f10x_adc.h // 注释掉则不启用ADC驱动未被包含的外设驱动不会被编译从而减少固件体积。控制中断向量的使能部分外设的中断向量需要通过该文件间接控制结合stm32f10x_it.c。例如若不启用ADC则可注释掉#include stm32f10x_adc.h避免ADC相关的中断函数被编译。定义库函数的调试输出开关部分库函数如assert_param()参数检查的调试信息输出可通过该文件中的宏如USE_FULL_ASSERT控制是否启用便于开发阶段调试和量产阶段关闭冗余输出。典型配置示例// 启用参数检查开发阶段用量产可关闭#defineUSE_FULL_ASSERT// 包含需要使用的外设驱动#includestm32f10x_rcc.h// 时钟控制#includestm32f10x_gpio.h// GPIO控制#includestm32f10x_tim.h// 定时器控制// 不包含SPI和I2C驱动项目中用不到// #include stm32f10x_spi.h// #include stm32f10x_i2c.h三者的协作关系stm32f10x_conf.h决定项目中启用哪些外设驱动为中断处理和其他功能提供基础支持。当外设触发中断时中断向量表会引导系统执行stm32f10x_it.c中对应的中断服务函数而这些函数的声明在stm32f10x_it.h中。三者共同构成了STM32中断系统和外设管理的核心框架确保中断响应的规范性和代码的可维护性。通过合理配置这三个文件开发者可以高效管理中断逻辑、裁剪项目代码适配不同场景的需求如资源受限的嵌入式设备需最小化固件体积。