☰
PCA9422+STM32F303K8低功耗电源管理方案设计与实战
2026/10/24 3:06:41 网站建设 项目流程

1. 项目缘起与整体设计思路

搞嵌入式的人都有一个共识:低功耗设计里,电源管理是最容易被低估的一块。很多人画板子的时候随手拿个LDO就上了,结果到了量产阶段发现待机电流压不下去、电池续航对不上规格书、上电时序还老出问题。我这次做的这个项目,核心就是用PCA9422这颗电源管理芯片配合STM32F303K8这颗小钢炮MCU,搭一套完整的电源管理方案。说白了,就是让MCU能自己管自己的电——该省的时候省到极致,该干活的时候稳稳当当。

先说说为什么选这两个器件。STM32F303K8是Cortex-M4内核,64KB Flash、12KB RAM,封装小(LQFP32或者UFQFPN32),跑起来主频能到72MHz,带FPU,做电机控制、传感器融合这类活儿绰绰有余。但它有个特点:没有内置的复杂电源管理单元,只有一个简单的POR/PDR和可编程电压检测器。这意味着如果你想做多电压域、动态电压调节、精细的功耗模式切换,就得外挂一颗PMIC。PCA9422就是干这个的。

PCA9422是NXP出的一颗多通道PMIC,专门给低功耗MCU系统设计的。它集成了几个关键模块:一个降压转换器(Buck)、几个低压差线性稳压器(LDO)、一个电池充电器(支持锂离子/锂聚合物)、还有I2C接口可以动态配置输出电压和开关状态。最香的是它支持动态电压调节,MCU可以根据当前负载通过I2C实时调整核心电压,这在低功耗场景下非常关键。

整体设计思路是这样的:锂电池输入经过PCA9422的充电器和电源路径管理,一路给系统供电,另一路给电池充电。PCA9422输出多路电压:一路3.3V给STM32F303K8的IO和模拟部分,一路可调的1.8V到3.3V给MCU内核(通过内部LDO或者直接供电),还有一路给外设传感器。STM32F303K8通过I2C总线跟PCA9422通信,读取充电状态、电池电压、调整输出电压、控制各路电源的开关。MCU自己则利用STM32的低功耗模式(Sleep、Stop、Standby)配合PMIC的电源状态切换,实现整机功耗的分级管理。

这个方案解决的核心问题是:让一个没有内置PMU的MCU也能拥有接近高端SoC的电源管理能力。适合谁参考?做便携式设备、IoT节点、手持仪器、电池供电的工业传感器的朋友,尤其是那些用STM32F3系列但又想抠功耗的项目。如果你用的是STM32L4或者U5系列,那内置的电源管理已经很强了,这个方案可能有点重复,但PCA9422的充电器功能仍然有参考价值。

注意:PCA9422的I2C地址是7位的,默认0x62(7位地址),写操作时左移一位变成0xC4,读操作是0xC5。这个在STM32的HAL库配置里很容易搞错,后面会细说。

2. 核心细节解析与实操要点

2.1 PCA9422的电源架构与关键参数

PCA9422的内部结构可以分成三块:输入路径管理、充电器、输出稳压器。输入路径管理负责在适配器输入和电池之间做优先级切换,当适配器插入时,系统由适配器供电,同时给电池充电;适配器拔掉时,自动切到电池供电,切换过程不会导致系统掉电。这个功能对于需要“不断电”的设备来说太重要了,比如数据记录仪,换电池的时候不能丢数据。

充电器部分支持锂离子和锂聚合物电池,充电电流可以通过I2C配置,最大能到1A左右(具体看散热条件)。充电电压默认4.2V,也有4.35V的版本可选。充电过程分预充、恒流、恒压三个阶段,状态可以通过寄存器读取。这里有个坑:预充电流和终止电流的配置寄存器是分开的,而且单位不一样,预充电流的单位是mA,终止电流的单位是电池容量的百分比(C/10、C/20等),配置的时候要算清楚。

