ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

STM32寄存器白话手册:从点灯到硬件直控的四层思维地图

STM32寄存器白话手册:从点灯到硬件直控的四层思维地图 1. 这本“白话手册”到底在说什么——给刚摸到STM32开发板的新手一句实在话你拆开一块崭新的STM32F103C8T6最小系统板插上USB线打开Keil或STM32CubeIDE新建工程点下编译——结果满屏红色报错“undefined reference toSystemInit”或者更常见的LED不亮、串口没反应、定时器死活不进中断。你翻遍官方参考手册RM0008看到第127页的RCC_CFGR寄存器描述里写着“Bits 21:16 PLLMUL[4:0]: PLL multiplication factor”旁边跟着一串二进制编码表和条件说明头开始嗡嗡响。这不是技术文档这是密码本。“STM32寄存器白话手册”不是另一本翻译版参考手册也不是把寄存器地址表重新排个版。它是我带过十几届嵌入式实训课、陪上百位初学者从点灯踩到FreeRTOS内存溢出后用掉三支记号笔、写废两本A4草稿纸最终沉淀下来的寄存器操作思维地图。它解决的核心问题非常具体当你面对一个功能比如让PA5输出PWM你不需要先背熟整个GPIOx_BSRR、GPIOx_BRR、GPIOx_ODR、GPIOx_IDR、GPIOx_LCKR……而是直接知道——该动哪几个比特为什么只动这几个动错了会怎样以及怎么一眼看出它动对了没有。这本手册的关键词是“白话”但“白话”不等于“简化”。它把“复位值0x40010800”翻译成“出厂时所有IO口默认高阻输入像关着的水龙头你得先拧开配置为推挽输出再调流量设置高低电平”把“APB2ENR | (1 2)”解释成“相当于在供电总闸APB2上给GPIOA这一路单独合上空气开关否则后面接的灯泡寄存器根本没电按开关写寄存器也没用”。它面向的是已经焊好板子、手边有示波器、能测到PA5引脚电压但看不懂数据手册第3章时序图的人。如果你还在纠结“什么是寄存器”那建议先花15分钟用面包板搭个555振荡电路如果你已经能用HAL库点亮LED但想搞懂HAL底层到底干了什么这本书就是你撕开封装胶布的第一把小刀。我试过最笨也最有效的方法把一块STM32F103C8T6焊在洞洞板上只接晶振、复位、BOOT0接地其他全悬空。然后用万用表红表笔点PA0黑表笔接地手动执行一条指令*(unsigned int*)0x40010800 0x00000001;—— 万用表立刻从0V跳到3.3V。那一刻寄存器不再是PDF里的符号而是你手指能触碰到的真实电压。这本手册就是要把这种“触感”传递给你。2. 为什么非得啃寄存器——从三个真实翻车现场说起很多人问“现在都有CubeMX和HAL库了连初始化代码都能自动生成为啥还要学寄存器”这个问题我每次实训课第一节课都会被问到。我的回答从来不是讲理论而是带大家看三个我亲手调试过的、用HAL库写的项目翻车现场2.1 现场一UART接收卡死示波器显示RX线上有信号但HAL_UART_Receive_IT()永远不进回调某学员做温湿度采集终端用HAL_UART_Receive_IT()接收传感器返回的ASCII字符串。调试时发现只要传感器返回的数据长度超过16字节程序就卡死在HAL_UART_Receive_IT()里。他查遍HAL库源码发现函数内部调用了__HAL_UART_ENABLE_IT(huart1, UART_IT_RXNE)再往里跟是操作USART1-CR1 | USART_CR1_RXNEIE。但他没意识到CR1寄存器的RXNEIE位bit5只是打开了“接收数据寄存器非空”这个中断使能开关而真正触发中断的硬件条件是USART_SR寄存器里的RXNE标志位bit5被硬件自动置1。当数据流持续涌入而他的中断服务程序处理太慢比如在里面做了浮点运算SR寄存器的RXNE位就会一直保持1但因为中断已经被响应过一次CPU不会再次进入中断导致后续数据覆盖前一个字节RX寄存器只有1字节深度。他最后的解法是在中断里加了一句__HAL_UART_CLEAR_FLAG(huart1, UART_FLAG_RXNE);—— 这行代码的本质就是向USART1-SR寄存器的RXNE位写0清掉这个标志。如果不理解SR寄存器每个比特的含义和清零机制光看HAL库的CLEAR_FLAG宏就像看天书。2.2 现场二PWM频率死活调不准示波器测出来是理论值的两倍另一个学员想用TIM2_CH1PA0输出1kHz方波按CubeMX配置预分频PSC71自动重装载ARR999理论频率72MHz/((711)(9991))1kHz。可示波器一测是2kHz。他反复检查参数甚至换了块新板子。最后我让他打开STM32F103xx参考手册第19章找到TIMx_CR1寄存器重点看CMS[1:0]中心对齐模式选择和DIR计数方向位。原来他CubeMX里误勾了“Center-aligned mode”CMS01此时计数器在0→ARR→0双向计数一个完整周期需要计数2ARR次所以实际频率翻倍。HAL库生成的代码里有一句htim2.Instance-CR1 | TIM_CR1_CMS_0;他完全没注意。寄存器手册里明确写着“In center-aligned mode, the counter counts up then down between 0 and the auto-reload value.” —— 这句话翻译成人话就是“中心对齐模式下计数器先从0数到ARR再从ARR数回0才算一个周期。” 不看寄存器定义只信图形化配置就像开车只看导航不看路标拐错一个弯目的地就偏了50公里。2.3 现场三低功耗模式下RTC闹钟失效万用表测LSE晶振停振最典型的是RTC项目。学员用HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI)进入STOP模式期望RTC闹钟唤醒。结果一进STOP板子就彻底没反应。他查HAL库发现进入STOP前要调用HAL_RCC_OscConfig()配置LSE又调用HAL_RTC_SetAlarm()。但漏掉了最关键一步在进入STOP前必须确保LSE晶振已经起振并稳定且RTC时钟源已成功切换到LSE。这需要读取RCC_CSR寄存器的LSERDY位bit 1确认LSE就绪再检查RTC_ISR寄存器的RSF位bit 5是否为1Register Synchronization Flag只有RSF1才表示RTC寄存器同步完成此时才能安全写入ALRMxR。他跳过了这两个关键状态检查直接进STOPLSE还没起振就被断电RTC自然失灵。寄存器手册第7.3.4节清楚列出“The LSE oscillator must be enabled and stable before it can be selected as RTC clock source.” —— “LSE振荡器必须先启用并稳定才能被选作RTC时钟源。” 这不是建议是硬件铁律。HAL库的HAL_RTC_Init()函数内部就包含这些检查但如果你不理解背后寄存器的状态流转逻辑出了问题连排查方向都找不到。这三个现场本质都是同一个问题把抽象的API当成了魔法却忽略了API背后操控的是物理世界里真实存在的晶体管开关阵列。寄存器就是这些开关的唯一控制面板。白话手册的价值不在于让你背下所有地址而在于帮你建立一种直觉看到一个功能需求脑子里能立刻映射出“需要动哪几个外设的哪几个寄存器的哪几个比特”以及“动之前要确认哪些前置状态”。3. 白话手册的骨架四层递进式理解模型市面上很多寄存器教程要么是纯地址表罗列像电话黄页要么是逐字翻译参考手册像文言文注释。这本白话手册采用我实践验证过的“四层递进模型”每一层都解决一个认知台阶确保你能稳稳踩上去3.1 第一层寄存器是什么——从“内存地址”到“硬件开关”的具象化先扔掉所有术语。想象你面前有一块真实的STM32芯片放大镜下能看到密密麻麻的金属走线。其中一组走线专门连接到GPIOA模块的“输出控制单元”。这组走线的起点就是GPIOA_BSRR寄存器Base Set/Reset Register的物理地址0x40010818。当你执行*(volatile unsigned int*)0x40010818 0x00000020;CPU做的不是“写数据”而是向这组特定走线发送一串电信号这串电信号被GPIOA模块的硬件逻辑电路解读为“请把PA5引脚的输出电平强制置为高”。这个过程和你按下一个实体开关让电流通过灯泡点亮物理本质完全一样。区别只在于实体开关是机械的寄存器是电子的实体开关控制一根线寄存器可以同时控制32根线一个32位寄存器。所以寄存器不是软件概念它是硬件电路在CPU地址空间里的一个“影子接口”。白话手册里所有寄存器讲解第一句必然是“这个寄存器就是控制XX硬件模块的YY功能的物理开关面板。”3.2 第二层寄存器怎么用——“读-改-写”与“原子操作”的生死线新手最容易犯的错误是把寄存器当普通变量用。比如想把PA5设为高电平他写GPIOA-ODR GPIOA-ODR | (1 5); // 错危险这行代码看似正确但它包含了三次独立操作1) 从0x4001080C地址读取当前ODR值2) 执行或运算3) 把结果写回0x4001080C。问题在于如果在第1步和第3步之间硬件中断发生另一个中断服务程序也修改了ODR的其他位比如PA6那么第3步写回去的值就会把PA6的修改覆盖掉。这就是经典的“读-改-写”Read-Modify-Write竞态问题。白话手册给出的解决方案是直接使用BSRR寄存器的原子置位/复位特性GPIOA-BSRR (1 5); // 原子置位PA5不影响其他位 GPIOA-BSRR (1 (5 16)); // 原子复位PA5不影响其他位BSRR寄存器的设计很巧妙低16位bit0~15写1表示置位对应IO高16位bit16~31写1表示复位对应IO写0无效。这意味着你向BSRR写一个32位数硬件电路会自动解析出哪些位要置1、哪些位要清0并在一个总线周期内完成中间不会被打断。这就像你有一个带32个独立拨动开关的控制台每个开关只控制一根线拨动一个其他完全不受影响。白话手册里所有涉及多比特操作的寄存器都会明确标注“此处必须用BSRR/BSRR替代ODR避免读-改-写风险”并附上实测对比波形图——用示波器抓取PA5和PA6两个引脚在中断频繁触发时ODR方式会导致PA6电平毛刺而BSRR方式则纹丝不动。3.3 第三层寄存器之间怎么联动——“时钟树”与“状态机”的全局视角单个寄存器好懂难的是理解一堆寄存器如何协同工作。比如启动一个ADC转换你需要操作至少5个寄存器RCC_APB2ENR开ADC时钟、ADC1_CR2启动转换、ADC1_SMPR1设置采样时间、ADC1_CHSELR选择通道、ADC1_DR读取结果。但顺序错了就全白忙。白话手册用“水电站调度”来类比RCC_APB2ENR是上游水库的总闸门必须先打开置位bit9水时钟信号才能流到ADC厂房ADC1_CR2是厂房里的开机按钮但按之前得确认水压时钟稳定ADC1_SMPR1是调节进水阀门开度的旋钮决定水流模拟信号在管道里停留多久采样时间ADC1_CHSELR是选择哪条支流哪个通道的水进入主厂房最后ADC1_DR是厂房出口的流量计显示实时水量数字结果。任何一个环节没到位整个流程就卡死。手册里每个外设章节开头必有一张手绘风格的“寄存器依赖关系图”用箭头标明“必须先配置A才能操作B”并标注每个步骤失败时的典型现象如“若未开时钟写ADC1_CR2无任何反应ADC1_SR的EOC位永不置1”。3.4 第四层寄存器出错了怎么办——“状态寄存器”是你的X光机所有外设模块都配有一个状态寄存器SR比如USART_SR、TIM_SR、ADC_SR。这是寄存器手册里最常被忽略却是最救命的部分。它不像控制寄存器那样让你“发号施令”而是让你“听诊把脉”。比如当你调用HAL_UART_Transmit()发送数据函数却卡死在while(__HAL_UART_GET_FLAG(huart1, UART_FLAG_TC) RESET)循环里说明传输完成TC标志位一直没变。这时你应该立刻去看USART_SR寄存器的其他位TXE发送寄存器空是否为1如果TXE0说明发送缓冲区TDR还塞着上一个字节没发出去原因可能是波特率算错导致时序异常如果TXE1但TC0说明数据已发完但停止位还没送完可能是因为线路短路导致TX引脚被拉低硬件无法产生停止位。白话手册把每个外设的SR寄存器做成一张“故障速查表”左边列现象如“发送卡死”、“接收无中断”、“定时器不计数”右边直接对应SR寄存器的哪一位应该为1或0并给出用万用表或示波器验证的实操方法。例如查“ADC不转换”表里写“检查ADC1_SR的ADONS位bit0用万用表测ADC1电源引脚电压若电压正常但ADONS0说明ADC1_CR2的ADON位未置位若ADONS1但EOC0用示波器测ADC1时钟输入引脚确认时钟信号存在且频率正确。”4. 核心外设寄存器白话精解以GPIO、USART、TIM为例4.1 GPIO寄存器组从“点灯”到“精准控压”的全流程拆解GPIO是STM32最基础也最易被低估的外设。很多人以为“点灯”就是GPIOA-ODR | (15);但实际工业场景中GPIO常用于精密控制比如驱动一个0.1Ω的电流检测电阻要求输出电平误差小于5mV。这就必须深挖GPIO寄存器的每一个细节。GPIOx_MODER模式寄存器地址偏移0x00这是GPIO的“职业认证”。每个IO口占2位00输入01通用推挽输出10复用功能11模拟。白话手册强调“MODER不是开关是上岗证。你给PA5发了上岗证01它才有资格当推挽输出没发证00你再往ODR写1它也只会高阻悬空不会输出3.3V。” 实操心得配置MODER时必须用“读-改-写”安全操作因为MODER是32位寄存器你只想改PA5的2位不能把其他30位全清零。正确写法GPIOA-MODER (GPIOA-MODER ~(3 (5*2))) | (1 (5*2));—— 先用掩码~(3(5*2))把PA5的2位清零再用| (1(5*2))把01写进去。GPIOx_OTYPER输出类型寄存器地址偏移0x04决定“推挽”还是“开漏”。推挽0像双人抬轿能拉高也能拉低开漏1像单人拉绳只能拉低拉高靠外部上拉电阻。白话手册用LED驱动举例“驱动共阳极LEDLED正极接VCC必须用开漏模式否则PA5输出高电平时LED两端都是3.3V没压差不亮输出低电平时PA5拉低LED负极接地形成回路点亮。” 参数计算若用开漏驱动LED上拉电阻R需满足R VCC / I_maxI_max是LED最大允许电流通常20mA且R (VCC - Vf_LED) / I_desiredVf_LED是LED正向压降约1.8V。实测下来4.7kΩ上拉电阻在3.3V系统中既能保证足够亮度又不会让PA5过载。GPIOx_OSPEEDR输出速度寄存器地址偏移0x08不是“跑多快”是“边沿有多陡”。00低速10MHz01中速2MHz10高速50MHz11超高速100MHz。白话手册警告“别盲目设高速驱动长PCB走线10cm或容性负载50pF时高速边沿会引发振铃ringing用示波器看PA5波形会发现上升沿有剧烈震荡可能误触发下游电路。此时应降速到中速并在PA5引脚就近加一个100Ω串联电阻吸收高频能量。” 这个经验是我在调试一个CAN总线节点时因PA11CAN_TX边沿过陡导致CANH/CANL差分信号畸变连续烧毁3片TJA1050后总结的。GPIOx_PUPDR上拉/下拉寄存器地址偏移0x0C解决“悬空”问题。00无上下拉01上拉10下拉11保留。白话手册特别指出“对于复用功能引脚如USART1_TXPA9即使你不用上拉也强烈建议设为‘无上下拉’00而不是留空。因为某些复用功能如I2C内部有弱上拉若外部再接强上拉会导致电流冲突。” 实操技巧用万用表二极管档测PA5对地电阻若PUPDR设为上拉01应测得约40kΩ内部上拉典型值若设为下拉10应测得约20kΩ内部下拉典型值若为00则电阻无穷大高阻。GPIOx_BSRR置位/复位寄存器地址偏移0x18前面提过这是GPIO操作的黄金法则。白话手册给出终极口诀“所有IO电平操作只用BSRR所有IO模式配置只用MODER/OTYPER/OSPEEDR/PUPDRODR只在极少数需要读取当前全部输出状态时才用且必须加volatile声明。” 并附上性能对比在72MHz主频下GPIOA-BSRR (15)执行耗时1个周期13.9ns而GPIOA-ODR | (15)因涉及读-改-写耗时至少5个周期69.4ns且有竞态风险。4.2 USART寄存器组从“发Hello World”到“抗干扰通信”的硬核解析USART是嵌入式通信的基石但也是寄存器配置最易出错的模块之一。白话手册不讲波特率公式而是聚焦三个致命细节USARTx_BRR波特率寄存器地址偏移0x0C它的值不是简单计算出来的而是由DIV_Mantissa高12位和DIV_Fraction低4位两部分组成。白话手册提供傻瓜式查表法假设系统时钟72MHz目标波特率115200查手册表227BRR0x341。但为什么是0x341因为72000000/(16115200)39.0625整数部分390x27小数部分0.0625161所以BRR0x271错手册规定DIV_Fraction是4位代表16分频的余数0.0625*161没错但DIV_Mantissa是12位39的十六进制是0x27所以BRR0x271还是错正确算法是DIV_Mantissa INT(39.0625) 39 0x27DIV_Fraction ROUND((39.0625 - 39)16) ROUND(0.062516) 1所以BRR (0x27 4) | 0x1 0x270 | 0x1 0x271。但实测发现0x271在某些晶振精度下仍有误差。白话手册的实操方案是用示波器测TX引脚调整BRR值直到一个bit宽度1/115200≈8.68μs误差小于5%最终确定BRR0x341即0x344 | 0x1这才是工程上真正可靠的值。手册里所有波特率配置都附有实测波形截图和对应BRR值。USARTx_CR1控制寄存器1地址偏移0x00重点讲UEUSART Enablebit13和RE/TE接收/发送使能bit2/3。白话手册强调“UE位是总电源开关必须最后置位。如果先置UE再配置BRR硬件会用BRR的复位值0计算波特率导致通信失败。正确顺序1) 配置BRR2) 配置CR1的RE/TE3) 最后置位UE。” 这个顺序在参考手册第27章“USART initialization sequence”里有明确说明但新手常忽略。手册用流程图展示错误顺序的后果UE先置位 → 硬件用BRR0计算波特率 → 波特率无限大 → TX引脚输出恒定高电平逻辑1。USARTx_SR状态寄存器地址偏移0x00这是通信故障的诊断中心。白话手册提炼出“SR三剑客”TXETransmit Data Register Emptybit7发送数据寄存器空。当你要发一个字节先检查TXE为1才往TDR写数据。白话“TXE1说明TDR这个‘快递柜’空了你可以塞新包裹TXE0说明柜子还有货没发走你塞新货会丢件。”TCTransmission Completebit6发送完成。当TDR的数据移到移位寄存器并发送完毕TC置1。白话“TC1说明你塞的包裹不仅进了柜子TXE还真的被快递员硬件送到了收件人TX线手上。”RXNERead Data Register Not Emptybit5接收数据寄存器非空。当RX线上收到一个完整字节硬件把它放进RDRRXNE置1。白话“RXNE1说明快递员RX线把包裹字节投进了你的RDR‘收件箱’你可以去取了不取下次包裹来了会覆盖前一个。” 手册给出经典问题排查链若接收不到数据按此顺序查SRRXNE0→ 查RE是否置位RXNE0但RX线上有信号→ 查时钟是否开启RCC_APB2ENR bit17RXNE1但读RDR总是0xFF→ 查是否忘了清除RXNE标志读RDR自动清RXNE但有些旧版手册说需写0实测读RDR即可。4.3 TIM定时器寄存器组从“延时”到“精确脉宽调制”的毫秒级掌控TIM是STM32的“心脏起搏器”其寄存器配置直接影响系统实时性。白话手册以TIM2通用定时器为例直击三个核心痛点TIMx_PSC预分频寄存器地址偏移0x00不是“分多少次”而是“每来多少个时钟脉冲计数器才加1”。白话手册用跑步比喻“PSC71意思是CPU每跑72步72个时钟周期TIM2的计数器才迈1步。所以如果CPU主频72MHzTIM2的计数器时钟就是72MHz/(711)1MHz即每1微秒计1。” 关键参数PSC值必须是16位无符号整数0~65535所以最大分频比为65536。若需更低频必须用ARR配合。实操陷阱PSC写入后需等待UG位Update Generation被硬件置1表示新PSC值已生效。手册推荐写法TIM2-PSC 71; TIM2-EGR TIM_EGR_UG;—— 主动触发更新事件避免等待不确定时间。TIMx_ARR自动重装载寄存器地址偏移0x04决定“跑多远”。当计数器从0数到ARR就产生一次更新事件UEV并自动清零重启。白话手册强调“ARR不是周期是周期减1。因为计数器从0开始数到ARR共ARR1个数。” 所以要产生1ms定时中断计数器时钟1MHz则ARR (1MHz * 0.001s) - 1 1000 - 1 999。手册里所有定时计算都强制写出“-1”并用红色加粗标注因为这是90%新手第一次写定时器时的必错点。TIMx_CCMR1捕获/比较模式寄存器1地址偏移0x18这是PWM的灵魂。以CH1为例CC1S[1:0]bit0~1选择通道功能00输出01输入IC110输入IC211保留OC1M[2:0]bit6~4选择输出比较模式110PWM模式1111PWM模式2。白话手册详解PWM模式1“当CNT CCR1输出高当CNT CCR1输出低。所以CCR1值越大高电平时间越长占空比越大。” 而PWM模式2相反。手册用示波器截图对比两种模式同一CCR1500模式1输出高电平500us模式2输出低电平500us。并给出工业应用忠告“控制电机或LED亮度务必用PWM模式1OC1M110因为它的高电平对应‘有效’状态逻辑清晰若误用模式2调试时会发现‘增大CCR1亮度反而变暗’徒增困惑。”5. 实操避坑指南那些只有踩过才知道的“寄存器暗礁”5.1 时钟配置RCC寄存器组的“蝴蝶效应”RCC复位和时钟控制是STM32的“中央调度室”一个比特配错全盘皆输。白话手册记录了我踩过的最深的三个坑坑一HSI校准值被意外修改HSI内部高速RC振荡器出厂校准值存在RCC_ICSCR寄存器的HSITRIM[6:0]位bit3~9。新手有时为了“优化”时钟用CubeMX修改HSITRIM结果发现USB通信失败。原因USB模块要求时钟精度±0.25%而HSI本身精度只有±1%校准值是厂家在产线上用高精度仪器测得的。你随意改一个比特精度偏差可能达±5%USB PHY直接罢工。白话手册的硬性规定“除非你有频谱分析仪和校准夹具否则HSITRIM位必须保持复位值0x10任何修改都视为高危操作。”坑二APB1/APB2时钟使能顺序颠倒某学员配置USART1挂APB2和I2C1挂APB1他先写了RCC-APB2ENR | RCC_APB2ENR_USART1EN;再写RCC-APB1ENR | RCC_APB1ENR_I2C1EN;结果I2C通信正常USART1却无反应。查手册发现USART1的时钟使能位bit14在APB2ENR但它的复位值依赖于APB1域的时钟稳定性。正确顺序必须是1) 先使能APB1时钟RCC-APB1ENR | ...2) 等待APB1时钟稳定查RCC_CR的HSION/HSIRDY3) 再使能APB2时钟RCC-APB2ENR | ...。手册里所有时钟使能代码都强制用while(!(RCC-CR RCC_CR_HSIRDY));做等待绝不省略。坑三PLL配置后忘记清除PLL就绪标志配置PLL时先写RCC-CFGR设置倍频系数再置位RCC-CR的PLLEN位。但PLLEN置位后硬件需要时间锁定期间RCC-CR的PLLREADY位bit25为0。新手常在PLLEN置位后立即切时钟源到PLL导致系统死锁。白话手册的黄金等待法RCC-CR | RCC_CR_PLLON; while(!(RCC-CR RCC_CR_PLLRDY));—— 必须用while循环等待PLLREADY1且循环内不能有任何可能影响时钟的代码如调用SysTick_Delay。手册实测在72MHz系统下PLL锁定时间约100μs但必须用硬件标志判断不能用软件延时。5.2 中断配置NVIC寄存器组的“优先级迷宫”中断是实时系统的命脉但NVIC嵌套向量中断控制器的优先级分组PRIGROUP常让人晕头转向。白话手册用“医院急诊分级”类比PRIGROUP0000分组所有4位抢占优先级0位子优先级。像三甲医院所有科室中断都能随时插队抢占但同科室病人同中断按先后排队无子优先级。适合对实时性要求极高的场合如电机FOC控制。PRIGROUP1015分组3位抢占1位子优先级。像社区医院内科、外科、儿科不同抢占组可互相插队但内科里感冒和心梗同抢占组不同子组按病情轻重排。PRIGROUP1117分组0位抢占4位子优先级。像家庭医生所有病人都不能插队只能按预约顺序子优先级看诊。适合简单系统。白话手册的致命提醒“NVIC_SetPriorityGrouping()必须在任何中断使能前调用且只能调用一次” 我曾调试一个项目主循环里反复调用此函数结果发现中断响应时间忽长忽短。原因每次调用都重置PRIGROUP导致正在执行的中断服务程序ISR的优先级规则突然改变硬件行为不可预测。手册规定PRIGROUP配置必须放在main()函数
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表