版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1章ARMCortex-M3内核与STM32微控制器 ARMv7架构分为哪几个系列?各系列针对哪些应用?ARMv7架构分为3个系列:Cortex-A系列:针对日益增长的应用程序运行需求,包括Linux、WindowsCE、Android和iOS系统的消费电子和无线产品,如智能手机、平板电脑等。Cortex-R系列:针对需要运行实时操作系统来进行控制应用的系统,如汽车电子、硬盘控制器等实时性要求较高的领域。Cortex-M系列:应用于当前8/16位微控制器MCU的替代产品,面向微控制器和低成本、低功耗的嵌入式应用领域。简述ARMCortex-M3处理器的性能特点。ARMCortex-M3是一款基于ARMv7架构的嵌入式处理器核心,其主要性能特点包括:采用哈佛架构,具备独立的指令和数据总线,能够同时进行多个操作,提高运行效率。内核流水线设计为3个阶段:取指、解码和执行。32位处理器,拥有32位内部数据总线和32位寄存器。支持Thumb-2指令集,兼容传统Thumb指令,代码密度高,内存使用减少约31%,性能提升约38%。配备13个通用寄存器、2个堆栈指针寄存器、1个链接寄存器、1个程序计数器。具有NVIC(嵌套向量中断控制器),支持中断嵌套,中断响应速度快。低功耗设计,适合嵌入式应用。试述STM32F10x系列微控制器片内包含哪些资源?STM32F10x系列微控制器片内主要包含以下资源:ARMCortex-M332位RISC内核Flash存储器(程序存储器)SRAM静态随机存取存储器(数据存储器)GPIO通用输入输出端口(多达多个端口,每个端口16个引脚)多个定时器(高级定时器、通用定时器、基础定时器)多个USART/UART串口SPI接口I2C接口ADC模数转换器(12位分辨率)DMA控制器外部中断EXTIRTC实时时钟看门狗定时器(独立看门狗和窗口看门狗)时钟和复位系统(RCC)电源管理模块调试接口(SWD/JTAG)STM32F10x系列内核工作频率最高可达多少?STM32F10x系列微控制器的内核工作频率最高可达72MHz。根据STM32命名规则,STM32F103RBT6的引脚、封装、Flash大小是什么?根据STM32命名规则分析STM32F103RBT6:STM32:32位微控制器F:产品类型(通用型)103:子系列(增强型)R:引脚数——64引脚B:Flash容量——128KBT:封装类型——LQFP封装6:工作温度范围——-40°C~85°C所以:引脚数为64脚,封装为LQFP,Flash大小为128KB。STM32F10x系列产品中的高密度、中密度和低密度是按什么划分的?STM32F10x系列产品中的高密度、中密度和低密度是按照片内Flash存储器容量来划分的:低密度:Flash容量在16KB~32KB之间中密度:Flash容量在64KB~128KB之间高密度:Flash容量在256KB~512KB之间简述冯·诺依曼架构和哈佛架构特点。STM32F10x的微处理器采用的是哪种架构?冯·诺依曼架构特点:程序指令和数据存放在同一个存储器中,共用同一条总线。结构简单,但指令和数据不能同时读取,存在"冯·诺依曼瓶颈",执行效率较低。哈佛架构特点:程序指令和数据存放在独立的存储器中,拥有各自独立的数据总线和地址总线。指令和数据可以同时读取,提高了执行效率,但硬件结构较复杂。STM32F10x微处理器(ARMCortex-M3内核)采用的是哈佛架构,具备独立的指令总线和数据总线,使得处理器能够同时进行指令读取和数据操作,提高了运行效率。什么是时钟树?STM32有哪几个时钟源?AHB分频器输出的时钟送给哪几个模块使用?时钟树是指STM32微控制器内部复杂的时钟分配系统,它从时钟源出发,经过一系列的分频器、倍频器和选择开关,将时钟信号分配给各个外设和总线,形成一个树状结构的时钟分配网络。STM32的时钟源主要有4个:HSI(HighSpeedInternal):高速内部时钟,RC振荡器,频率为8MHzHSE(HighSpeedExternal):高速外部时钟,外接晶振,频率通常为4~16MHz(常用8MHz)LSI(LowSpeedInternal):低速内部时钟,RC振荡器,频率约为40kHzLSE(LowSpeedExternal):低速外部时钟,外接32.768kHz晶振AHB分频器输出的时钟主要送给以下模块使用:AHB总线(供CPU、DMA、存储器等使用)APB1总线(低速外设,如USART2/3、I2C、TIM2~7等)APB2总线(高速外设,如GPIO、USART1、ADC、TIM1/8等)Cortex系统定时器(SysTick)STM32的SYSCLK系统时钟是什么?SYSCLK是STM32的系统时钟,是供给CPU内核及大部分外设工作的主时钟。SYSCLK的时钟源可以通过时钟配置寄存器(RCC_CFGR)的SW位选择,可选的时钟源有:HSI时钟HSE时钟PLLCLK(锁相环输出时钟)通常情况下,SYSCLK由PLL倍频后的时钟提供,最高频率为72MHz。SYSCLK经过AHB分频器后得到HCLK(AHB总线时钟),再经分频得到APB1和APB2总线时钟。在STM32F10x最小系统中,8MHz晶振旁边连接的电容是多大?有什么作用?在STM32F10x最小系统中,8MHz晶振旁边连接的电容通常为22pF(两个相同的电容,通常取值范围为12pF~25pF)。作用:这些电容称为负载电容(匹配电容),用于匹配晶振的负载电容要求。使晶振电路能够可靠起振并稳定工作。微调晶振的振荡频率,确保频率精度。消除高频干扰,提高振荡电路的稳定性。简述STM32的复位方式。手动复位按键处的电容有什么作用?STM32的复位方式主要有:上电复位(POR):芯片上电时,电源电压从0上升到工作电压的过程中,芯片自动复位。掉电复位(PDR):电源电压下降到阈值以下时,芯片自动复位。外部手动复位:通过NRST引脚上的手动复位按键电路实现复位。独立看门狗复位:看门狗定时器溢出时触发系统复位。窗口看门狗复位:窗口看门狗超时触发复位。软件复位:通过NVIC的应用程序中断和复位控制寄存器(AIRCR)实现软件系统复位。手动复位按键处电容的作用:手动复位按键处并联的电容起滤波和防抖作用。按下按键时,电容可以消除按键机械触点弹跳造成的抖动信号,确保产生干净、可靠的复位脉冲;同时在上电瞬间提供延时,确保电源稳定后才解除复位状态,实现可靠的上电复位功能。简述STM32F10x的内存分布情况。STM32F10x的内存分布(存储器映射)如下:0x00000000~0x07FFFFFF:程序存储器(Flash,512KB),可通过BOOT0/BOOT1引脚配置映射到不同存储区0x08000000~0x0807FFFF:Flash存储器起始地址区域(用户程序存储区)0x1FFFF000~0x1FFFF7FF:系统存储区(出厂Bootloader)0x1FFFF800~0x1FFFF80F:选项字节0x20000000~0x2000FFFF:SRAM静态内存区(最多64KB,取决于具体型号)0x40000000~0x400077FF:APB1外设区0x40010000~0x40013FFF:APB2外设区0x40018000~0x400233FF:AHB外设区0xE0000000~0xE00FFFFF:Cortex-M3内核内部区域(系统控制、NVIC、SysTick等)什么是微控制器最小系统?简述STM32F10x最小系统的组成及各部分功能。微控制器最小系统是指使微控制器能够正常工作所需的最基本的外围电路组合,仅包含维持微控制器运行所必需的电路,不包括具体应用所需的扩展电路。STM32F10x最小系统的组成及各部分功能:电源电路:为芯片提供稳定的工作电压(通常3.3V),包括去耦电容和电源滤波电路。时钟电路:高速外部晶振电路(HSE):8MHz晶振+负载电容,提供主时钟源。低速外部晶振电路(LSE):32.768kHz晶振,供RTC使用。复位电路:由复位按键和RC电路组成,连接NRST引脚,实现手动复位和上电复位。BOOT启动配置电路:通过BOOT0和BOOT1引脚的电平配置,选择芯片的启动模式(从Flash启动、从系统存储器启动、从SRAM启动)。下载调试接口:SWD(串行线调试)或JTAG接口,用于程序下载和在线调试。STM32微控制器芯片:系统的核心。2章STM32开发环境搭建 简述STM32微控制器3种开发模式的区别和联系。STM32微控制器的3种开发模式为寄存器开发模式、标准外设库(SPL)开发模式和HAL库开发模式。比较项寄存器开发标准外设库(SPL)HAL库开发方式直接操作寄存器调用封装的C函数API图形化配置+调用抽象API开发效率低,开发周期长中等,需手动编写驱动高,STM32CubeMX自动生成代码效率最高较高较低(封装层次多)可移植性差较差(针对特定系列)好(跨系列兼容)学习难度高,需深入理解硬件中等较低,但理解底层较难联系:三种模式本质上都是通过控制STM32的硬件寄存器来实现功能。寄存器开发是最底层的方式;SPL库是对寄存器操作的封装;HAL库则是在更高层次上对SPL的进一步抽象,配合STM32CubeMX工具实现图形化配置和代码自动生成。三者从底层到高层逐步抽象,开发效率逐步提高,但对底层的控制力逐步降低。什么是CMSIS?ARM公司为什么要制定CMSIS标准?CMSIS(CortexMicrocontrollerSoftwareInterfaceStandard,Cortex微控制器软件接口标准)是ARM公司制定的一套独立于供应商的Cortex-M微控制器硬件抽象层标准。ARM公司制定CMSIS标准的原因:在CMSIS之前,不同芯片厂商(如意法半导体、NXP、德州仪器等)各自提供的软件开发库存在差异,导致软件在不同厂商芯片间移植困难。CMSIS为Cortex-M系列处理器定义了统一的软件接口标准,包括内核访问层、设备外设访问层和系统视图层。通过统一标准,简化了软件在不同Cortex-M芯片之间的移植工作。降低了开发者的学习成本,只需学习一套标准即可开发不同厂商的Cortex-M芯片。促进了第三方工具链、中间件和软件开发工具的兼容和发展。简述嵌入式软件开发与计算机桌面应用程序开发方式的区别。嵌入式系统软件开发一般分为哪几个阶段?区别:比较项嵌入式软件开发桌面应用程序开发开发环境交叉编译环境(主机+目标板)本地编译环境硬件依赖与具体硬件平台紧密相关与硬件无关,由OS管理资源限制内存、存储资源有限资源丰富操作系统可能有RTOS或无OS(裸机)有完善的OS(Windows/Linux等)调试方式需要仿真器/调试器+目标硬件本地调试实时性通常有实时性要求一般无严格的实时性要求嵌入式系统软件开发一般分为以下阶段:需求分析:明确系统功能、性能和约束条件。系统设计:包括硬件选型、软件架构设计、模块划分。开发环境搭建:安装交叉编译工具链、IDE、驱动程序等。代码编写:使用C/C++等语言编写应用程序和外设驱动。编译与链接:通过交叉编译器生成目标平台的可执行文件。下载与调试:通过仿真器(如ST-Link)将程序下载到目标硬件,使用在线调试工具调试。测试与验证:在目标硬件上进行功能测试和性能验证。优化与发布:优化代码和资源占用,最终生成固件发布。什么是启动文件?启动文件有什么作用?启动文件是STM32微控制器上电后最先执行的代码,通常由汇编语言编写(如startup_stm32f103xb.s),在进入main()函数之前执行。启动文件的作用:初始化堆栈指针(SP):设置主堆栈指针(MSP)的初始值。设置程序计数器(PC):将PC指向复位处理函数Reset_Handler。配置中断向量表:定义中断向量表,包含系统异常和各外设中断的入口地址。初始化.data段:将Flash中的已初始化全局变量/静态变量拷贝到SRAM。清零.bss段:将未初始化的全局变量/静态变量区域清零。调用SystemInit()函数:初始化系统时钟。调用main或main()函数:最终跳转到用户程序的main()函数开始执行。提供中断服务程序入口:为所有中断/异常提供默认的处理函数入口。编写中断函数,实现中断函数接口的文件是什么?编写中断函数、实现中断函数接口的文件通常是:stm32f1xx_it.c(HAL库模式下):中断服务函数文件,包含了所有外设的中断服务程序(ISR)的框架代码,由STM32CubeMX自动生成,开发者在此文件中编写具体的中断处理逻辑。启动文件(如startup_stm32f103xb.s):提供了中断向量表和默认的中断处理入口地址。stm32f1xx_hal_xxx.c:HAL库外设驱动文件中定义了中断处理相关的回调函数。在HAL库开发模式下,中断服务函数一般在stm32f1xx_it.c文件中编写,而具体的中断处理逻辑通常通过HAL库提供的回调函数(HAL_GPIO_EXTI_Callback)来实现。简述基于HAL库开发模式的开发步骤。基于HAL库的开发模式主要步骤如下:创建工程:打开STM32CubeMX,选择目标芯片型号。配置芯片参数:配置RCC时钟源(HSE/HSI)和时钟树(SYSCLK、AHB、APB1、APB2频率)。配置SYS调试接口(如SWD)。配置所需外设(如GPIO、USART、TIM、ADC等)及其工作参数。配置中断优先级分组和NVIC。生成代码:设置工程名称、工具链(如MDK-ARM),点击生成代码。编写用户代码/*USERCODEBEGIN*//*USERCODEEND*/注释之间编写用户功能代码。编译工程:在Keil中编译工程,确保无错误。下载程序:通过ST-Link等仿真器将程序下载到目标芯片。调试与测试:利用在线调试功能调试程序,在硬件上验证功能。STM32开发中使用了很多英文缩写,请解释下列英文缩写的含义。序号缩写全称含义(1)RCCResetandClockControl复位和时钟控制(2)RTCReal-TimeClock实时时钟(3)EXTIExternalInterrupt外部中断(4)PWMPulseWidthModulation脉冲宽度调制(5)PLLPhaseLockedLoop锁相环(用于时钟倍频)(6)OSCOscillator振荡器(7)NVICNestedVectoredInterruptController嵌套向量中断控制器(8)ISPIn-SystemProgramming在系统编程(在线烧录)(9)UARTUniversalAsynchronousReceiver/Transmitter通用异步收发传输器(10)SPISerialPeripheralInterface串行外设接口(11)APIApplicationProgrammingInterface应用程序编程接口(12)AFIOAlternateFunctionI/O复用功能输入输出(13)IRQInterruptRequest中断请求(14)APBAdvancedPeripheralBus高级外设总线嵌入式开发中大量使用到了宏定义#define,简述#define与typedef的区别。比较项#definetypedef本质预处理指令,文本替换C语言关键字,定义类型别名处理时机预处理阶段(编译前)编译阶段类型检查无类型检查,仅文本替换有类型检查作用范围从定义处到文件末尾(或#undef)受作用域限制指针含义#definepint*后pa,b;中a是指针,b是inttypedefint*p;后pa,b;中a和b都是指针可读性容易产生歧义语义清晰调试宏在调试时不可见调试时可见示例:#defineUINT8#defineUINT8unsignedchar //宏定义,预处理时文本替换typedefunsignedcharuint8; //类型别名,编译时处理在STM32HAL库中,两者都广泛使用:#define用于定义常量和宏函数,typedef用于定义结构体、枚举和函数指针等类型别名。3章GPIO通用输入/输出 GPIO可以配置成哪几种工作模式?STM32F1系列微控制器的GPIO可以配置为以下8种工作模式:输入模式(4种):浮空输入(GPIO_MODE_INPUT/floating):引脚电平由外部信号决定,内部不上拉也不下拉。上拉输入(GPIO_MODE_INPUT/pull-up):内部接上拉电阻,引脚悬空时为高电平。下拉输入(GPIO_MODE_INPUT/pull-down):内部接下拉电阻,引脚悬空时为低电平。模拟输入(GPIO_MODE_ANALOG):用于ADC采集或DAC输出,数字部分断开。输出模式(4种):开漏输出(GPIO_MODE_OUTPUT_OD):输出低电平时引脚接地,输出高电平时引脚为高阻态。推挽输出(GPIO_MODE_OUTPUT_PP):可主动输出高电平和低电平,驱动能力强。复用开漏输出(GPIO_MODE_AF_OD):开漏输出模式下的复用功能(如I2C)。复用推挽输出(GPIO_MODE_AF_PP):推挽输出模式下的复用功能(如USART、SPI)。简述STM32推挽输出模式和开漏输出模式的区别和应用场合。比较项推挽输出开漏输出高电平输出主动输出高电平(VCC)高阻态(需外部上拉电阻才能输出高电平)低电平输出主动输出低电平(GND)主动输出低电平(GND)驱动能力强,可灌入和拉出电流仅能灌入电流(拉低)电平转换输出电平固定为芯片供电电压通过外部上拉电阻可实现电平转换应用场合:推挽输出:LED驱动、蜂鸣器驱动、继电器驱动等需要直接驱动外设的场合,以及SPI的MOSI/SCK等需要主动输出高低电平的通信接口。开漏输出:I2C总线(SDA/SCL线需开漏+上拉,实现线与功能)、多设备共用总线需要"线与"逻辑的场合、需要电平转换的场合。通过阅读HAL库的GPIO操作函数HAL_GPIO_Init(),HAL_GPIO_WritePin(),HAL_GPIO_ReadPin()源代码,可以看出其实质是分别通过操作什么来实现的?HAL_GPIO_Init():实质是通过操作GPIO的寄存器(CRL、CRH、BSRR、BRR、ODR等)来实现的。该函数根据传入的GPIO初始化结构体参数,配置对应引脚的CRL/CRH寄存器(控制模式、速度),以及通过BSRR/BRR寄存器设置初始电平。HAL_GPIO_WritePin():实质是通过操作GPIO端口位设置/清除寄存器(BSRR)来实现的。写1对应位设置输出高电平,写1对应位清除输出低电平。HAL_GPIO_ReadPin():实质是通过读取GPIO输入数据寄存器(IDR)来实现的。读取IDR寄存器的对应位获取引脚输入电平状态。HAL库中定义了很多布尔类型的常量,请简述下列常量的含义。SET:值为1,表示"置位"状态,通常用于表示引脚输出高电平、标志位置位等。RESET:值为0,表示"复位"状态,通常用于表示引脚输出低电平、标志位清零等。ENABLE:值为1,表示"使能",用于开启某个外设或功能模块。DISABLE:值为0,表示"禁用",用于关闭某个外设或功能模块。这些常量本质上是FunctionalState和GPIO_PinState等枚举类型的值,使用语义化常量代替0和1,提高代码可读性。HAL库是通过什么来实现内存空间的定义和操作的?HAL库主要通过以下方式实现内存空间的定义和操作:结构体映射:通过C语言结构体(struct)将外设寄存器映射到对应的内存地址空间。例如GPIO_TypeDef结构体将GPIO的CRL、CRH、IDR、ODR、BSRR、BRR等寄存器按顺序映射到连续的地址空间。宏定义基地址:通过宏定义外设的基地址(如#defineGPIOA((GPIO_TypeDef*)GPIOA_BASE)),将结构体指针指向外设的物理地址。指针操作:通过结构体指针直接读写寄存器的值,如GPIOA->BSRR=...。volatile关键字:寄存器变量使用volatile修饰,防止编译器优化,确保每次都从实际地址读写。这种"结构体+指针"的方式实现了对硬件寄存器的直接操作,同时保持了良好的代码可读性和可维护性。改写示例1的程序,通过操作ODR寄存器实现LED1的闪烁。/*/*在main函数的while循环中,通过ODR寄存器异或操作实现LED1闪烁*//*USERCODEBEGINWHILE*/while(1){/*通过对ODR寄存器的对应位进行异或操作,实现电平翻转*/GPIOA->ODR^=GPIO_PIN_1; /*PA1引脚电平翻转(假设LED1连接PA1)*/HAL_Delay(500); /*延时500ms*//*USERCODEENDWHILE*/}说明:ODR(输出数据寄存器)的每一位对应一个GPIO引脚的输出电平。通过对目标位进行异或(^=)操作,可以实现电平翻转(0变1,1变0),从而实现LED闪烁。这种方法比使用HAL_GPIO_TogglePin()更直接,效率更高。编写程序,实现以下功能:LED1以1s为间隔一直闪烁,同时LED2以0.2s为间隔闪烁30次。/*/*假设LED1连接PA1,LED2连接PA2*//*USERCODEBEGINWHILE*/uint32_tled1_time=0; /*LED1上次切换时间*/uint32_tled2_time=0; /*LED2上次切换时间*/uint8_tled2_count=0; /*LED2闪烁次数计数*/uint8_tled2_state=1; /*LED2是否还在闪烁阶段*/while(1){uint32_tnowHAL_GetTick(); /*获取当前系统滴答时间(ms)*//*LED1以1s间隔一直闪烁*/if(now-led1_time>=1000){led1_time=now;HAL_GPIO_TogglePin(GPIOAGPIO_PIN_1); /*LED1翻转*/}/*LED2以0.2s间隔闪烁30次(30次翻转=15次完整闪烁周期)*/if(led2_state&&(now-led2_time>=200)){led2_time=now;HAL_GPIO_TogglePin(GPIOAGPIO_PIN_2); /*LED2翻转*/led2_count++;if(led2_count30) /*翻转30次后停止*/{led2_state0; /*停止闪烁*/HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);/*LED2熄灭*/}}}/*USERCODEENDWHILE*/说明:使用HAL_GetTick()获取系统运行时间(毫秒),通过非阻塞方式判断时间间隔,实现两个LED独立闪烁而不互相影响。LED1持续闪烁,LED2闪烁30次后停止。思考如何识别按键的长按事件。改写示例3的Key_Scan()函数,实现识别按键K1和K2的长按事件,并增加如下功能:当长按K1时,LED1和LED2同时点亮;当长按K2时,LED1和LED2同时熄灭。/*/*定义长按时间阈值(单位ms)*/#defineLONG_PRESS_TIME1000/**@brief 按键扫描函数,支持长按检测@note 假设K1连接PB0,K2连接PB1,低电平表示按下*/voidKey_Scan(void){staticuint32_tk1_press_time=0;staticuint32_tk2_press_time=0;staticuint8_tk1_pressed=0;staticuint8_tk2_pressed=0;/*检测K1按下*/if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET){if(!k1_pressed){}else{}}else{
k1_pressed=1;k1_press_timeHAL_GetTick(); /*记录按下时刻*//*判断是否达到长按时间*/if((HAL_GetTick()-k1_press_time)>=LONG_PRESS_TIME){/*长按K1:LED1和LED2同时点亮*/HAL_GPIO_WritePin(GPIOAGPIO_PIN_1GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOAGPIO_PIN_2GPIO_PIN_SET);k1_pressed0; /*处理完毕,等待释放后才能再次触发*//*延时去抖,等待按键释放*/while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET);}k1_pressed0; /*K1释放*/}/*检测K2按下*/if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET){if(!k2_pressed){}else{
k2_pressed=1;k2_press_time=HAL_GetTick();if((HAL_GetTick()-k2_press_time)>=LONG_PRESS_TIME){/*长按K2:LED1和LED2同时熄灭*/HAL_GPIO_WritePin(GPIOAGPIO_PIN_1GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOAGPIO_PIN_2GPIO_PIN_RESET);k2_pressed=0;while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET);}}}}else{k2_pressed=0;}}长按识别原理:在按键按下时记录起始时间,持续检测按键是否保持按下状态,当按下持续时间超过设定的长按阈值(如1000ms)时,判定为长按事件。移植开源的按键驱动框架(如MultiButton),完成上题的功能。/*基于MultiButton框架的按键驱动示例*/#include"multi_button.h"/*定义按键结构体*/staticstructButtonbtn_k1;staticstructButtonbtn_k2;/*读取按键电平的回调函数*/staticuint8_tread_k1_pin(void){returnHAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);}staticuint8_tread_k2_pin(void){returnHAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);}/*按键事件回调函数*/staticvoidbtn_k1_callback(void*btn){structButton*b=(structButton*)btn;if(b->event==LONG_PRESS_START){/*长按K1:LED1和LED2同时点亮*/HAL_GPIO_WritePin(GPIOAGPIO_PIN_1GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOAGPIO_PIN_2GPIO_PIN_SET);}}staticvoidbtn_k2_callback(void*btn){structButton*b=(structButton*)btn;if(b->event==LONG_PRESS_START){/*长按K2:LED1和LED2同时熄灭*/HAL_GPIO_WritePin(GPIOAGPIO_PIN_1GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOAGPIO_PIN_2GPIO_PIN_RESET);}}/*初始化按键*/voidButton_Init_User(void){button_init(&btn_k1,read_k1_pin00); /*低电平有效*/button_initbutton_init(&btn_k2,read_k2_pin,0,1);button_attach(&btn_k1,LONG_PRESS_START,btn_k1_callback);button_attach(&btn_k2,LONG_PRESS_START,btn_k2_callback);button_start(&btn_k1);button_start(&btn_k2);}/*在SysTick中断中调用,提供按键扫描的时基*/voidHAL_SYSTICK_Callback(void){button_ticks();}是一个轻量级的按键驱动框架,支持短按、长按、双击等事件检测。移植时需要提供读取按键电平的函数,并注册事件回调函数。使用AI工具(如豆包、腾讯元宝等),编写一个基于HAL库的通用的按键驱动程序,要求支持多个按钮,可以设置按键按下和松开时的默认电平,可以识别短按、长按、双击等按键事件。/*/*通用按键驱动程序key_driver.h*/#ifndefKEY_DRIVER_H#defineKEY_DRIVER_H#include"stm32f1xx_hal.h"#include<stdint.h>#defineMAX_KEYS 8#defineDEBOUNCE_TIME 20#defineLONG_PRESS_TIME1000#defineDOUBLE_CLICK_GAP300/*最大按键数*//*消抖时间(ms)*//*长按阈值(ms)*//*双击间隔(ms)*//*按键事件类型*/typedefenum{KEY_EVENT_NONE=0,KEY_EVENT_SHORT_PRESS, /*短按*/KEY_EVENT_LONG_PRESS,/**/KEY_EVENT_DOUBLE_CLICK,/**/KEY_EVENT_RELEASE/**/}key_event_t;/*按键状态*/typedefenum{KEY_STATE_IDLE=0,KEY_STATE_PRESSED,KEY_STATE_LONG_PRESSED,KEY_STATE_WAIT_DOUBLE}key_state_t;/*按键结构体*/typedefstruct{GPIO_TypeDef*port;uint16_tpin;uint8_tactive_level;key_state_tstate;uint32_tpress_time;uint32_trelease_time;/*GPIO端口*//*GPIO引脚*//*按下时的有效电平(0或1)*//*当前状态*//*按下时刻*//*释放时刻*/void(*callback)(uint8_tkey_idkey_event_tevent); /*事件回调*/}}key_t;voidKeyDriver_Init(void);voidKeyDriver_Register(uint8_tid,GPIO_TypeDef*port,uint16_tpin,uint8_tactive_level,void(*cb)(uint8_t,key_event_t));voidKeyDriver_Scan(void);#endif/*KEY_DRIVER_H*//*通用按键驱动程序-key_driver.c*/#include"key_driver.h"statickey_tkeys[MAX_KEYS];/*读取按键电平,返回1=按下,0=松开*/staticuint8_tKey_ReadLevel(key_t*key){uint8_tpin_val=HAL_GPIO_ReadPin(key->port,key->pin);if(key->active_level==1)returnpin_val;else}
return!pin_val;voidKeyDriver_Init(void){for(inti=0;i<MAX_KEYS;i++){keys[i].state=KEY_STATE_IDLE;keys[i].callback=0;}}voidKeyDriver_Register(uint8_tid,GPIO_TypeDef*port,uint16_tpin,uint8_tactive_level,void(*cb)(uint8_t,key_event_t)){if(id>=MAX_KEYS)return;keys[id].port=port;keys[id].pin=pin;keys[id].active_level=active_level;keys[id].state=KEY_STATE_IDLE;keys[id].callback=cb;}voidKeyDriver_Scan(void){uint32_tnow=HAL_GetTick();for(inti=0;i<MAX_KEYS;i++){if(keys[i].callback==0)continue;uint8_tpressed=Key_ReadLevel(&keys[i]);switch(keys[i].state){caseKEY_STATE_IDLE:if(pressed){keys[i].press_time=now;keys[i].state=KEY_STATE_PRESSED;}break;caseKEY_STATE_PRESSED:if(pressed){/*检测长按*/if((now-keys[i].press_time)>=LONG_PRESS_TIME){keys[i].state=KEY_STATE_LONG_PRESSED;keys[i].callback(i,KEY_EVENT_LONG_PRESS);}}else{/*消抖后释放*/if((now-keys[i].press_time)>=DEBOUNCE_TIME){keys[i].release_time=now;keys[i].state=KEY_STATE_WAIT_DOUBLE;}else{keys[i].state=KEY_STATE_IDLE;}}break;caseKEY_STATE_LONG_PRESSED:if(!pressed){keys[i].state=KEY_STATE_IDLE;keys[i].callback(i,KEY_EVENT_RELEASE);}break;caseKEY_STATE_WAIT_DOUBLE:if(pressed){/*检测双击*/if((now-keys[i].release_time)<DOUBLE_CLICK_GAP){keys[i].callback(i,KEY_EVENT_DOUBLE_CLICK);keys[i].state=KEY_STATE_IDLE;/*等待释放*/while(Key_ReadLevel(&keys[i]));}}else{/*超时则判定为短按*/if((now-keys[i].release_time)>=DOUBLE_CLICK_GAP){keys[i].callback(i,KEY_EVENT_SHORT_PRESS);keys[i].state=KEY_STATE_IDLE;}}break;}}}/*/*使用示例-main.c*//*事件回调函数*/voidKeyCallback(uint8_tkey_id,key_event_tevent){switchswitch(event){caseKEY_EVENT_SHORT_PRESS:if(key_id==0){/*K1短按*/HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);/*切换LED1*/}break;caseKEY_EVENT_LONG_PRESS:if(key_id==0){/*K1长按*/HAL_GPIO_WritePin(GPIOA,GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_SET);}break;caseKEY_EVENT_DOUBLE_CLICK:if(key_id==0){/*K1双击*/HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);}break;default:break;}}intmain(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();KeyDriver_Init();/*注册K1:PB0,低电平有效*/KeyDriver_Register(0,GPIOB,GPIO_PIN_0,0,KeyCallback);/*注册K2:PB1,低电平有效*/KeyDriver_Register(1,GPIOB,GPIO_PIN_1,0,KeyCallback);while(1){KeyDriver_Scan();HAL_Delay(5);/*每5ms扫描一次*/}}说明:该通用按键驱动采用状态机设计,支持多按键注册、自定义有效电平、短按/长按/双击事件识别,通过回调函数处理事件,具有良好的通用性和可移植性。4章外部中断EXTI 什么是中断?什么是中断优先级?什么是中断嵌套?中断:是指在程序执行期间,当特定事件发生时,CPU暂停当前程序的执行,转而执行一个专门为此事件设计的中断服务程序(ISR),完成ISR后,CPU返回到原先的程序执行点继续执行。中断优先级:当存在多个中断源同时请求中断时,CPU根据各个中断源的紧急程度来决定优先处理哪一个,这种紧急程度通过中断优先级来体现。STM32中中断优先级分为抢占优先级和响应优先级(子优先级)。中断嵌套:当一个中断正在执行时,如果来了一个更高抢占优先级的中断,CPU会暂停当前中断服务程序的执行,转而去执行更高优先级的中断服务程序,等执行完毕后再返回继续执行被暂停的中断服务程序,这种机制称为中断嵌套。只有抢占优先级更高的中断才能打断当前正在执行的中断。中断处理入口函数可以从哪个文件中找到?中断处理入口函数(中断服务函数/ISR)可以在以下文件中找到:启动文件(如startup_stm32f103xb.s):定义了中断向量表,包含所有中断和异常的入口地址,以及默认的中断处理函数(通常是一个无限循环B.)。stm32f1xx_it.c:在HAL库开发模式下,STM32CubeMX生成的中断服务函数文件,包含了各个外EXTI0_IRQHandler()USART1_IRQHandler()等。中断和异常有什么不同?ARMCortex-M3内核的NVIC支持多少种异常和中断?中断和异常的区别:NMI(不可屏蔽中断)、硬件错误(HardFault)、系统时钟节拍(SysTick)等,是处理器内核层面的。中断:由外部设备或外设产生的事件触发的,如GPIO外部中断、USART中断、定时器中断等,是外设层面的。中断是异常的一种子集。ARMCortex-M3内核的NVIC支持:共支持256种异常和中断(中断号0~255)其中包括16个系统异常(中断号0~15,如复位、NMI、HardFault等)以及240个外部中断(中断号16~255)STM32F10x系列具体使用了其中的一部分(约60~68个中断,具体取决于芯片型号)已知3个中断...请写出这3个中断的中断优先级顺序。已知中断优先级组为2(即2位抢占优先级,2位响应优先级):中断抢占优先级响应优先级中断3(RTC中断)21中断6(外部中断0)30中断7(外部中断1)20优先级排序规则:先比较抢占优先级(数值越小优先级越高),抢占优先级相同则比较响应优先级(数值越小优先级越高)。优先级顺序(从高到低):中断7(外部中断1):抢占优先级2,响应优先级0最高中断3(RTC中断):抢占优先级2,响应优先级1中断6(外部中断0):抢占优先级3,响应优先级0最低说明:中断7和中断3的抢占优先级相同(都为2),但中断7的响应优先级更高(0<1),所以中断7优先于中断3。中断6的抢占优先级最低(3),排在最后。中断7和中断3之间不能发生中断嵌套(抢占优先级相同),只能排队执行。STM32的外部中断EXTI10~EXTI15共用一个外部中断服务函数voidEXTI15_10_IRQHandler(void),若此时PA10、PA11、PA13、PA14和PA15同时产生中断,则实际开发中应如何区分和处理来自这5个引脚的外部中断?可以在回调函数中区别引脚,比如:voidvoidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin){switchswitch(GPIO_Pin){caseGPIO_PIN_10://PA10中断处理break;caseGPIO_PIN_11://PA11中断处理break;caseGPIO_PIN_13://PA13中断处理break;caseGPIO_PIN_14://PA14中断处理break;caseGPIO_PIN_15://PA15中断处理break;default:break;}}编写程序模拟烟雾检测紧急报警:当按键K1按下时表示发生紧急情况(烟雾超标),产生中断,LED1亮,发出报警信息;当按键K1松开时表示紧急情况已消除,进入中断,LED1灭,取消报警。/*/*假设K1连接PB0,配置为外部中断,上升沿和下降沿都触发*//*LED1连接PA1*//*在STM32CubeMX中配置PB0为GPIO_EXTI,触发模式为Rising/FallingEdge*//*外部中断回调函数*/voidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin){if(GPIO_PinGPIO_PIN_0) /*K1按键(PB0)产生中断*/{if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_SET){/*按键松开(上升沿),紧急情况消除*/HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);/*LED1灭*/}else{/*按键按下(下降沿),烟雾超标紧急情况*/HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);/*LED1亮*/}}}说明:将按键K1连接的GPIO引脚配置为外部中断模式,设置为上升沿和下降沿都触发。在回调函数中通过读取引脚当前电平判断是按下还是松开,分别执行报警和取消报警的逻辑。5章串口通信 什么是串行通信和并行通信?比较串行通信和并行通信的优缺点。串行通信:每次只传输一个比特的通信方式,发送方依次将数据的每个比特传输到接收方。并行通信:每次传输多个比特的通信方式,发送方将要传输的多个数据比特同时传输到接收方(通常8bit、16bit或32bit)。比较项串行通信并行通信传输速度较低(逐位传输)较高(同时传输多位)线缆数量少(1~4根线)多(8/16/32根线)成本低高抗干扰强,适合远距离弱,适合近距离同步性需要同步机制天然同步适用场景远距离、低成本通信短距离、高速通信在数字通信中,比特率和波特率有什么区别和联系?比特率:每秒传输的二进制位数(bitspersecond,bps),表示信息传输速率。波特率:每秒传输的码元(符号)个数(Baud),表示信号变化的速率。区别:比特率关注的是信息量,波特率关注的是信号波形的变化。当一个码元携带多个比特信息时(如使用多进制调制),比特率大于波特率。联系:比特率=波特率×每个码元携带的比特数。在二进制传输中(如UART通信),每个码元携带1个比特,此时比特率=波特率。例如,波特率9600对应比特率也是9600bps。简述RS232的接口组成及其电平标准。RS232接口组成:RS232接口通常使用DB9或DB25连接器(常用DB9)。主要信号线包括:TXD(发送数据)、RXD(接收数据)、GND(信号地)、RTS(请求发送)、CTS(清除发送)、DTR(数据终端就绪)、DSR(数据设备就绪)等。最简单的通信只需3根线:TXD、RXD、GND。RS232电平标准:逻辑"1"(MARK):-3V~-15V(通常为-12V左右)逻辑"0"(SPACE):+3V~+15V(通常为+12V左右)采用负逻辑:负电压表示逻辑1,正电压表示逻辑0传输电平范围:-15V~+15V噪声容限:约2V(-3V~+3V之间为不确定区)注意:STM32的UART输出为TTL电平(0~3.3V),需要通过MAX232等电平转换芯片才能与RS232接口连接。UART数据帧格式由哪几部分组成?UART数据帧由以下几部分组成:起始位(StartBit):1位,固定为逻辑0(低电平),标志数据帧的开始。数据位(DataBits):5~9位,通常为8位,低位在前,高位在后(LSBfirst)。校验位(ParityBit):0或1位,可选无校验(None)、奇校验(Odd)、偶校验(Even)。停止位(StopBit):1、1.5或2位,固定为逻辑1(高电平),标志数据帧的结束。空闲状态:无数据传输时,线路保持高电平(逻辑1)。[空闲(1)]起始(0)][D0[空闲(1)]起始(0)][D0D1D2D3D4D5D6D7]停止(1)]分别说明USART在发送期间和接收期间有几种中断事件?发送期间的中断事件:发送数据寄存器空中断(TXE):当TDR(发送数据寄存器)中的数据被移入移位寄存器,TDR为空时触发,提示可以写入下一个数据。发送完成中断(TC):当一帧数据的所有位(包括停止位)都已从移位寄存器发送出去,且TDR也为空时触发,表示发送完全完成。CTS中断:CTS标志变化时触发(用于硬件流控)。接收期间的中断事件:接收数据寄存器非空中断(RXNE):当移位寄存器接收完一个字节并传输到RDR(接收数据寄存器)时触发,提示可以读取接收到的数据。空闲线中断(IDLE):检测到接收线路空闲时触发,可用于判断数据包结束。校验错误中断(PE):接收数据校验错误时触发。噪声错误中断(NE):检测到噪声时触发。帧错误中断(FE):检测到帧错误(如停止位不正确)时触发。过载错误中断(ORE):接收数据被覆盖(RDR中的数据未及时读取)时触发。编程题:参照本章的示例程序,利用STM32F103系列微控制器的USART2分别以查询方式和中断方式实现异步串行通信的收发功能。/*/*查询方式实现USART2收发*//*假设USART2已通过STM32CubeMX配置:波特率115200,8位数据,无校验,1停止位*//*查询方式*/voidUSART2_Polling_Test(void){uint8_ttx_buf[]="HellofromUSART2(Polling)!\r\n";uint8_trx_buf[1];/*发送数据*/HAL_UART_Transmit(&huart2,tx_buf,sizeof(tx_buf)-1,HAL_MAX_DELAY);/*接收数据并回显*/while(1){if(HAL_UART_Receive(&huart2,rx_buf,1,HAL_MAX_DELAY)==HAL_OK){HAL_UART_Transmit(&huart2,rx_buf,1,HAL_MAX_DELAY);/*回显*/}}}/*中断方式实现USART2收发*/uint8_trx_data;uint8_tuint8_ttx_buf[]="HellofromUSART2(Interrupt)!\r\n";voidUSART2_Interrupt_Test(void){/*发送数据*/HAL_UART_Transmit_IT(&huart2,tx_buf,sizeof(tx_buf)-1);/*开启接收中断*/HAL_UART_Receive_IT(&huart2,&rx_data,1);}/*发送完成回调函数*/voidHAL_UART_TxCpltCallback(UART_HandleTypeDef*huart){if(huart->Instance==USART2){/*发送完成后的处理*/}}/*接收完成回调函数*/voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart){if(huart->Instance==USART2){/*将接收到的数据回显发送*/HAL_UART_Transmit_IT(&huart2,&rx_data,1);/*再次开启接收中断*/HAL_UART_Receive_IT(&huart2,&rx_data,1);}}说明:查询方式使用HAL_UART_Transmit()和HAL_UART_Receive()阻塞式函数,程序会等待发送/接收完成;中断方式使用HAL_UART_Transmit_IT()和HAL_UART_Receive_IT()非阻塞函数,在回调函数中处理数据。编程题:STM32单片机是没有显示器和键盘的,在学习STM32时,常常需要用串口来打印调试信息,请编写程序实现重定向printf()函数和scanf()函数,将标准输入和标准输出重定向到串口外设中。/*/*在工程中添加以下代码*//*重定向fputc和fgetc(适用于KeilMDK)*/#include<stdio.h>externUART_HandleTypeDefhuart1; /*假设使用USART1*//*重定向fputc,使printf输出到串口*/intfputc(intch,FILE*f){HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,HAL_MAX_DELAY);returnch;}/*重定向fgetc,使scanf从串口输入*/intfgetc(FILE*f){uint8_tch=0;HAL_UART_ReceiveHAL_UART_Receive(&huart1,&ch,1,HAL_MAX_DELAY);returnch;}/*/*在Keil中还需要以下设置:勾选UseMicroLIB(Project->Options->Target->CodeGeneration)*//*使用示例*/voidmain(void){/*...HAL初始化...*/printf("STM32SerialPrintTest\r\n");printf("Enteranumber:");intnum=0;scanf("%d",&num);printf("Youentered:%d\r\n",num);while(1);}说明:重定向原理是C标准库的printf最终调用fputc输出字符,scanf最终调用fgetc读取字符。通过重写这两个函数,将字符的输入输出指向UART外设,即可实现printf和scanf通过串口进行数据交互。在Keil中需要勾选UseMicroLIB选项来减少库的体积。6章DMA 什么是DMA?简述DMA的工作原理。DMA(DirectMemoryAccess,直接存储器存取)是一种数据传输技术,也是一种微控制器的片上外设。DMA传输方式无需CPU干预,通过硬件直接实现外设与存储器之间或存储器与存储器之间的数据传输。工作原理:CPU首先配置DMA控制器,设置源地址、目标地址、传输数据量、传输方向、数据宽度等参数。外设向DMA控制器发出DMA请求。DMA控制器获得总线控制权后,直接在源地址和目标地址之间传输数据,不需要CPU参与。每传输一个数据,DMA的传输计数器递减。当传输计数器减到0时,传输完成,DMA控制器向CPU发出中断通知传输结束。CPU在整个传输过程中可以执行其他任务,只在传输开始前配置和传输结束后处理时参与,大大提高了CPU的利用率。STM32F1系列微控制器有几个DMA?用DMA传输的外设主要有哪些?STM32F1系列微控制器最多有2个DMA控制器:DMA1:有7个通道,所有STM32F103系列芯片都有。DMA2:有5个通道,仅存在于大容量STM32F103系列芯片和互联型STM32F105/107系列芯片中。(STM32F103C8T6属于中等容量,只有DMA1)用DMA传输的外设主要包括:定时器(TIM1~TIM4等,用于输入捕获、输出比较等)ADC1(模数转换结果传输)SPI1/SPI2USART1/USART2/USART3I2C1/I2C2每个DMA通道可以管理一个或多个外设的DMA请求,但同一时刻同一通道只能有一个请求有效。在有多个DMA请求同时发生的情况下,如何确定DMA传输的优先顺序?当多个DMA请求同时发生时,通过仲裁器按照优先级来确定DMA传输的顺序。优先级分为4个等级:最高优先级(VeryHigh)高优先级(High)中等优先级(Medium)低优先级(Low)优先级判定规则:首先按软件配置的优先级等级比较,高优先级的通道先执行传输。如果优先级相同,则按照硬件通道号确定优先级,通道号小的优先级更高(如通道1优先于通道2)。在DMA1和DMA2同时存在的系统中,DMA1的优先级高于DMA2。优先级在DMA通道初始化时通过DMA初始化结构体的Priority成员配置。DMA工作模式有哪些?STM32的DMA有以下几种工作模式:外设到存储器:数据从外设数据寄存器传输到内存(如ADC采集数据存入数组)。存储器到外设:数据从内存传输到外设数据寄存器(如将数组数据通过USART发送)。存储器到存储器:数据从一块内存区域传输到另一块内存区域(仅DMA2支持此模式)。按传输方式分:正常模式:传输完设定的数据量后停止DMA传输。循环模式:传输完设定的数据量后,自动重新开始下一轮传输,持续不断地传输数据。使用DMA传输时,需要配置的参数有哪些?使用DMA传输时需要配置的主要参数包括:DMA控制器和通道:选择DMA1或DMA2,以及具体的通道号。传输方向:外设到存储器、存储器到外设、存储器到存储器。外设地址:外设数据寄存器的地址(源地址或目标地址)。存储器地址:内存缓冲区的地址(源地址或目标地址)。数据宽度:外设和存储器的数据宽度(字节8位、半字16位、字32位)。传输数据量:要传输的数据个数(最大65536)。优先级:VeryHigh/High/Medium/Low。工作模式:正常模式或循环模式。地址递增方式:外设地址是否递增(PeripheralInc)、存储器地址是否递增(MemoryInc)。DMA中断:传输完成中断、半传输完成中断、传输错误中断等。DMA通道一次传输的最大数据量是多少?DMA通道一次传输的最大数据量为65535(即16位计数器的最大值)。DMA的数据传输量寄存器(NDTR)是16位的,可存储的值为0~65535,但实际传输数据量为NDTR寄存器写入的值(写入0表示传输65536个数据)。因此,一次DMA传输最多可传输65535个数据单位。7章I2C通信 简述I2C总线的硬件构成。I2C总线的硬件构成如下:两条信号线:SDA(SerialDataLine):双向数据线,用于传输数据。SCL(SerialClockLine):时钟线,由主设备控制,用于同步数据传输。上拉电阻:SDA和SCL线都需要外接上拉电阻(通常4.7kΩ~10kΩ),因为I2C设备引脚为开漏输出,需要上拉电阻在空闲时保持高电平。设备连接:总线上可连接多个设备,包括一个主设备和多个从设备。主设备控制SCL时钟线。设备地址:每个从设备有一个唯一的7位或10位地址,主设备通过地址选择通信对象。总线仲裁机制:当多个主设备同时访问总线时,通过仲裁机制决定哪个设备控制总线。STM32与I2C接口器件如何连接?画出连接示意图。连接说明:STM32的SDA引脚连接到从设备的SDA引脚。STM32的SCL引脚连接到从设备的SCL引脚。SDA和SCL各接一个4.7kΩ~10kΩ的上拉电阻到VCC(3.3V)。STM32和从设备共地(GND相连)。如果总线上有多个从设备(如OLED、温度传感器等),它们的SDA和SCL分别并联到总线上,各自有独立的设备地址。STM32的I2C外设支持不同的通信速度,标准速度可达多少?快速模式可达多少?标准模式:最高速度可达100kbps(100kHz)快速模式:最高速度可达400kbps(400kHz)部分STM32型号还支持快速模式Plus(Fm+),最高可达1MHz。I2C的应答信号(ACK)和非应答信号(NACK)有什么区别?ACK(应答信号):接收方在接收到8位数据后的第9个时钟周期内,将SDA线拉低(低电平),表示已成功接收到数据,可以继续接收下一个字节。NACK(非应答信号):接收方在第9个时钟周期内保持SDA为高电平,表示未成功接收数据或不想继续接收数据。区别:项目ACKNACKSDA电平低电平高电平含义数据接收成功,继续接收数据接收失败或结束接收应用场景:主设备读取从设备数据时,每收到一个字节后发送ACK表示继续读取。当主设备读取最后一个字节时,发送NACK通知从设备读取结束,随后主设备产生停止条件。从设备地址不匹配时,从设备发送NACK。STM32的I2C外设由哪几个部分组成?各有什么功能?STM32的I2C外设主要由以下几个部分组成:时钟控制单元:产生I2C通信所需的SCL时钟信号,控制时钟频率(标准模式100kHz、快速模式400kHz)。数据控制单元:管理SDA线上的数据收发,包括数据移位寄存器、数据寄存器等,负责数据的串并转换。地址寄存器/比较器:存储自身的从设备地址,并与接收到的地址进行比较,判断是否被寻址。控制寄存器:配置I2C的工作模式、使能各种功能(如ACK控制、中断使能等)。状态寄存器:反映I2C的当前状态(如起始条件已发送、地址已发送、数据已接收等),供软件查询。DMA接口:支持DMA方式进行数据传输,减轻CPU负担。STM32的I2C外设支持哪些中断事件?分别在什么情况下触发?STM32的I2C外设支持的主要中断事件包括:起始条件已发送(SB):主模式下,起始条件已发送,触发中断。地址已发送(ADDR):地址字节已发送(主模式)或地址匹配(从模式),触发中断。数据字节传输完成(BTF):一个数据字节传输完成(发送或接收),触发中断。接收缓冲区非空(RXNE):接收到一个数据字节且数据寄存器可读,触发中断。发送缓冲区空(TXE):数据寄存器为空,可写入下一个发送数据,触发中断。停止条件检测(STOPF):从模式下检测到停止条件,触发中断。总线错误(BERR):检测到总线错误,触发中断。仲裁丢失(ARLO):主模式下仲裁丢失,触发中断。应答失败(AF):收到NACK信号,触发中断。过载/欠载(OVR):数据溢出或欠载错误,触发中断。PEC错误(PECERR):校验错误,触发中断。在HAL库中,这些中断事件通常通过事件回调函数(HAL_I2C_MasterTxCpltCallback、HAL_I2C_MasterRxCpltCallback等)来处理。8章SPI通信 画出单主机多从机的SPI通信电路。连接说明:SCK、MOSI、MISO三条线被所有从设备共享(并联)。每个从设备有一条独立的SS/CS(片选)线连接到主设备的不同GPIO引脚。主设备通过与某个从设备的SS/CS线拉低来选择该从设备进行通信。同一时刻只能有一个从设备的SS/CS为低电平(被选中)。SPI通信中的时钟相位和极性有什么作用?SPI通信中通过时钟极性(CPOL)和时钟相位(CPHA)来定义4种不同的时钟模式,确保主从设备使用一致的时序进行通信:CPOL(ClockPolarity,时钟极性):CPOL=0:空闲时SCK为低电平,时钟脉冲为高电平有效。CPOL=1:空闲时SCK为高电平,时钟脉冲为低电平有效。CPHA(ClockPhase,时钟相位):CPHA=0:在时钟的第一个跳变沿(前沿)采样数据,第二个跳变沿(后沿)输出数据。CPHA=1:在时钟的第二个跳变沿(后沿)采样数据,第一个跳变沿(前沿)输出数据。4种SPI模式:模式CPOLCPHA空闲电平采样沿000低上升沿采样101低下降沿采样210高下降沿采样311高上升沿采样作用:不同的SPI从设备可能要求不同的时钟模式,主设备必须根据从设备的数据手册设置正确的CPOL和CPHA,才能正确地进行数据收发。STM32的SPI外设由哪几个部分组成?各有什么功能?STM32的SPI外设主要由以下部分组成:主控制电路:SCK时钟信号,通过分频系数控制通信速率(最高fpclk/2)。主模式控制:控制SCK的输出、CS信号的管理等。数据移位寄存器:核心部件,负责数据的串并转换。发送时将并行数据转为串行数据从MOSI输出,接收时将MISO上的串行数据转为并行数据。数据寄存器(DR):存储待发送数据和已接收数据,供CPU读写。FIFO缓冲区:部分型号支持发送和接收FIFO,提高数据吞吐量。时钟相位和极性控制:配置CPOL和CPHA,适应不同从设备的时序要求。状态寄存器(SR):反映SPI的当前状态(如发送缓冲区空TXE、接收缓冲区非空RXNE、忙标志BSY等)。CRC计算单元:可选的CRC校验功能,用于数据完整性校验。DMA接口:支持DMA方式进行数据传输。NSS引脚管理:管理片选信号,可配置为硬件管理或软件管理模式。STM32的SPI外设支持几种中断?分别在什么情况下触发?STM32的SPI外设支持以下中断事件:发送缓冲区空中断(TXE):当发送数据寄存器为空,可以写入下一个发送数据时触发。接收缓冲区非空中断(RXNE):当接收数据寄存器中有接收到的数据可读时触发。错误中断:以下错误条件触发:主模式错误(MODF):当主设备的NSS引脚被外部拉低(硬件NSS管理模式下)时触发。溢出错误(OVR):接收数据未被及时读取,新的数据覆盖了旧数据时触发。CRC错误(CRCERR):接收到的CRC校验值与计算值不匹配时触发。在HAL库中,这些中断事件通过HAL_SPI_TxCpltCallback()、HAL_SPI_RxCpltCallback()、HAL_SPI_ErrorCallback()等回调函数来处理。9章基础定时器 STM32定时器的时基单元包括什么?各有什么功能?STM32定时器的时基单元(Time-BaseUnit)包括以下三个
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 超越自我 2026年秋季高二语文部编版第四单元单元归类复习卷(含答案)
- 考前速递 2027年中考广西壮族自治区语文初三湘教版夯实基础卷(含答案)
- 突破自我 2026年秋季高二道德与法治部编版上学期期末测试卷(含答案)
- 命题风向标 2027年湖北省历史九年级中考仿真卷(含答案)
- 2027年河南省英语中考北师大版综合模拟卷(含答案)
- 赢战月考 2026-2027学年第一学期初一语文部编版第一单元单元测试卷(含答案)
- 2027届吉林省道德与法治中考人教版中考仿真卷(含答案)
- 河南事业编综合管理岗 2026 模拟预测试卷 含答案
- 2026 水利岗事业编面试题型分析 含答案含解析
- 2026计算机岗事业编面试高频题 题库含答案含解析
- 2026届高考语文考向核心卷含答案(全国二卷)
- 中石油招聘历年笔试真题(完整版含答案解析)
- CMA与CNAS检测报告深度解读:一单一库新政下的效力边界与实务指南
- 乒乓球馆转让合同范本
- 扬州大学《大学物理A》2025 - 2026学年第一学期期末试卷(A卷)
- 上海护理学副高面审题库及答案解析
- 肿瘤防治课件下载
- 调研县疾控中心工作报告
- 成都新和平科技有限公司25000t-a皮革助剂及20000t-a纺织助剂生产线项目环评报告
- 《脑电图的临床应用》课件
- TCAPC 009-2022零售药店经营乳腺癌治疗药品药学服务规范
评论
0/150
提交评论