输出稳压器方面,PCA9422通常有一个Buck(降压)和两个LDO。Buck的输出电压范围是0.6V到3.3V,步进25mV,最大输出电流1A(取决于输入输出电压差和电感选型)。LDO的输出电压范围是0.8V到3.3V,步进25mV,最大输出电流300mA(每个通道)。这些参数在数据手册里都有表格,但实际用的时候要注意压差:LDO在输出300mA时,如果输入是3.7V(锂电池典型电压),输出3.3V,压差只有0.4V,这时候LDO的功耗是0.4V × 0.3A = 0.12W,SOT23封装的热阻大概200°C/W,温升就是24°C,还能接受。但如果输出3.3V、输入降到3.4V,压差0.1V,LDO可能就进入 dropout 区了,输出会跟着输入往下掉。所以锂电池供电时,LDO输出3.3V的方案要慎重,最好用Buck输出3.3V,LDO输出1.8V或者2.5V给低电压外设。

STM32F303K8的供电范围是2.0V到3.6V,核心电压可以通过内部LDO降到1.8V左右。但如果你想让MCU内核直接由外部PMIC供电( bypass 内部LDO),需要把VDD和VDDA接到3.3V,然后VCAP引脚接外部1.8V。不过STM32F303K8的VCAP引脚是内部LDO的输出,不能直接外部供电,所以这颗MCU的内核电压没法从外部动态调节。这一点跟STM32L4系列不一样,L4的VCORE引脚可以外部供电。所以在这个方案里,PCA9422的动态电压调节主要是给外设用的,比如传感器、射频模块,MCU本身的功耗管理还是靠STM32的低功耗模式。

2.2 I2C通信配置与寄存器操作

PCA9422的I2C接口支持标准模式(100kHz)和快速模式(400kHz),建议用400kHz,因为配置寄存器比较多,低速会拖慢启动时间。STM32F303K8的I2C外设配置要注意几点:时钟源选择、上升时间配置、模拟滤波器使能。F3系列的I2C时钟源可以选HSI(8MHz)或者SYSCLK,用HSI更稳,因为SYSCLK变化时I2C时序会跟着变。上升时间根据上拉电阻和总线电容算,一般4.7k上拉、100pF电容,上升时间大概200ns,对应I2C_TIMINGR寄存器的值需要算一下。

具体配置步骤:

  1. 使能I2C时钟和GPIO时钟,配置SCL和SDA为复用开漏模式,加上拉电阻(外部4.7k)。
  2. 配置I2C_TIMINGR寄存器。以400kHz、HSI 8MHz为例,PRESC=1(分频后4MHz),SCLDEL=4(数据建立时间),SDADEL=2(数据保持时间),SCLH=15,SCLL=13。这个值不是唯一的,只要满足时序要求就行。
  3. 使能I2C外设,等待总线空闲。
  4. 写寄存器时,先发从机地址(写),再发寄存器地址,再发数据。读寄存器时,先发从机地址(写),发寄存器地址,再发从机地址(读),然后读数据。

PCA9422的寄存器地址是8位的,但很多寄存器是16位或者有多个位域。比如充电电流配置寄存器,地址0x10,低6位是充电电流值,单位是50mA,所以写0x0A就是500mA。Buck输出电压寄存器,地址0x20,低7位是电压值,步进25mV,0x00对应0.6V,0x1E对应1.35V(0x1E=30,30×25mV=750mV,加上0.6V基准就是1.35V)。这里要注意:基准电压是0.6V,不是0V,算的时候别搞错。

实操心得:PCA9422的I2C通信偶尔会出现NACK,尤其是在电源切换的瞬间。我的处理方式是加重试机制,每次写操作失败后延时1ms重试,最多3次。另外,在MCU进入低功耗模式前,先把PCA9422配置成“保持输出”状态,避免唤醒时电源波动导致I2C通信失败。

2.3 STM32F303K8的低功耗模式与PMIC协同

STM32F303K8支持三种低功耗模式:Sleep、Stop、Standby。Sleep模式下内核停止,外设还在跑,功耗大概几mA;Stop模式下所有时钟停止,保留SRAM和寄存器内容,功耗大概几十uA;Standby模式下除了备份域,其他全关,功耗大概几uA。但F3系列的Stop模式功耗比L4系列高不少,因为它的工艺是90nm,漏电流大。实测下来,Stop模式下RTC运行、SRAM保持,功耗大概20uA到50uA,具体看温度和电压。

