基于GreenPAK的数码管与键盘复用设计:3引脚实现高效人机交互
1. 项目概述:当数码管遇上键盘,如何用3个引脚搞定一切?
在搞嵌入式开发,尤其是那些对成本敏感、PCB空间金贵的消费电子产品时,最头疼的问题之一就是微控制器(MCU)的I/O口不够用。一个四位数码管要7个段选加4个位选,11个引脚;一个4x4矩阵键盘又要8个引脚(4行+4列)。加起来19个引脚,对于很多只有20来个I/O的8位MCU来说,几乎被榨干,其他传感器、通信接口就别想了。这时候,“复用”就成了救命稻草。但软件分时复用太吃CPU时间,反应慢了显示会闪烁,键盘响应会迟钝。有没有一种硬件级的、高效的复用方案呢?
这就是我们今天要拆解的核心:基于GreenPAK SLG46538V可编程器件的4位数码管与4x4键盘扫描复用设计。这个方案的精妙之处在于,它把最耗时的扫描和刷新逻辑,全部用硬件状态机(ASM)实现,MCU只需要通过I2C总线发送要显示的数据,或者读取被按下的键值。最终,MCU仅需占用3个引脚(I2C的SDA、SCL和一个中断引脚INT),就能同时管理显示和键盘输入。这不仅仅是省了几个引脚,更是把MCU从繁琐的周期性扫描任务中彻底解放出来,让它能专注于更上层的业务逻辑。无论是做个小型的电子密码锁、可编程定时器,还是简易的仪器仪表界面,这个架构都极具参考价值。
2. 核心设计思路与硬件选型解析
2.1 为什么选择GreenPAK?
GreenPAK(来自Renesas)是一系列基于非易失性存储器(NVM)的可编程混合信号器件。你可以把它理解为一个高度可定制、引脚级的“数字乐高”。它内部集成了大量的数字逻辑单元(查找表LUT、触发器DFF)、模拟模块(比较器、振荡器)、以及像异步状态机(ASM)、I2C/UART硬核这样的复杂功能块。它的核心价值在于“胶合逻辑”和“外设卸载”。在这个项目里,我们看中了它的几个关键特性:
- 双向I/O引脚(Bi-directional I/O Pins):这是实现复用的物理基础。同一个引脚,可以在不同时刻被配置为强推挽输出(驱动数码管阴极)或带上拉电阻的数字输入(读取键盘行线状态)。这个切换是由内部逻辑自动控制的,无需MCU干预。
- 异步状态机(ASM):这是整个设计的“大脑”。ASM是一个可编程的时序逻辑控制器,可以根据输入条件在不同的状态间跳转。我们用它来严格编排“显示刷新”和“键盘扫描”这两个任务的时间片,确保它们互不干扰。
- I2C通信硬核:提供了与MCU通信的标准、高效的通道。MCU通过它写入显示数据,读取键值。
- 高集成度与小封装:SLG46538V是3mm x 3mm的20引脚QFN封装,非常节省空间,成本也远低于使用多路逻辑芯片搭建的方案。
注意:选择PNP晶体管(如PMBT5401)作为数码管位选驱动是关键。因为我们的设计是共阳极数码管,段选信号(阴极)由GreenPAK引脚拉低点亮。位选控制则需要一个高电平有效的信号去打开晶体管,从而接通该位数码管的公共阳极电压。PNP晶体管在基极为低电平时导通,正好匹配GreenPAK引脚输出低电平来“选中”某一位数码管的逻辑。
2.2 系统架构与分时复用原理
整个系统的运作就像一场精心编排的双人舞,舞台(I/O引脚)只有一套,但两位舞者(数码管和键盘)轮流上场。
硬件连接拓扑:
- GreenPAK的8个复用引脚:PIN13, 16, 18, 19, 3, 5, 7, 10。这8个引脚被分成两组功能:
- 段选/列扫描线(Segment/Column):PIN13, 16, 18, 19。在显示模式,它们输出7段码中的a, b, c, d段(以及小数点dp,由其他引脚兼任);在键盘扫描模式,它们依次输出低电平脉冲,对键盘的4列进行扫描。
- 位选/行读取线(Digit/Row):PIN3, 5, 7, 10。在显示模式,它们经过晶体管驱动电路,依次输出低电平来选通4位数码管中的某一位;在键盘扫描模式,它们被切换为带上拉电阻的输入模式,用于读取键盘的4行状态。
- MCU接口:仅需连接GreenPAK的I2C引脚(SDA, SCL)和中断输出引脚(INT,本例中为PIN4)。
分时复用时序: 设计采用一个固定的时间片轮转机制,一个完整的周期约为9.7毫秒(约103Hz刷新率,人眼无闪烁感)。
- 显示刷新阶段(约8ms):在此阶段,ASM控制电路进入显示模式。8个复用引脚全部配置为输出。系统依次点亮4位数码管,每位点亮约2ms。利用人眼的视觉暂留效应,我们看到的是4位数同时稳定显示。
- 键盘扫描阶段(约1.7ms):显示阶段结束后,立即切换到键盘扫描模式。此时,PIN3,5,7,10被内部逻辑自动切换为带上拉的输入模式,准备读取。PIN13,16,18,19则依次输出一个低电平脉冲(每列约0.4ms),同时检测4个输入引脚的电平。如果某一行被拉低,说明该行与该列交叉点的按键被按下。
- 中断与数据交换:当键盘扫描阶段检测到有键按下时,GreenPAK会通过PIN4向MCU发出一个中断信号。MCU在中断服务程序中,通过I2C读取被锁存的键值。显示数据则是由MCU在任何时候通过I2C写入GreenPAK内部的显示缓冲区,由ASM在显示阶段自动循环取出并显示。
这种硬件自动化的分时复用,保证了显示无闪烁,键盘响应及时(最坏情况下的响应时间小于一个周期9.7ms),且MCU开销极低。
3. GreenPAK内部逻辑设计深度剖析
3.1 时钟与节拍生成
任何状态机都需要一个心跳。这里使用了两个时钟源:
- 显示刷新时钟:来自内部的RC振荡器(RC OSC),频率设为25kHz。然后经过一个24分频器,得到约1042Hz的时钟。再经过一个Pipe Delay(实际上是一个触发器实现的分频器)进行2分频,最终得到一个约521Hz的时钟信号。这个信号用于驱动显示相关的时序逻辑,包括控制ASM在4个显示位之间切换,以及同步一些数据锁存触发器(DFF0-DFF2)。
- 键盘扫描时钟:来自另一个振荡器OSC0。它的频率被设置为比显示时钟快得多(具体快4倍),以确保在分配给键盘扫描的约1.7ms时间内,能快速完成4列的扫描。OSC0的输出经过边沿检测器(EDGE DET0, DET1)产生短脉冲,用于触发ASM在键盘扫描的各个状态间跳转。
实操心得:时钟频率的选择是平衡显示效果和键盘响应速度的关键。显示刷新率(整个周期频率)建议保持在100Hz以上以避免闪烁。键盘扫描速度则要足够快,以防漏检快速按键。文中9.7ms的周期是个不错的起点。如果需要调整,可以通过GreenPAK Designer软件修改OSC0的预分频器(‘CLK’ predivider)和输出分频器(‘OUT0’ divider)的值,这两个参数可以通过I2C动态配置,非常灵活。
3.2 异步状态机(ASM)的编排
ASM是整个设计的核心控制器。我们可以将其状态大致划分为两个主区域:
- 状态0-3:显示控制状态。每个状态对应点亮一位数码管。ASM的输出(共8位)在这四个状态下,会根据MCU写入显示缓冲区的数据,通过连接矩阵输出不同的段码组合到复用引脚上。同时,会有一个特定的输出引脚(对应PIN6, 17, 15, 12,经晶体管驱动)输出低电平来选通当前位数码管。
- 状态4-7:键盘扫描状态。例如,状态4对应“扫描第1列”。在此状态下,ASM控制PIN13输出低电平(假设第1列),其他列引脚为高阻或高电平。同时,它会“监听”被配置为输入的4个行线(PIN3,5,7,10)的状态。状态5、6、7则依次扫描第2、3、4列。
ASM从一个状态跳转到下一个状态,是由前面提到的时钟节拍信号触发的。从状态3(显示最后一位)完成后,会通过一个条件跳转到状态4(开始键盘扫描),从而实现两个模式的自动切换。
3.3 显示数据存储与I2C写入
显示数据不是直接由ASM产生的,而是由MCU通过I2C写入的。GreenPAK内部有一个叫做“连接矩阵输出RAM”的存储区。对于4位数码管,每位数需要8个比特来控制7个段加1个小数点(实际可能用不到8位,但按字节对齐方便处理)。因此,MCU需要写入4个字节的数据。
I2C写入流程:
- MCU发起起始条件(Start)。
- 发送GreenPAK的I2C设备地址+写标志位(Control byte ‘0x00’)。
- 发送要写入的寄存器起始地址(Address byte)。这个地址指向显示缓冲区在连接矩阵RAM中的位置。
- 依次发送4个字节的显示数据(Data bytes)。每个字节的位0-6分别对应段a-g,位7对应小数点dp。例如,要显示数字“1”,需要点亮b和c段,则对应的字节数据为
0b00000110(假设低电平点亮,且a段为最低位)。 - MCU发起停止条件(Stop)。
写入后,这些数据会一直保存在GreenPAK的RAM中,ASM在每个显示周期会自动读取并输出,直到MCU写入新数据或器件断电。
3.4 键盘扫描与键值编码
键盘扫描的原理是“逐列扫描,读取行线”。
- 列扫描:在键盘扫描阶段,ASM依次让4个列线(复用引脚)中的一个输出低电平,其他三列保持高阻(或高电平)。
- 行读取:4个行线(复用引脚)此时已被配置为带上拉的输入。当没有按键按下时,读取到的都是高电平。如果某个按键被按下,而它所在的列正好被拉低,那么它所在的行线也会被拉低。
- 键值检测:当任意一个行输入变为低电平时,会触发一个检测电路(由4位查找表LUT0等构成),产生一个“有键按下”的标志信号。
- 键值编码:一旦检测到有键按下,需要确定是哪个键。此时,4条列扫描线的状态(哪一列为低)和4条行输入线的状态(哪一行为低)共同构成了一个8位的“坐标”。为了简化MCU的处理,GreenPAK内部使用一组3位查找表(LUT4-LUT9)对这个“坐标”进行编码,压缩成一个4位的二进制键值(0x0~0xF)。例如,第2行第3列的按键可能被编码为0x7。
- 键值锁存与中断:编码后的4位键值被锁存到一组D触发器(DFF3-DFF6)中保存。同时,“有键按下”标志会触发一个脉冲,从PIN4(中断引脚)输出,通知MCU。
- MCU读取:MCU收到中断后,发起I2C读操作。读的地址是固定的(例如Address byte ‘0xF1’)。读回的一个字节数据中,高4位就包含了刚才锁存的4位键值,低4位可能用作其他状态位或保留。
注意事项:按键去抖。机械按键在按下和释放的瞬间会产生物理抖动,导致在几毫秒内电平快速变化。这个设计将键盘扫描逻辑放在了硬件中,但去抖功能通常需要在MCU软件中实现。一种简单的做法是:MCU在收到中断后,延迟10-20ms再次读取键值,如果相同则确认为有效按键。更可靠的方法是在软件中实现状态机进行消抖处理。如果对实时性要求极高,也可以考虑利用GreenPAK内部的延迟或滤波器模块尝试在硬件层面进行初步消抖。
4. 电路搭建与器件选型实操指南
4.1 核心器件清单与参数
- 可编程器件:Renesas SLG46538V GreenPAK IC。这是整个方案的核心。
- 显示部分:
- 4位共阳极7段数码管(Common Anode 4-Digit 7-Segment LED Display)。注意必须是共阳极,因为我们的驱动电路设计如此。
- PNP晶体管 x 4:推荐PMBT5401。关键参数:集电极电流Ic需大于单个数码管所有段全亮时的总电流。假设每段LED电流5mA,7段全亮加小数点约40mA,PMBT5401的Ic连续电流可达600mA,绰绰有余。也可选用其他类似的通用PNP小信号晶体管,如2N3906。
- 基极电阻 x 4:用于限制流入GreenPAK引脚的电流。GreenPAK引脚输出低电平,电流从VCC经电阻、晶体管BE结到引脚。根据GreenPAK引脚的最大灌电流能力(查数据手册,通常约25mA)和晶体管需要的基极电流来计算。假设晶体管β值约100,需要驱动40mA集电极电流,则基极电流Ib约0.4mA。若VCC=5V,晶体管BE结压降约0.7V,则电阻R = (5V - 0.7V) / 0.0004A ≈ 10.75kΩ。为留有余量,选用10kΩ或12kΩ电阻是安全的。
- 段限流电阻 x 8:每个段引脚(a-g, dp)都需要一个限流电阻。阻值根据LED正向电压(Vf,通常约1.8-2.2V红/绿光)、电源电压(VCC)和期望的段电流(Iseg)计算。公式:R = (VCC - Vf - Vce_sat(晶体管)) / Iseg。假设VCC=5V, Vf=2.0V, Vce_sat=0.2V,期望Iseg=5mA,则R = (5 - 2.0 - 0.2) / 0.005 = 560Ω。常用330Ω-1kΩ之间,电阻越小越亮但功耗越大。
- 键盘部分:4x4矩阵薄膜键盘或机械按键键盘。无需额外元件,GreenPAK内部已配置上拉电阻。
- MCU接口:上拉电阻。I2C总线(SDA, SCL)需要外部上拉电阻,典型值为4.7kΩ或10kΩ,接至MCU和GreenPAK的共同逻辑电压(如3.3V或5V)。中断引脚(INT)如果MCU内部无上拉,也建议接一个上拉电阻(如10kΩ)。
- 电源:一个稳定的3.3V或5V电源,为GreenPAK、数码管、晶体管提供工作电压。需注意总电流需求,特别是4位数码管所有段全亮时的峰值电流。
4.2 电路连接详解
- GreenPAK与数码管连接:
- 段选线:GreenPAK的PIN13, 16, 18, 19, 3, 5, 7, 10(具体哪个引脚对应哪个段,由内部矩阵连接定义,设计时需在GreenPAK Designer中规划好)各通过一个段限流电阻连接到数码管对应的段引脚(a, b, c, d, e, f, g, dp)。注意,这里PIN3,5,7,10在显示模式下是段选功能。
- 位选线:GreenPAK的PIN6, 12, 15, 17(这4个引脚专用于位选控制,不复用)各通过一个基极电阻连接到对应PNP晶体管(Q1-Q4)的基极。晶体管的发射极接VCC(电源正极),集电极接对应位数码管的公共阳极(COM1-COM4)。
- GreenPAK与键盘连接:
- 列线:键盘的4根列线(C1-C4)分别连接到GreenPAK的PIN13, 16, 18, 19。注意:这4个引脚与数码管的段选线是共用的。
- 行线:键盘的4根行线(R1-R4)分别连接到GreenPAK的PIN3, 5, 7, 10。注意:这4个引脚与数码管的另外4段选线是共用的。
- GreenPAK与MCU连接:
- I2C:GreenPAK的SDA、SCL引脚分别接MCU的I2C数据线和时钟线,并各自通过上拉电阻接VCC。
- 中断:GreenPAK的PIN4(配置为中断输出)接MCU的一个外部中断输入引脚或普通GPIO(配置为输入模式)。
- 电源与地:VDD接3.3V/5V,VSS接地。
实操心得:PCB布局建议:
- 电源去耦:务必在GreenPAK的VDD和VSS引脚附近放置一个100nF的陶瓷电容,以滤除高频噪声。
- 电流路径:数码管的位选驱动电流较大(峰值可能超过100mA),确保从电源到晶体管再到数码管阳极的走线足够宽。
- 键盘走线:键盘连接线如果较长,考虑在GreenPAK的键盘输入引脚附近添加对地的小电容(如10pF-100pF)以增强抗干扰能力,防止误触发。
- 测试点:预留GreenPAK关键引脚(如复用引脚、中断引脚)的测试点,方便用示波器调试时序。
5. 软件配置与MCU端驱动开发
5.1 GreenPAK设计文件配置
所有硬件逻辑都是在GreenPAK Designer软件中图形化配置的。你需要从Renesas官网下载并安装该软件(免费),然后导入或重新创建本项目设计。
- 引脚配置:在软件中,将PIN3,5,7,10,13,16,18,19配置为“数字双向引脚”,并根据ASM的输出和内部矩阵连接,定义它们在显示和扫描模式下的具体行为。
- ASM配置:这是最复杂的部分。你需要定义8个状态(或更多,取决于具体设计),并为每个状态设置:
- 状态跳转条件:通常连接到显示时钟或扫描时钟的边沿信号。
- 输出值:每个状态下,ASM的8个输出位(连接到内部矩阵)应该是什么值。这些值决定了复用引脚在此时是输出高/低电平(显示),还是准备输入(扫描),以及具体输出哪个段码或列扫描信号。
- 时钟配置:配置RC OSC和OSC0的频率和分频,以达到约9.7ms的总周期。
- I2C配置:设置GreenPAK的I2C从设备地址(默认为0x00,但7位地址通常是0x00右移一位?这里需仔细查数据手册,原文中控制字节0x00是写,0x01是读,这更像是包括读写位在内的8位控制字)。配置好连接矩阵输出RAM的映射地址,以便MCU访问。
- 键值编码逻辑:使用3位LUT(LUT4-LUT9)组合,将8位的行列状态编码成4位键值。这需要根据你的键盘实际连接,真值表。
完成设计后,使用GreenPAK编程器(如Silego GreenPAK POD)将配置文件烧录到SLG46538V芯片中。
5.2 MCU端驱动程序要点
MCU端的代码相对简单,主要任务是I2C通信和中断处理。
初始化:
- 初始化MCU的I2C外设。
- 配置连接GreenPAK中断引脚(PIN4)的MCU引脚为输入模式,并使能下降沿(或低电平)中断。
- (可选)通过I2C向GreenPAK写入初始显示数据,如全灭或显示“----”。
显示函数: 编写一个函数,接收一个包含4个数字/字符的数组,将其转换为7段码表,然后通过I2C写入GreenPAK的显示缓冲区。
中断服务程序(ISR): 当MCU检测到来自GreenPAK的中断引脚下降沿时,进入中断。
- 清除中断标志(如果是边沿触发)。
- 延迟一小段时间(如15ms)进行软件去抖。
- 通过I2C读取键值寄存器(地址0xF1)。
- 从读取的字节中提取高4位,即为按键编码(0x0-0xF)。
- 根据你的应用逻辑,将这个键值转换为具体的功能(数字、确认、取消等)。
- (重要)处理完键值后,中断条件可能依然存在,需要确保MCU能准备接收下一次中断。有些设计需要在MCU读取键值后,GreenPAK内部逻辑才会清除中断标志,具体需看设计。
主循环: 主循环可以完全不用关心显示刷新和键盘扫描,只需在需要更新显示时调用显示函数,在中断中处理按键即可。这极大简化了主程序逻辑。
6. 调试技巧与常见问题排查
即使设计再完美,调试阶段也总会遇到问题。以下是一些实战中总结的排查思路。
6.1 显示问题排查
| 现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 所有数码管完全不亮 | 1. 电源未接通或电压不对。 2. GreenPAK未正确编程或未工作。 3. 位选晶体管全部未导通。 |
1. 测量VCC电压,检查GreenPAK VDD引脚电压。 2. 用编程器验证芯片是否已编程。检查OSC是否起振(可用示波器测时钟相关引脚)。 3. 用万用表测量位选控制引脚(PIN6,12,15,17)在显示期间是否有低电平脉冲输出。测量晶体管基极电压。 |
| 只有某一位不亮 | 1. 该位数码管损坏或焊接问题。 2. 对应的位选晶体管或基极电阻损坏。 3. GreenPAK对应位选引脚无输出。 |
1. 交换数码管测试。 2. 检查该路晶体管、电阻的焊接和值。 3. 用示波器查看该位选引脚在对应时间段是否有低电平脉冲。 |
| 某一段在所有位都不亮 | 1. 该段对应的GreenPAK引脚到数码管之间的限流电阻开路或焊接问题。 2. GreenPAK内部该段输出逻辑错误。 |
1. 检查该段限流电阻通路。 2. 用示波器查看该段引脚(如PIN13对应段a)在显示不同数字时的波形是否正确。对比ASM中该段的输出定义。 |
| 显示乱码或数字错误 | 1. 段码数据转换错误(MCU软件问题)。 2. GreenPAK内部连接矩阵RAM映射错误。 3. I2C写入地址或数据顺序错误。 |
1. 确认digit_to_7seg转换表正确,特别是小数点处理。2. 在GreenPAK Designer中检查ASM各状态输出与引脚连接的映射关系。 3. 用逻辑分析仪抓取I2C总线数据,核对写入的地址和数据是否符合预期(参考原文图6)。 |
| 显示闪烁或暗淡 | 1. 刷新频率过低(低于60Hz)。 2. 每位点亮时间太短或段电流太小。 3. 电源驱动能力不足。 |
1. 用示波器测量显示周期,调整OSC分频提高刷新率。 2. 适当减小段限流电阻,增加亮度。检查晶体管饱和压降是否过大。 3. 测量数码管全亮时电源电压是否被拉低。 |
6.2 键盘扫描问题排查
| 现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 所有按键无反应 | 1. 键盘扫描模式未启动或时序错误。 2. GreenPAK中断引脚(PIN4)未连接或配置错误。 3. MCU中断未正确配置。 |
1. 用示波器观察复用引脚在“键盘扫描阶段”是否有列扫描脉冲(低电平依次出现)。观察行输入引脚是否被正确切换为输入模式(高电平)。 2. 测量PIN4在按下按键时是否有脉冲输出。 3. 检查MCU中断引脚配置、使能及中断服务程序是否注册。 |
| 某一行或某一列按键全部失灵 | 1. 对应的行线或列线连接断开。 2. GreenPAK对应引脚损坏或内部逻辑错误。 3. 键盘本身行列线断路。 |
1. 检查PCB走线和焊接。 2. 在扫描模式下,用示波器检查失灵列对应的引脚是否有扫描脉冲,失灵行对应的引脚在按下该行其他键时是否能被拉低。 3. 用万用表通断档检查键盘薄膜或按键PCB。 |
| 单个按键失灵 | 1. 该按键接触不良(氧化或损坏)。 2. 行列交叉点焊接问题。 |
1. 更换按键或使用清洁剂。 2. 检查交叉点通断。 |
| 按键连击或反应不稳定 | 1. 按键抖动,软件去抖不充分。 2. 扫描速度过快或过慢,导致信号不稳定。 3. 电路噪声干扰。 |
1. 增加MCU软件去抖的延时时间,或采用更稳定的状态机去抖算法。 2. 调整OSC0的频率,改变扫描周期。 3. 检查电源稳定性,在键盘输入引脚加小电容滤波,确保信号地线良好。 |
| 读取的键值错误 | 1. GreenPAK内部键值编码LUT配置错误。 2. I2C读取地址或数据解析错误。 3. 行列连接与ASM/LUT预期顺序不匹配。 |
1. 在GreenPAK Designer中仔细核对LUT4-LUT9的真值表,确保每个按键的8位行列状态组合能正确映射到4位编码。 2. 用逻辑分析仪捕获I2C读操作,确认读取的地址(0xF1)和数据字节,核对高4位。 3. 系统化测试:依次按下每个键,记录MCU读到的值,与预期编码表对比,找出映射错误规律。 |
6.3 I2C通信问题排查
如果显示和键盘完全没反应,很可能是I2C通信没建立。
- 工具:一个USB逻辑分析仪(如Saleae)是必备的,可以同时抓取SDA和SCL信号。
- 查什么:
- 起始信号:MCU是否发出了Start条件?
- 设备地址:发送的7位从机地址(或8位控制字)是否正确?SLG46538V的地址需要查数据手册确认,并注意读写位。
- 应答:GreenPAK是否在每个字节后回复了ACK?
- 数据:写入显示缓冲区的数据是否正确?读取键值时的地址和数据是否正确?
- 上拉电阻:SDA和SCL线上的上拉电阻是否已接?阻值是否合适(通常4.7kΩ-10kΩ)?
- 电压电平:MCU和GreenPAK的IO电平是否兼容(同为3.3V或5V)?
调试是一个系统性的过程,从电源开始,到时钟,再到核心功能模块。按照“电源 -> 时钟 -> 基本输出(如固定显示)-> 复杂逻辑(复用切换)-> 输入(键盘)-> 通信(I2C)”的顺序进行,可以更快地定位问题所在。这个基于GreenPAK的复用方案,将复杂的时序逻辑硬件化,虽然前期设计需要一些精力,但一旦调试成功,其稳定性和对MCU资源的节省效果是非常显著的,特别适合在需要精简BOM和PCB空间的产品中批量应用。