
1. 项目概述与LCD模块核心价值在嵌入式系统尤其是便携式、电池供电的设备开发中LCD显示是一个既常见又充满挑战的环节。它直接关系到用户体验和产品的功耗表现。很多开发者初次接触MCU的LCD模块时往往会被一堆寄存器、复杂的时序和偏压设置搞得晕头转向要么是显示乱码要么是功耗居高不下。我最近在几个基于TI MSPM0 L系列微控制器的低功耗仪表项目里深入折腾了它的LCD模块发现其设计相当精巧但手册上的信息比较分散实际配置起来有不少门道。MSPM0 L系列的LCD控制器是一个高度集成的模块它最大的亮点是在极低的功耗下直接驱动段码式LCD玻璃无需额外的驱动芯片。这对于成本敏感且对续航有严苛要求的应用比如水表、气表、便携医疗设备、温控器等是巨大的优势。它支持从静态到8路复用8-MUX的多种驱动方式内置电荷泵可以生成LCD所需的偏压电压还支持段闪烁、内存切换显示等高级功能。但要把这些功能都调通、调稳关键在于吃透那二十几个寄存器。本文将从一个实际开发者的角度带你逐层拆解MSPM0 L系列LCD模块的寄存器不仅告诉你每个位是干什么的更会分享如何组合配置它们来实现稳定、低功耗的显示并避开那些我亲自踩过的“坑”。2. LCD模块整体架构与寄存器地图解析在深入每个寄存器之前我们需要先建立对MSPM0 LCD模块整体架构的认知。这个模块并非一个简单的GPIO模拟而是一个拥有独立时序发生器、内存管理和电压生成电路的完整显示控制器。2.1 模块功能框图与数据流虽然数据手册中的框图很详细但我们可以从数据流的角度来理解它。整个过程可以概括为显示数据从LCDM[y]或LCDBM[y]内存寄存器中取出经过LCD控制逻辑根据LCDCTL0等寄存器设置的复用模式、频率和偏压转换成特定的电压波形最终通过被配置为LCD功能的引脚输出到LCD玻璃上。这里有几个关键角色显示内存LCDM[y]/LCDBM[y]这是核心。你可以把它想象成一个位图bitmap每一位对应一个LCD段Segment的亮灭。但需要注意的是这个映射关系不是简单的1对1而是与复用模式MUX和引脚配置COM/SEG紧密相关。时序与控制单元主要由LCDCTL0、LCDBLKCTL等寄存器控制。它负责产生帧同步信号、COM/SEG扫描时序以及闪烁时钟。LCDDIVx和LCDMXx位就在这里配置决定了刷新率和复用路数。电压生成单元由LCDVCTL寄存器主导。LCD需要多级电压如V1, V2, V3, V4来驱动以避免直流分量损坏液晶。这个单元可以通过内部电荷泵或电阻分压网络来产生这些偏压LCDCPEN、LCDINTBIASEN、VLCDx等位的配置直接影响功耗和显示对比度。引脚复用与配置单元涉及LCDPCTL0-3和LCDCSSEL0-3寄存器。MSPM0的LCD引脚与GPIO复用你需要先用LCDPCTLx使能引脚的数字LCD功能再用LCDCSSELx指定该引脚是作为公共端COM还是段端SEG。2.2 寄存器地图概览与访问逻辑MSPM0的LCD寄存器是内存映射的这意味着你可以像操作普通变量一样通过指针或底层驱动库来读写它们。所有寄存器都是32位宽但很多只使用了其中的一部分位。为了方便查阅和编程我习惯将寄存器分为以下几类并整理成表格寄存器类别寄存器名称 (偏移地址)核心功能简述模块使能与复位PWREN(0x800)模块电源使能需要密钥解锁RSTCTL(0x804)模块复位控制需要密钥解锁STAT(0x814)模块状态如复位粘滞位中断管理IIDX(0x1020)最高优先级中断索引IMASK(0x1028)中断掩码使能RIS(0x1030)原始中断状态MIS(0x1038)被屏蔽的中断状态ISET(0x1040)软件置位中断ICLR(0x1048)软件清除中断EVT_MODE(0x10E0)事件线模式选择核心控制LCDCTL0(0x1100)总开关、MUX模式、频率分频、低功耗波形LCDBLKCTL(0x1108)闪烁模式与频率控制LCDMEMCTL(0x110C)显示内存控制清除、选择电压与偏置控制LCDVCTL(0x1110)核心电荷泵、偏压模式、参考电压、VLCD选择LCDVREFCFG(0x1DFC)VREF开启时间配置引脚功能配置LCDPCTL0-3(0x1114-0x1120)使能具体引脚的LCD数字功能LCDCSSEL0-3(0x1128-0x1134)配置引脚为COM或SEG显示内存LCDM[y](0x1140 y)主显示内存y0~63LCDBM[y](0x1180 y)闪烁显示内存y0~31注意访问PWREN和RSTCTL寄存器需要先向KEY字段写入特定的解锁密钥PWREN.KEY0x26,RSTCTL.KEY0xB1这是为了防止软件意外开关模块或复位。这是一个重要的安全机制在初始化流程中必须严格遵守。3. 核心控制寄存器详解与配置策略这一部分是LCD驱动的“大脑”配置是否正确直接决定了显示能否正常工作以及基本性能。3.1 LCDCTL0全局控制与时钟配置LCDCTL0寄存器是LCD模块的“总闸门”和“节奏器”。LCDON (Bit 0)这是LCD模块的总开关。务必在配置完所有其他参数尤其是时钟和电压后最后才将其置1。在修改LCDDIVx或LCDMXx时也必须先将其清零。LCDLP (Bit 1)低功耗波形选择。仅当在LCDVCTL中选择了1/3偏压LCDBIASSEL0时才有效。启用后COM和SEG线上的波形会得到优化以降低功耗但可能会牺牲一些对比度或响应速度。在电池供电应用中如果对比度可接受建议开启。LCDSON (Bit 2)段输出使能。这是一个非常实用的功能特别是实现“全屏熄灭但保持驱动电路活动”的场景。当LCDSON0时所有段输出被关闭显示空白但LCD时序发生器、电荷泵等仍在工作。这比反复开关LCDON更快速适用于需要频繁切换显示内容但不想重新初始化LCD的场合。LCDMXx (Bits 5-3)复用模式选择。这是连接硬件设计的关键。000: 静态 (Static) – 每个COM线独立驱动无复用。用于极少段数的简单显示。001: 2路复用 (2-MUX) – 最常用模式之一COM0和COM1分时驱动。010: 3路复用 (3-MUX)011: 4路复用 (4-MUX) – 最常用模式之一平衡了引脚数和驱动复杂度。100-111: 5至8路复用 – 用于驱动更复杂的段码屏但软件配置和内存映射会更复杂。选择依据完全由你使用的LCD玻璃的硬件连接决定。必须查阅LCD数据手册或原理图。LCDDIVx (Bits 15-11)LCD时钟分频器。它与LCDMXx共同决定帧频率f_FRAME。公式f_LCD f_SOURCE / ((LCDDIVx 1) * ValueLCDMXx)。其中f_SOURCE通常是内部低速时钟如32.768kHzValueLCDMXx是复用路数Static1 2-MUX2 以此类推。目标帧率通常设置在30Hz至100Hz之间。低于30Hz可能产生肉眼可见的闪烁高于100Hz则会不必要地增加功耗。例如使用32.768kHz时钟源4-MUX模式目标帧率60Hzf_LCD 60Hz * 4 240Hz。LCDDIVx 32768 / 240 - 1 ≈ 135但LCDDIVx最大值为31分频32。这说明在低时钟源下高帧率和高复用数可能无法同时满足需要权衡使用更高频率的时钟源。配置示例4-MUX 约64Hz帧频使用32.768kHz时钟// 假设寄存器基地址为 LCD_BASE HW_REG(LCD_BASE LCD_O_CTL0) (0x07 11) | // LCDDIVx 7, 即分频8。 f_LCD 32768 / ((71)*4) 1024 Hz (0x03 3) | // LCDMXx 3, 即4-MUX。 ValueLCDMXx4 (0x0 2) | // LCDSON 0, 初始关闭段输出 (0x0 1) | // LCDLP 0, 初始使用标准波形 (0x0 0); // LCDON 0, 先不开启模块 // 计算实际帧频 f_FRAME f_LCD / ValueLCDMXx 1024 / 4 256 Hz。这个值偏高功耗会大。 // 更合理的设置LCDDIVx 31分频32则 f_LCD 32768/(32*4)256Hz f_FRAME64Hz。3.2 LCDBLKCTL闪烁功能控制闪烁功能可以用来吸引用户注意或者实现简单的动画效果。LCDBLKCTL寄存器控制其行为。LCDBLKMODx (Bits 1-0)闪烁模式。00禁用闪烁。01独立段闪烁。这是最常用的模式。闪烁由LCDBM[y]内存寄存器控制只有LCDBM[y]中对应位为1的段才会参与闪烁。这允许你精确控制哪些段闪烁。10全屏闪烁。所有显示的段一起闪烁。11内存切换。显示内容在LCDM[y]和LCDBM[y]之间交替显示。可以用于实现两个不同画面的交替显示类似于简单的动画。重要限制数据手册明确指出在5-MUX及更高复用模式下闪烁功能是禁用的。如果你的屏是4-MUX或更低可以放心使用。LCDBLKPREx (Bits 4-2)闪烁时钟预分频。它基于f_LCD进行分频产生闪烁频率f_BLINK f_LCD / (2^(LCDBLKPREx1))。例如LCDBLKPREx0(分频2)f_LCD256Hz则f_BLINK128Hz闪烁太快人眼无法分辨。通常设置为4(分频32)或5(分频64)以获得1-2Hz的舒适闪烁频率。配置示例启用独立段闪烁频率约1Hz// 假设 f_LCD 已配置为 256 Hz // 期望闪烁频率 f_BLINK 1 Hz // 所需分频比 f_LCD / f_BLINK 256 // 查找 LCDBLKPREx 分频值 2^(LCDBLKPREx1) // 若 LCDBLKPREx7 分频值256 符合。 HW_REG(LCD_BASE LCD_O_BLKCTL) (0x07 2) | // LCDBLKPREx 7 分频256 (0x01 0); // LCDBLKMODx 01 独立段闪烁模式3.3 LCDMEMCTL显示内存操作这个寄存器提供了对显示内存的批量操作和显示源选择。LCDDISP (Bit 0)显示源选择。当LCDBLKMODx00无闪烁时软件可以自由切换该位来选择显示LCDM[y](0)还是LCDBM[y](1)的内容。这在需要快速切换两套显示内容如正常界面和菜单界面时非常有用避免了频繁重写内存。LCDCLRM (Bit 1)和LCDCLRBM (Bit 2)清除内存位。向这些位写1可以一次性清除所有LCDM[y]或LCDBM[y]寄存器。这个操作是自清除的硬件会在完成清除后自动将该位拉回0。在初始化时用这个功能快速清屏比用循环写64个寄存器效率高得多。注意LCDCLRBM在5-MUX及以上模式无效这是由硬件限制决定的。4. 电压、偏置与引脚配置的深入实践这是LCD驱动中最容易出问题也最影响显示质量和功耗的部分。4.1 LCDVCTL电压与偏置系统核心LCDVCTL寄存器掌管着为LCD玻璃产生合适驱动电压的整个模拟前端。LCDREFMODE (Bit 0)参考电压模式。选择R13引脚上的电压是静态0还是切换1模式。对于大多数内部偏置的应用选择静态模式0即可。LCDBIASSEL (Bit 1)偏压选择。0为1/3偏压1为1/4偏压。这必须严格匹配LCD玻璃的规格。1/4偏压通常能提供更好的对比度和更宽的视角但功耗略高。同样在5-MUX及以上模式才需要关注此设置。LCDINTBIASEN (Bit 2)内部偏置使能。这是关键位。如果置1则启用MCU内部的电阻分压网络来产生LCD所需的V1-V4偏压无需外部电阻节省成本和空间。绝大多数应用都应启用此位设为1。VLCDSEL_VDD_R33 (Bit 3)当LCDINTBIASEN1时此位选择内部电阻分压网络的最高电压源。0来自R33引脚外部提供1来自内部AVDD。为了简化设计通常选择内部AVDD设为1。LCD_HP_LP (Bit 4)高低功耗波形选择仅LCDINTBIASEN1且LCDBIASSEL0时有效。低功耗波形0可进一步降低功耗但驱动能力较弱可能影响对比度尤其在低温下。需要根据实际显示效果和功耗测试来决定。LCDSELVDD (Bit 5)选择R33引脚电压来源。0来自外部1内部连接到AVDD。如果使用内部偏置且VLCD由内部提供此位通常设为1。LCDREFEN (Bit 6)内部参考电压使能。如果使用内部偏置通常需要使能设为1。LCDCPEN (Bit 7)电荷泵使能。当LCD工作电压VLCD高于芯片供电电压AVDD时必须启用电荷泵来升压。是否启用取决于VLCDx的设置和AVDD电压。VLCDx (Bits 11-8)LCD电压等级设置。这个4位字段定义了R33引脚上的电压VLCD相对于内部参考电压的倍数是调节显示对比度的最关键参数。公式手册给出对于1/3偏压R33 3 * [1/3 Bias Mode Voltage]对于1/4偏压R33 4 * [1/4 Bias Mode Voltage]。这里的“Bias Mode Voltage”就是LCD玻璃数据手册上要求的驱动电压通常叫V_LCD。计算示例假设LCD玻璃要求V_LCD 3.0V我们使用1/3偏压。所需R33电压 3 * 3.0V 9.0V。如果AVDD3.3V那么9.0V 3.3V必须启用电荷泵(LCDCPEN1)。VLCDx的值决定了电荷泵的倍压比例。需要查阅器件数据手册中关于电荷泵输出电压与VLCDx关系的表格来选择合适的值。通常它是一个线性或分段线性的关系。LCDCPFSELx (Bits 15-12)电荷泵时钟频率选择。频率越低功耗越小但电荷泵的响应速度和驱动能力也越弱。需要在功耗和电压稳定性间折衷。通常使用默认值或较低频率即可。LCDVBSTEN (Bit 24)电压增压电路使能。当VDDA模拟供电低于1.6V时需要使能此功能来为开关控制电路提供一个升压的VDDA确保内部开关能正常导通。在常规3.3V或1.8V供电下通常不需要开启。配置示例3.3V系统驱动3.0V LCD使用内部1/3偏压// 假设经过查表或计算VLCDx0xE (14) 对应所需的输出电压 // 假设电荷泵频率选择默认值 0x0 HW_REG(LCD_BASE LCD_O_VCTL) (0x00 24) | // LCDVBSTEN 0 VDDA1.6V 不使能 (0x00 16) | // 保留位 (0x00 12) | // LCDCPFSELx 0 电荷泵频率 ~4.1kHz (0x0E 8) | // VLCDx 0xE 根据数据手册表格选择 (0x1 7) | // LCDCPEN 1 使能电荷泵因为需要升压 (0x1 6) | // LCDREFEN 1 使能内部参考 (0x1 5) | // LCDSELVDD 1 R33内部接AVDD (0x0 4) | // LCD_HP_LP 0 使用低功耗波形先尝试 (0x1 3) | // VLCDSEL_VDD_R33 1 内部偏置源选AVDD (0x1 2) | // LCDINTBIASEN 1 使能内部偏置 (0x0 1) | // LCDBIASSEL 0 1/3偏压根据LCD玻璃定 (0x0 0); // LCDREFMODE 0 静态参考模式4.2 脚配置LCDPCTLx 与 LCDCSSELx这是连接软件和物理硬件的桥梁配置错误会导致无显示或显示错乱。第一步使能LCD引脚功能 (LCDPCTL0-3)。 每个位如LCDS0对应一个物理引脚Lx。将该位置1则该引脚的数字功能被配置为LCD驱动。即使某个引脚被硬件设计为专用LCD引脚也建议在软件中将其使能以保证一致性。例如如果你使用了L0~L15则需要设置LCDPCTL0的低16位。第二步分配COM和SEG (LCDCSSEL0-3)。 这是最关键也是最容易出错的一步。每个位决定对应引脚是作为段线SEG 位0还是公共端COM 位1。COM线的数量必须等于你选择的复用模式MUX。例如4-MUX需要4个COM线COM0~COM3。硬件连接必须已知你必须清楚你的LCD玻璃的每个段比如数字“8”的a、b、c...段具体连接到了哪个MCU引脚以及这个引脚被定义为COM还是SEG。这需要原理图或LCD玻璃手册。配置规则在LCDCSSELx寄存器中将用作COM的引脚对应位置1用作SEG的置0。配置示例4-MUX使用L0~L3作为COM0~COM3 L4~L19作为SEG0~SEG15// 使能 L0~L19 的LCD功能 HW_REG(LCD_BASE LCD_O_PCTL0) 0x000FFFFF; // 低20位置1使能L0~L19 // 配置 L0~L3 为COM L4~L19为SEG // LCDCSSEL0 控制 L15~L0 uint32_t cssel0_val 0; cssel0_val | (1 0); // L0 as COM0 cssel0_val | (1 1); // L1 as COM1 cssel0_val | (1 2); // L2 as COM2 cssel0_val | (1 3); // L3 as COM3 // L4~L15 默认就是0作为SEG HW_REG(LCD_BASE LCD_O_CSSEL0) cssel0_val;5. 显示内存映射与段码编程实战配置好引脚和COM/SEG后如何让特定的段亮起或熄灭这就需要理解LCDM[y]内存寄存器与物理引脚、COM/SEG的映射关系。这是整个LCD驱动中最需要逻辑思维的部分。5.1 内存映射规则解析LCDM[y]寄存器不是简单地按引脚顺序排列。它的映射规则由复用模式MUX决定并且巧妙地利用了每个寄存器的8个位MBIT0~MBIT7来对应不同COM线上的状态。规则总结如下对于4-MUX及以下模式Static, 2, 3, 4-MUX每个LCDM[y]寄存器管理两个LCD引脚L[2*y]和L[2*y1]。每个引脚无论它是COM还是SEG在该寄存器中占用4个位MBIT0~3或MBIT4~7。位到COM的映射MBIT0-COM0MBIT1-COM1MBIT2-COM2MBIT3-COM3对于引脚L[2*y]使用MBIT0~3对于引脚L[2*y1]使用MBIT4~7。如何点亮一个段假设段Sx连接在引脚Lp配置为SEG和COMq上。找到管理引脚Lp的寄存器LCDM[y]。如果p是偶数y p/2使用该寄存器的低4位MBIT0~3如果p是奇数y (p-1)/2使用该寄存器的高4位MBIT4~7。将对应COMq的位设置为1。对于5-MUX至8-MUX模式每个LCDM[y]寄存器只管理一个LCD引脚L[y]。该引脚在该寄存器中占用8个位MBIT0~7分别对应COM0~COM7。如何点亮一个段假设段Sx连接在引脚LpSEG和COMq上。找到寄存器LCDM[p]。将MBITq位设置为1。5.2 编程示例与辅助函数为了简化操作强烈建议编写或使用现成的驱动库并提供将“引脚号COM号”转换为内存位操作的函数。示例4-MUX模式下点亮连接在L4SEG和COM1上的段/** * brief 在4-MUX模式下设置特定段的状态 * param seg_pin: 段线引脚编号 (如 4) * param com: 公共端编号 (0-3) * param state: 0熄灭 1点亮 */ void LCD_SetSegment_4MUX(uint8_t seg_pin, uint8_t com, bool state) { uint32_t reg_index; uint8_t bit_offset; volatile uint32_t *mem_reg; // 1. 计算寄存器索引和位偏移 if (seg_pin % 2 0) { // 偶数引脚使用低4位 (MBIT0-3) reg_index seg_pin / 2; bit_offset com; // MBIT0对应COM0 以此类推 } else { // 奇数引脚使用高4位 (MBIT4-7) reg_index (seg_pin - 1) / 2; bit_offset com 4; // MBIT4对应COM0 MBIT5对应COM1... } // 2. 获取寄存器地址 mem_reg (volatile uint32_t *)(LCD_BASE LCD_O_MEMORY reg_index); // 3. 设置或清除位 if (state) { *mem_reg | (1UL bit_offset); } else { *mem_reg ~(1UL bit_offset); } } // 调用示例点亮 L4-COM1 LCD_SetSegment_4MUX(4, 1, true);清屏与批量更新 对于需要更新大量段码的情况如刷新一个多位数字直接操作LCDM[y]寄存器效率最高。你可以先在一个内存中的缓冲区数组里构建好整个显示帧的位图然后一次性用memcpy或循环写入到LCDM[y]寄存器组中。LCDMEMCTL中的LCDCLRM位可以用于快速清空显示内存。6. 中断与低功耗管理LCD模块的中断主要用于同步和节能。6.1 中断源与应用FRMSTART帧开始中断。每开始刷新新的一帧时触发。可以用于在帧开始时同步更新显示数据双缓冲避免刷新过程中修改内存导致显示撕裂。BLKON/BLKOFF闪烁开启/关闭中断。在闪烁功能启用时每次闪烁状态切换时触发。可以用于在闪烁时执行其他任务或者实现更复杂的闪烁模式如闪烁几次后停止。配置中断示例// 使能帧开始中断 HW_REG(LCD_BASE LCD_O_IMASK) | (1 0); // FRMSTART 掩码位置1 // 在中断服务函数(ISR)中 void LCD_IRQHandler(void) { uint32_t int_idx HW_REG(LCD_BASE LCD_O_IIDX) 0xFF; if (int_idx 0x01) { // FRMSTART 中断索引 // 在此处安全地更新 LCDM[y] 数据双缓冲切换 // ... // 清除中断标志 HW_REG(LCD_BASE LCD_O_ICLR) (1 0); } }6.2 低功耗模式下的操作根据数据手册LCD模块在除SHUTDOWN模式外的所有低功耗模式下均可运行。这意味着在SLEEP或STANDBY模式下LCD可以保持显示仅消耗极低的电流。关键步骤是在进入低功耗模式前确保LCD模块已正确配置并运行稳定。配置系统时钟使LCD时钟源通常是LFCLK在低功耗模式下保持活动。在进入低功耗模式的代码中不要关闭LCD模块的电源或时钟。唤醒后LCD显示应保持不变。如果需要更新显示最好在唤醒后、再次进入低功耗前进行。一个常见的优化是在长时间无操作时使用LCDSON0关闭段输出显示空白但保持LCD模块上电这样在需要显示时可以瞬间恢复比完全关闭再初始化快得多功耗也远低于维持显示。7. 常见问题排查与调试心得在实际项目中我遇到了不少问题这里总结一下无任何显示检查电源和使能确认PWREN.ENABLE1LCDON1LCDSON1。检查时钟确认LCD时钟源如LFCLK已启用且运行正常。检查LCDDIVx计算确保帧频率在合理范围30-100Hz。检查电压用万用表测量R33、R13等引脚电压。确认VLCDx设置是否正确电荷泵是否使能如果需要。对比度电压不足是最常见的原因。检查引脚配置确认LCDPCTLx已使能所用引脚LCDCSSELx的COM/SEG分配与硬件连接完全一致。一个COM/SEG配错就会导致整片区域不显示。显示乱码或鬼影检查偏压和MUX模式确认LCDBIASSEL1/3或1/4偏压与LCD玻璃规格匹配。确认LCDMXx复用模式与硬件COM线数量匹配。检查内存映射这是最复杂的部分。再次核对你编写的段码设置函数确保LCDM[y]中每一位的设置都正确对应了引脚-COM的关系。建议编写一个测试函数依次点亮每一个段来验证映射关系。检查初始化顺序正确的顺序是配置引脚(LCDPCTLx,LCDCSSELx) - 配置电压/偏置(LCDVCTL) - 配置时钟和模式(LCDCTL0但LCDON0) - 清空显示内存(LCDMEMCTL.CLR) - 最后使能模块(LCDCTL0.LCDON1)。功耗过高降低帧频率增大LCDDIVx降低f_LCD和f_FRAME。在满足无闪烁的前提下帧频越低越好。启用低功耗波形如果使用1/3偏压尝试设置LCDLP1。优化电荷泵频率尝试提高LCDCPFSELx的值以降低电荷泵频率。关闭不用的功能如果不使用闪烁确保LCDBLKMODx00。闪烁功能不正常确认复用模式闪烁在5-MUX及以上模式不可用。检查闪烁内存在独立段闪烁模式(01)下只有LCDBM[y]中置1的段才会闪烁。你需要正确设置LCDBM[y]。检查闪烁频率LCDBLKPREx设置可能过大或过小导致闪烁太快看不见或太慢像没反应。计算一下f_BLINK。调试建议充分利用MCU的GPIO。在初始化阶段可以用GPIO翻转来标记代码执行到了哪里。用示波器测量一个COM或SEG引脚应该能看到规则的多电平阶梯波形。如果没有波形说明数字部分未工作如果波形幅度不对或形状怪异说明模拟偏压部分有问题。