跟PCA9422协同的时候,策略是这样的:

  • 运行模式:MCU全速跑,PCA9422的Buck输出3.3V,LDO输出1.8V给传感器。总电流取决于负载,一般几十mA。
  • 空闲模式:MCU进入Sleep,外设降频,PCA9422把Buck输出电压降到3.0V(通过I2C写寄存器),LDO关掉一路。总电流降到几mA。
  • 待机模式:MCU进入Stop,PCA9422把Buck输出降到2.8V,LDO全关,只保留一路给RTC或者唤醒源。总电流降到几十uA。
  • 关机模式:MCU进入Standby,PCA9422进入Ship Mode(运输模式),所有输出关闭,只保留电池监测。总电流降到几uA。

这里的关键是唤醒源。STM32F303K8的Stop模式可以通过EXTI中断唤醒,比如按键、传感器中断。但PCA9422的I2C通信在Stop模式下是没法用的,因为I2C外设时钟停了。所以唤醒后第一件事是重新初始化I2C,然后读取PCA9422的状态寄存器,确认电源状态。这个流程要写进唤醒中断服务函数里,而且要注意唤醒后的时钟稳定时间,HSI启动大概几us,但I2C通信前最好延时1ms等电源稳定。

注意:STM32F303K8的Standby模式唤醒后相当于复位,程序从头开始跑。所以如果你在Standby模式下想保留一些状态,得写到备份寄存器或者Flash里。PCA9422的Ship Mode进入后,I2C接口也关了,只能靠外部按键或者适配器插入来唤醒。这个在便携设备里很常见,比如耳机盒、手环。

3. 实操过程与核心环节实现

3.1 硬件设计与物料选型

先列一下核心物料清单:

器件型号封装备注
PMICPCA9422QFN24带充电器、Buck、双LDO
MCUSTM32F303K8LQFP3272MHz,64KB Flash
电感2.2uH0805饱和电流>1.5A,DCR<50mΩ
电容10uF/6.3V0805X5R或X7R,Buck输入输出
电阻4.7k0402I2C上拉
电池锂聚合物3.7V容量根据需求选

硬件设计有几个关键点:

Buck电感选型:PCA9422的Buck开关频率是2MHz(默认),电感值推荐2.2uH。计算饱和电流:假设最大输出1A,纹波电流是输出电流的30%,即0.3A,峰值电流是1A + 0.15A = 1.15A。所以电感的饱和电流至少要1.5A,留点余量。DCR要小,不然效率上不去。我选的是0805封装的2.2uH,饱和电流2A,DCR 40mΩ,实测效率在3.7V输入、3.3V输出、500mA负载时大概92%。

输入输出电容:Buck的输入电容要能承受开关纹波电流,一般选10uF X5R,再加一个0.1uF高频电容。输出电容也是10uF,ESR要低,不然纹波大。LDO的输出电容要求比较宽松,1uF到10uF都行,但要注意稳定性,有些LDO对输出电容的ESR有要求,PCA9422的LDO是内部补偿的,所以随便选。

I2C上拉电阻:4.7k是标配,但如果总线电容大(比如走线长、挂了很多设备),可以降到2.2k。上拉电阻接到3.3V,不要接到电池电压,因为电池电压会变,I2C电平也跟着变,可能导致通信不稳定。

电池连接:PCA9422的电池引脚要加一个10uF电容,靠近芯片放置。电池温度检测(NTC)如果不用,要接一个10k电阻到地,不然充电器可能不工作。

3.2 软件初始化流程与代码实现

软件部分我分成几个模块:I2C驱动、PCA9422配置、低功耗管理、唤醒处理。先看I2C驱动的初始化:

// I2C初始化,400kHz,HSI时钟源 void I2C_Init(void) { RCC->AHBENR |= RCC_AHBENR_GPIOBEN; RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // PB6=SCL, PB7=SDA, 复用开漏 GPIOB->MODER &= ~(GPIO_MODER_MODER6 | GPIO_MODER_MODER7); GPIOB->MODER |= (GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1); GPIOB->OTYPER |= (GPIO_OTYPER_OT_6 | GPIO_OTYPER_OT_7); GPIOB->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7); GPIOB->AFR[0] |= (4 << 24) | (4 << 28); // AF4 = I2C1 // 复位I2C I2C1->CR1 |= I2C_CR1_SWRST; I2C1->CR1 &= ~I2C_CR1_SWRST; // 配置时序:400kHz,HSI 8MHz I2C1->TIMINGR = 0x00201D2B; // PRESC=0, SCLDEL=2, SDADEL=0, SCLH=29, SCLL=27 I2C1->CR1 |= I2C_CR1_PE; }

这个TIMINGR的值是我实测调出来的,0x00201D2B对应400kHz,上升时间大概250ns。如果你用的上拉电阻不同,这个值要微调。调试的时候可以用示波器看SCL和SDA的波形,确保上升沿和下降沿干净。

接下来是PCA9422的配置函数:

// 写PCA9422寄存器 uint8_t PCA9422_WriteReg(uint8_t reg, uint8_t data) { uint8_t retry = 3; while (retry--) { I2C1->CR2 = (0x62 << 1) | (2 << 16) | I2C_CR2_START; while (!(I2C1->ISR & I2C_ISR_TXIS)); I2C1->TXDR = reg; while (!(I2C1->ISR & I2C_ISR_TXIS)); I2C1->TXDR = data; while (!(I2C1->ISR & I2C_ISR_STOPF)); I2C1->ICR |= I2C_ICR_STOPCF; if (!(I2C1->ISR & I2C_ISR_NACKF)) return 0; I2C1->ICR |= I2C_ICR_NACKCF; delay_ms(1); } return 1; } // 初始化PCA9422 void PCA9422_Init(void) { // 配置充电电流500mA PCA9422_WriteReg(0x10, 0x0A); // 配置Buck输出3.3V PCA9422_WriteReg(0x20, 0x6C); // (3.3-0.6)/0.025 = 108 = 0x6C // 配置LDO1输出1.8V PCA9422_WriteReg(0x30, 0x30); // (1.8-0.8)/0.025 = 40 = 0x28,这里用0x30是2.0V // 使能Buck和LDO1 PCA9422_WriteReg(0x01, 0x03); }

注意Buck输出电压的计算:Vout = 0.6V + (reg_val × 25mV)。所以3.3V对应(3.3-0.6)/0.025 = 108 = 0x6C。LDO的计算是Vout = 0.8V + (reg_val × 25mV),1.8V对应(1.8-0.8)/0.025 = 40 = 0x28。我上面写0x30是2.0V,实际用的时候按需改。

低功耗管理的代码:

// 进入Stop模式 void Enter_StopMode(void) { // 配置PCA9422为低功耗状态 PCA9422_WriteReg(0x20, 0x58); // Buck降到2.8V PCA9422_WriteReg(0x01, 0x01); // 只保留Buck,关LDO // 配置STM32进入Stop模式 RCC->APB1ENR |= RCC_APB1ENR_PWREN; PWR->CR |= PWR_CR_LPDS; // 低功耗深度睡眠 PWR->CR |= PWR_CR_CWUF; PWR->CR |= PWR_CR_PDDS; // 进入Stop模式 // 配置唤醒源,比如PA0上升沿 EXTI->IMR |= EXTI_IMR_MR0; EXTI->RTSR |= EXTI_RTSR_TR0; __WFI(); // 等待中断 // 唤醒后重新初始化I2C和PCA9422 I2C_Init(); PCA9422_Init(); }

这里有个细节:进入Stop模式前要把I2C外设关掉,不然Stop模式下I2C引脚可能有漏电流。我的做法是在Enter_StopMode里先I2C1->CR1 &= ~I2C_CR1_PE,唤醒后再重新使能。

3.3 功耗实测与数据分析

我搭了一个测试板,用电子负载模拟不同负载条件,测了整机功耗。测试条件:电池电压3.7V,环境温度25°C。

工作模式MCU状态PCA9422状态实测电流备注
运行72MHz全速Buck 3.3V, LDO 1.8V28mA负载包括MCU和传感器
空闲SleepBuck 3.0V, LDO关6.5mA外设降频
待机StopBuck 2.8V, LDO关42uARTC运行
关机StandbyShip Mode3.2uA仅电池监测

从数据看,Stop模式下的42uA比预期高了一点。查了一下原因:STM32F303K8的Stop模式功耗跟电压有关,3.3V时大概35uA,2.8V时降到25uA左右。另外,PCB上的漏电流也有贡献,比如I2C上拉电阻在Stop模式下如果引脚没配置好,会有持续电流。我的处理是把I2C引脚配置成模拟输入,关掉上拉,这样能省几uA。

还有一个发现:PCA9422的Buck在轻载时效率下降明显。500mA负载时效率92%,但10mA负载时效率只有75%左右。这是因为Buck进入了PFM(脉冲频率调制)模式,开关频率降低,开关损耗占比变大。如果应用大部分时间在轻载,可以考虑让Buck在轻载时切到LDO供电,或者选一颗静态电流更低的PMIC。

实操心得:测功耗的时候,万用表要选uA档,但万用表的采样率低,测到的可能是平均值。想看动态功耗,最好用示波器加电流探头,或者用专门的功耗分析仪。我一开始用万用表测Stop模式电流,读数是30uA,后来用示波器看,发现唤醒瞬间有几百uA的尖峰,平均下来才是42uA。这个尖峰是MCU唤醒时时钟启动和I2C通信造成的,没法完全消除,但可以通过优化唤醒流程缩短尖峰持续时间。

4. 常见问题与排查技巧实录

4.1 I2C通信失败排查

I2C通信失败是这个方案里最常见的问题,表现是MCU读不到PCA9422的寄存器,或者写进去没反应。排查步骤:

  1. 检查硬件连接:SCL和SDA有没有接反?上拉电阻有没有焊?用万用表测SCL和SDA对VCC的电阻,应该是4.7k左右。如果电阻无穷大,说明上拉没接或者虚焊。
  2. 检查地址:PCA9422的7位地址是0x62,写操作时左移一位是0xC4,读是0xC5。用逻辑分析仪抓波形,看第一个字节是不是0xC4。如果发的是0x62,那肯定NACK。
  3. 检查时序:用示波器看SCL频率是不是400kHz,上升时间是不是在300ns以内。如果上升时间太长(比如超过1us),说明上拉电阻太大或者总线电容太大,需要减小上拉电阻。
  4. 检查电源:PCA9422的VDD引脚有没有电压?如果电池没接或者适配器没插,PCA9422可能不工作。有些PMIC需要先给VDD供电才能通信,PCA9422的VDD可以从电池取电,但电池电压太低(比如低于2.5V)时,内部LDO可能没起来,I2C也不响应。

我遇到过一次诡异的情况:I2C能读不能写。后来发现是写寄存器的时候没有等STOPF标志,直接发了下一个START,导致总线冲突。STM32的I2C外设在发送STOP后,要等STOPF置位才能发下一个START,不然会出问题。这个在HAL库里有处理,但用寄存器操作的时候容易漏。

4.2 充电器不工作或充电电流不对

充电器不工作的表现是:插上适配器,电池电压不上升,或者充电状态寄存器一直是0。排查:

  • NTC引脚:如果不用温度检测,NTC引脚要接10k电阻到地。如果悬空,充电器会认为温度异常,停止充电。
  • 充电电流配置:充电电流寄存器写的是50mA的倍数,写0x0A是500mA。但实际充电电流还受输入电流限制影响,如果适配器能力不足,充电器会自动降低电流。可以读输入电流限制寄存器确认。
  • 电池电压:如果电池电压低于2.5V,充电器进入预充模式,电流很小(比如50mA)。这是正常的,等电压升到2.5V以上就会切到恒流模式。
  • 热问题:充电电流大时,PCA9422会发热。如果结温超过150°C,充电器会过热保护,停止充电。摸一下芯片烫不烫,如果烫手,要么降低充电电流,要么改善散热。

4.3 低功耗模式唤醒失败

唤醒失败的表现是:MCU进入Stop模式后,按按键没反应,或者唤醒后程序跑飞。排查:

  • 唤醒源配置:EXTI的IMR、RTSR、FTSR要配置正确。比如PA0上升沿唤醒,IMR的bit0要置1,RTSR的bit0要置1,FTSR的bit0要清0。
  • 时钟配置:Stop模式下HSI是关的,唤醒后要重新使能HSI并等待稳定。如果唤醒后直接跑I2C初始化,可能因为时钟没稳定导致通信失败。我的做法是唤醒后先延时1ms,再初始化外设。
  • 电源状态:PCA9422在Stop模式下如果被配置成关断输出,MCU可能直接掉电,没法唤醒。所以进入Stop模式前,要确保PCA9422的Buck输出保持开启,只是降低电压。
  • 中断优先级:如果唤醒中断的优先级太低,可能被其他中断阻塞。建议把唤醒中断设成最高优先级。

避坑技巧:调试低功耗模式时,先把所有外设关掉,只留唤醒源,测最简系统的功耗。然后逐个打开外设,看哪个外设增加了功耗。这样能快速定位问题。我一开始没关I2C,Stop模式电流多了15uA,后来把I2C引脚配置成模拟输入,电流就降下来了。

4.4 常见问题速查表

现象可能原因解决方法
I2C NACK地址错误、上拉缺失、电源未上检查地址0xC4、上拉4.7k、VDD电压
充电电流小预充模式、输入限流、NTC悬空检查电池电压、适配器能力、NTC接10k
Stop模式电流大外设未关、引脚漏电、电压偏高关外设、引脚设模拟输入、降电压
唤醒后跑飞时钟未稳定、电源波动、中断冲突延时1ms、检查PCA9422状态、调优先级
Buck输出纹波大电感选型不当、输出电容小换2.2uH/2A电感、加10uF电容
芯片发热充电电流大、LDO压差大降充电电流、改用Buck供电

5. 方案优化与扩展思路

5.1 动态电压调节的进阶用法

前面提到STM32F303K8的内核电压没法外部调节,但外设电压可以。比如你挂了一个射频模块,它在发射时需要3.3V,接收时可以降到2.5V,休眠时断电。通过PCA9422的I2C接口,MCU可以在不同工作阶段动态调整LDO输出电压,甚至关掉某一路LDO。这个在无线传感器节点里很有用,射频模块的功耗占大头,动态调节能省不少电。

具体实现:在射频模块的驱动里加一个RF_SetPowerMode函数,根据当前模式写PCA9422的LDO寄存器。比如发射模式写0x6C(3.3V),接收模式写0x50(2.8V),休眠模式写0x00(关断)。注意写寄存器后要延时一段时间等电压稳定,一般100us到1ms,看负载电容大小。

5.2 电池电量计的实现

PCA9422没有内置库仑计,但可以通过读取电池电压和充电状态来估算电量。锂电池的放电曲线比较平,3.7V到3.4V之间对应大概60%到20%的电量,所以单纯看电压误差很大。我的做法是结合开路电压法和负载电压法:在MCU进入Sleep模式时,负载电流很小,这时候读电池电压比较准;在运行模式下,根据负载电流查表补偿。具体表格可以实测得到,用电子负载模拟不同电流,记录电压和电量的对应关系。

代码实现:

uint8_t Get_BatteryLevel(void) { uint16_t vbat = PCA9422_ReadReg(0x05); // 电池电压寄存器 uint16_t vbat_mv = vbat * 5; // 假设步进5mV uint8_t level; if (vbat_mv > 4100) level = 100; else if (vbat_mv > 3900) level = 80 + (vbat_mv - 3900) / 10; else if (vbat_mv > 3700) level = 50 + (vbat_mv - 3700) / 10; else if (vbat_mv > 3500) level = 20 + (vbat_mv - 3500) / 10; else if (vbat_mv > 3300) level = 5 + (vbat_mv - 3300) / 20; else level = 0; return level; }

这个表是粗略的,实际用的时候要根据电池型号和负载特性调整。另外,充电时电压会偏高,所以充电状态下不要用电量计,直接显示充电图标就行。

5.3 多路电源的时序控制

有些外设对上下电时序有要求,比如传感器要先上模拟电再上数字电,或者射频模块要先上IO电再上核心电。PCA9422的多路输出可以通过I2C按顺序使能,实现时序控制。具体做法:在初始化函数里,先写LDO1使能,延时1ms,再写LDO2使能,再延时1ms,最后写Buck使能。关断时反过来。

这个功能在调试的时候很有用,比如某路外设上电时电流冲击大,导致电池电压瞬间跌落,MCU复位。通过分时上电,可以减小冲击。我试过在射频模块上电时,先开LDO给IO供电,再开Buck给功放供电,冲击电流从500mA降到200mA,电池电压跌落从300mV降到100mV,效果很明显。

最后再分享一个小技巧:PCA9422的寄存器配置可以存在STM32的Flash里,每次上电时从Flash读取配置,通过I2C写入PCA9422。这样如果硬件改了,只需要更新Flash里的配置表,不用重新编译代码。配置表可以用结构体数组定义,每个元素包含寄存器地址和值,初始化时遍历数组写入。这个做法在量产时特别方便,不同批次的板子可能用了不同的电池或外设,只需要改配置表就行。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询