TMS320VC5409A DSP内存架构与外设实战解析

1. 项目概述与核心价值

在嵌入式信号处理领域,选对一颗“芯”往往意味着项目成功了一半。今天要聊的TMS320VC5409A,是TI C5000平台上一颗非常经典且应用广泛的定点数字信号处理器。我接触这颗芯片超过十年,从早期的语音编解码器到后来的通信基带处理,它都扮演着核心角色。很多工程师拿到芯片手册,看到密密麻麻的内存映射图和寄存器描述,第一反应往往是头大——32K DARAM、OVLY位、XPC寄存器、McBSP、HPI……这些术语背后到底意味着什么?如何把它们用起来,而不是让芯片的性能躺在数据手册里睡大觉?

这篇文章,我就结合自己踩过的坑和积累的经验,带你彻底拆解5409A的内存架构与片上外设。我们不止看手册怎么说,更要看在实际项目中怎么用。比如,如何通过巧妙的内存映射,让关键循环代码跑在零等待的片上RAM里,从而把算法执行时间压缩到极致;又比如,如何配置McBSP与编解码器无缝对接,处理TDM流中的特定通道,而不被海量数据淹没。这些实战细节,手册里可不会写。

如果你正在评估或使用C54x系列DSP,或者任何需要高实时性、低功耗处理的嵌入式场景,理解5409A的这些核心机制,将帮助你最大化硬件潜力,写出更高效、更稳定的代码。我们从最根本的内存布局开始。

2. 内存架构深度解析与实战配置

TMS320VC5409A的内存系统是其高性能的基石,它并非简单的线性空间,而是一个可通过软件灵活配置的“立体战场”。理解并驾驭它,是发挥DSP算力的第一步。

2.1 哈佛架构与双总线优势

与冯·诺依曼架构的处理器不同,5409A采用了经典的哈佛架构。简单来说,就是程序和数据“分家”了,各有各的存储空间和访问通路。芯片内部有P-bus(程序总线)、C-bus、D-bus和E-bus等多条总线。这意味着,在一个机器周期内,CPU可以同时从程序存储器取指,并从数据存储器读写操作数。这种并行性对于信号处理中常见的“取数-运算-存结果”流水线操作是巨大的福音,能有效避免总线瓶颈。

在实际编程中,这种架构直接影响我们的代码和数据布局策略。最理想的状况是:频繁执行的核心算法代码(如FIR滤波循环、FFT蝶形运算)放在片上程序RAM;同时,需要快速存取的数据缓冲区(如输入采样队列、滤波器系数表)放在片上数据RAM。这样,CPU可以在一个周期内完成“从程序RAM取指令”和“从数据RAM加载数据”这两件事,实现单周期乘加(MAC)等高效率运算。

2.2 片上存储器详解:DARAM与ROM

5409A片上有两大块宝藏:32K字的双端口RAM(DARAM)和16K字的掩膜ROM。

2.2.1 双端口RAM(DARAM)的妙用

这32K字(每字16位)的DARAM被分成了4个独立的8K字块(DARAM0-DARAM3)。所谓“双端口”,是指每个存储块在一个周期内支持两次访问:可以是两次读,或者一次读和一次写。这对于许多DSP算法至关重要。

举个例子,在做向量点积运算sum += a[i] * b[i]时,在一个周期内,我们需要同时读取系数a[i]和采样数据b[i],然后进行乘加运算。如果这两个数据位于同一个单端口RAM块,就需要两个周期才能完成数据读取,严重拖慢速度。而DARAM允许我们在一个周期内从同一个8K块中同时读出这两个数,从而保证MAC指令的单周期执行。

实操心得:在分配数据时,我会刻意将需要同时访问的数据对(如滤波器的系数表和状态变量)安排在同一DARAM块的不同地址上。编译器通常不会自动做这种优化,需要手动通过#pragma DATA_SECTION指令将变量定位到特定的段,然后在链接命令文件(.cmd)中将这些段映射到具体的DARAM块地址。

2.2.2 片上ROM与引导加载器(Bootloader)

16K字的片上ROM是掩膜型的,意味着芯片出厂时内容就固定了。对于大规模量产、代码稳定的产品,将核心算法(如标准的GSM EFR语音编解码表)固化在ROM中可以节省宝贵的RAM空间。ROM的地址范围是C000h-FFFFh。

ROM中最有价值的部分是位于F800h-FBFFh的引导加载器(Bootloader)。这是一个出厂预置的小程序,当芯片复位后,如果MP/MC引脚为低电平(微计算机模式),CPU会从ROM的FF80h处开始执行,那里有一条跳转指令,直接跳到Bootloader的入口。

Bootloader支持多种启动方式,这是5409A系统设计灵活性的关键:

  • 并行EPROM启动:从外部8位或16位并行Flash/EPROM加载代码,最常见。
  • HPI启动:通过主机接口,由外部主处理器(如ARM、MCU)将代码灌入DSP内存。
  • 串口启动:通过McBSP从串行EEPROM或外部串行设备加载。
  • 热启动:从特定的内存地址开始执行,用于系统复位后快速恢复。

注意事项:选择启动方式需要硬件设计配合。例如,使用HPI启动,则主机必须在DSP上电复位后及时准备好并开始传输数据;使用串行启动,则要确保McBSP的时钟和帧同步信号在Bootloader读数据时是有效的。设计不当会导致DSP启动失败,一直停留在Bootloader状态。

2.3 内存映射与关键控制位

内存空间如何划分,哪些在片上,哪些在片外,是由几个关键的寄存器位控制的。下图是理解这一切的核心:

程序空间 (Program Space) 数据空间 (Data Space) (由XPC和IPTR共同决定) (固定范围 0000h - FFFFh) ┌──────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────┐ │ 页127 (7F0000h - 7FFFFFh) XPC=7Fh │ │ FFFFh ┌──────────────────────────────┐ │ │ ... │ │ │ 外部存储器 │ │ │ 页1 (010000h - 01FFFFh) XPC=01h │ │ │ (当访问>7FFFh且OVLY=0) │ │ │ 页0 (000000h - 00FFFFh) XPC=00h │ │ 8000h ├──────────────────────────────┤ │ │ ├─────────────────────────────────┤ │ │ │ │ │ │ │ │ │ │ │ DARAM3 │ │ │ │ 外部程序存储器 │ │ │ │ (6000h - 7FFFh) │ │ │ │ (当OVLY=0或地址超出片上范围) │ │ │ 6000h ├──────────────────────────────┤ │ │ │ │ │ │ │ DARAM2 │ │ │ ├─────────────────────────────────┤ │ │ │ (4000h - 5FFFh) │ │ │ │ │ │ │ 4000h ├──────────────────────────────┤ │ │ │ 片上DARAM (当OVLY=1) │ │ │ │ DARAM1 │ │ │ │ (映射到0080h - 7FFFh区域) │ │ │ │ (2000h - 3FFFh) │ │ │ │ │ │ │ 2000h ├──────────────────────────────┤ │ │ ├─────────────────────────────────┤ │ │ │ DARAM0 │ │ │ │ │ │ │ │ (0080h - 1FFFh) │ │ │ │ 保留/中断向量区 │ │ │ 0080h ├──────────────────────────────┤ │ │ │ (0000h - 007Fh, 不可映射) │ │ │ │ 存储器映射寄存器(MMR) │ │ │ │ │ │ │ │ (0000h - 005Fh) │ │ │ └─────────────────────────────────┘ │ │ 0060h └──────────────────────────────┘ │ │ │ │ │ └────────────────────────────────────────────────────┘ └────────────────────────────────────────────┘

2.3.1 OVLY位:片上RAM的“双重身份”

OVLY位位于PMST寄存器的第5位,它是决定片上DARAM是否出现在程序空间的关键。

  • OVLY = 0:片上DARAM出现在数据空间(0080h-7FFFh)。程序空间访问该地址范围时,将访问外部存储器。这种模式适用于程序代码全部放在外部Flash或ROM,片上RAM专用于数据的场景。
  • OVLY = 1:片上DARAM被同时映射到程序空间和数据空间的0080h-7FFFh区域。这是最常用、性能最优的模式。它意味着你可以把需要高速运行的代码段(用#pragma CODE_SECTION指定)链接到0080h之后的地址,CPU取指时直接访问片上RAM,零等待状态。同时,数据访问也在这块高速RAM上。

踩坑记录:务必注意,数据空间的0000h-007Fh是存储器映射寄存器(MMR)区,程序空间的0000h-007Fh是保留/中断向量区。无论OVLY为何值,程序空间的0000h-007Fh都不会映射到片上RAM。如果你错误地将代码段链接到0000h-007Fh,并设置OVLY=1,期望它跑在片上RAM,结果是CPU会去访问外部存储器,如果外部没有连接存储器,程序将跑飞。

2.3.2 MP/MC引脚与位:片上ROM的“开关”

MP/MC引脚在上电复位时被采样,并决定PMST寄存器中MP/MC位的初始值。

  • MP/MC = 0 (微计算机模式):片上ROM被映射到程序空间的C000h-FFFFh。复位后,CPU从ROM的FF80h(Bootloader入口)开始执行。
  • MP/MC = 1 (微处理器模式):片上ROM被禁用,C000h-FFFFh区域指向外部存储器。复位向量(FF80h)也位于外部存储器。这种模式用于调试阶段,代码放在外部易失性存储器中,方便修改。

2.3.3 XPC寄存器与扩展程序空间

5409A的地址线是23位,理论上可以寻址8M(2^23)字的程序空间。但传统的程序地址寄存器(PC)只有16位,只能寻址64K。为了解决这个问题,5409A引入了分页扩展内存机制

  • 整个8M程序空间被划分为128页,每页64K。
  • XPC寄存器(地址001Eh)是一个7位的存储器映射寄存器,它指定当前程序位于哪一页。
  • 当程序跳转或调用超出当前64K页面时,需要同时修改PC和XPC。芯片提供了6条专用指令(如FBACC,FCALA,FCALL)来处理远地址跳转和调用。

实战技巧:对于大多数应用,程序代码不会超过64K,因此可以忽略XPC,将其始终设为0,只使用页0(000000h-00FFFFh)。只有当你的代码库异常庞大时,才需要考虑分页管理。使用分页会稍微增加跳转开销,并让代码管理变得更复杂。

2.3.4 IPTR与中断向量重映射

中断向量表默认在程序空间的FF80h-FFFFh。但通过设置PMST寄存器的高9位(IPTR字段),你可以将整个128字的中断向量表重定位到任何128字对齐的页面起始地址。例如,设置IPTR = 0x0001,则中断向量表将位于0080h-00FFh(页0内)。这常用于将中断向量表搬到更快的片上RAM中,以加快中断响应。但硬件复位向量(RS)是例外,它永远固定在FF80h,无法重映射。

2.4 内存保护机制

5409A提供了一个简单的内存保护选项,通过设置相应的保护位(在文档中提及为ROM保护位),可以阻止外部发起的指令访问片上存储器空间。这在一定程度上防止了代码被恶意读取。但需要注意的是,HPI写入不受此限制,HPI读取则被限制在4000h-5FFFh区域。这个功能在注重代码安全性的应用中会启用。

3. 片上外设功能详解与驱动开发要点

内存是舞台,外设就是演员。5409A丰富的片上外设使其能灵活对接各种外部器件。

3.1 软件可编程等待状态生成器

当CPU访问速度较慢的外部存储器(如Flash、SDRAM)或外设时,需要插入等待周期。5409A的软件等待状态寄存器(SWWSR)可以精细地控制不同地址范围的等待状态数。

SWWSR将外部地址空间划分为5个区域:

  1. I/O空间(0000-FFFFh)
  2. 数据空间高半部分(8000-FFFFh)
  3. 数据空间低半部分(0000-7FFFh)
  4. 程序空间高半部分(视XPA位决定是xx8000-xxFFFFh还是400000h-7FFFFFh)
  5. 程序空间低半部分(视XPA位决定是xx0000-xx7FFFh还是000000h-3FFFFFh)

每个区域可以用3个比特位配置0-7个基本等待状态。此外,软件等待状态控制寄存器(SWCR)中的SWSM位可以将所有基本等待状态数乘以1或2,从而实现最多14个等待状态。

配置示例:假设外部Flash连接在程序空间,其读取需要3个等待周期才能稳定输出数据。我们可以这样配置:

// 假设XPA=0,程序空间低半部分(xx0000-xx7FFFh)映射Flash // 设置基本等待状态为3 SWWSR = (SWWSR & 0xFFF8) | 0x0003; // 将bit2-0设为011b (3) // 如果需要更慢的访问(例如低温下),可以启用倍乘 SWCR |= 0x0002; // 设置SWSM位为1,等待状态数x2 -> 实际为6个等待状态

注意事项:复位后,SWWSR默认所有区域为7个等待状态(最保守)。在系统初始化时,应根据实际硬件速度尽早优化此配置。过少的等待状态会导致数据读取错误,过多的等待状态则会无谓地降低性能。

3.2 可编程存储体切换(Bank Switching)

当连续的两次内存访问发生在不同的外部存储体(以32K字为边界)时,地址总线需要时间切换。Bank Switching逻辑会自动插入一个额外的周期,防止总线冲突。这由BSCR寄存器控制。

  • CONSEC位:决定切换模式。通常设为0,仅在跨32K边界访问时插入额外周期,保证大多数连续访问是全速的。
  • BH/HBH位:控制总线和HPI总线的总线保持器(Bus Holder)。启用后,当总线处于高阻态时,保持器会维持总线上的最后一个逻辑电平,防止因总线浮动引入噪声,降低功耗。在总线挂接多个器件时建议开启。

3.3 增强型主机接口(HPI8/16)

HPI是5409A与外部主处理器(Host)通信的桥梁,主处理器可以是MCU、ARM或另一颗DSP。

3.3.1 HPI8与HPI16模式

  • HPI8模式:8位数据总线(HD[7:0]),通过HBIL信号区分高低字节来完成16位传输。地址和数据通过同一组信号线分时复用(复用模式),或使用单独的HA[2:0]地址线(非复用模式)。这是传统模式。
  • HPI16模式(增强特性)这是5409A的一大亮点。当HPI16引脚接高电平时,HPI工作在16位非复用模式。此时,主机通过16位数据总线(HD[15:0])和16位地址总线(HA[15:0])直接访问DSP的整个片上内存空间(包括扩展地址页),无需像HPI8那样通过HPIA寄存器间接寻址。数据传输效率翻倍,且编程模型更简单直观。

3.3.2 HPI访问机制主机通过HPI访问DSP内存,本质上是一种直接内存访问(DMA)。HPI模块内部有一个DMA控制器,负责将主机侧的数据搬移到DSP的内存中,反之亦然。这意味着主机访问与DSP内核的执行是异步的,主机可以在DSP运行代码的同时读写其内存。

开发心得:在HPI16非复用模式下,主机端的驱动编写会简单很多。主机可以将DSP的内存看作一段连续的地址空间。一个常见的应用架构是:主处理器(如ARM)运行Linux,负责系统管理和上层应用;5409A作为协处理器,负责底层实时信号处理(如音频降噪)。ARM通过HPI16将待处理的音频数据块地址和长度写入DSP内存的特定邮箱(Mailbox)区域,然后触发DSP中断。DSP的中断服务程序读取邮箱,处理数据,完成后写回状态,再触发ARM的中断。这种主从协作模式非常高效。

3.4 多通道缓冲串行口(McBSP)

McBSP是5409A与外部串行设备(如音频编解码器、电信帧处理器、SPI器件)通信的核心。5409A有三个独立的McBSP,功能强大。

3.4.1 核心功能与时钟配置McBSP支持全双工、双缓冲、独立收发时钟和帧同步。其时钟源配置非常灵活,通过PCR寄存器的SCLKME位和SRGR2寄存器的CLKSM位组合选择:

  • CLKSM=0, SCLKME=0: 时钟来自CLKS引脚(5409A上通常不可用)。
  • CLKSM=1, SCLKME=0: 时钟来自内部CPU时钟(默认)。
  • CLKSM=0, SCLKME=1: 时钟来自接收时钟引脚(BCLKR)。
  • CLKSM=1, SCLKME=1: 时钟来自发送时钟引脚(BCLKX)。

后两种方式为需要外部参考时钟的应用(如从编解码器获取主时钟)提供了便利。

3.4.2 多通道选择与TDM应用这是McBSP的杀手级功能。它支持最多128个通道的TDM数据流。例如,在一条串行数据线上,时分复用着32路语音信号(每路16位,每秒8k采样)。你的DSP可能只需要处理其中的第5和第18路。

  • 传统32通道模式(RMCME/XMCME=0):通道被分为A、B两个分区,每个分区16个通道。通过RCERA/B和XCERA/B寄存器选择使能哪些通道。数据只会进出被使能的通道对应的DRR和DXR寄存器,其他通道的数据被自动忽略/不发送,极大节省了DSP内核的处理开销和DMA带宽。
  • 增强128通道模式(RMCME/XMCME=1):通道被分为A-H共8个分区。需要使用新增的RCERC-H和XCERC-H寄存器来配置。这对于更复杂的多路复用系统(如某些电信背板标准)非常有用。

3.4.3 SPI协议兼容模式通过配置CLKSTP等寄存器,McBSP可以模拟SPI主设备或从设备的时序,直接连接SPI Flash、传感器等器件,无需额外的GPIO模拟,且效率更高。

调试陷阱:McBSP的配置寄存器很多,务必遵循正确的初始化序列:先使收发器处于复位状态(XRST=RRST=0),配置所有相关寄存器(如SPCR, RCR, XCR, SRGR等),最后再释放复位(XRST=RRST=1)。错误的顺序可能导致McBSP无法正常工作。另外,注意最大速率限制:多通道模式下为9Mbps,非多通道模式下为38Mbps。

3.5 硬件定时器与时钟发生器

3.5.1 硬件定时器这是一个简单的16位递减计数器,带4位预分频器。计时周期 = (TDDR+1) * (PRD+1) / CLKOUT频率。定时器中断非常稳定,常用于提供系统时基、任务调度或产生精确的PWM波形(配合GPIO)。

3.5.2 时钟发生器与PLL5409A的时钟模块可以从外部晶振或时钟源产生内核工作时钟(CLKOUT)。

  • DIV模式:输入时钟直接除以2或4。此时PLL被禁用,功耗最低。
  • PLL模式:输入时钟乘以一个系数(从0.25到15,共31种选择)。这允许使用一个较低频率的外部晶振(如10MHz),通过PLL倍频得到较高的内核时钟(如100MHz),降低系统高频噪声和成本。

时钟模式由CLKMD寄存器控制,而该寄存器的复位值由硬件引脚CLKMD1-3在上电时的电平决定。这是一个硬件与软件协同配置的典型例子。例如,硬件设计将CLKMD引脚设置为“PLL x 10”模式,那么上电后,如果外部接10MHz晶振,内核时钟就是100MHz。之后,软件还可以通过修改CLKMD寄存器切换到其他倍频比或DIV模式。

重要提醒:文档中提到,并非所有5409A的芯片版本都支持晶体振荡器模式(即直接在X1/X2引脚接晶振)。在设计硬件前,必须查阅你所使用的具体芯片版本对应的勘误表(Silicon Errata, SPRZ186),确认该功能是否被支持。如果不支持,则必须使用有源晶振或时钟发生器,将时钟信号直接输入X2/CLKIN引脚,X1悬空。

4. 系统设计实战与常见问题排查

理解了各个模块,最终要把它们组合成一个稳定工作的系统。这里分享一些整体性的设计思路和排错经验。

4.1 系统初始化流程最佳实践

一个可靠的DSP系统,初始化顺序至关重要。下面是我常用的流程:

  1. 关闭看门狗:第一时间关闭看门狗定时器,防止在漫长的初始化过程中触发复位。
  2. 配置时钟与PLL:根据硬件连接(CLKMD引脚状态)和所需CPU频率,设置CLKMD寄存器。如果使能PLL,通常需要延时等待PLL锁定稳定。
  3. 配置等待状态:根据外部存储器的数据手册(访问时间),计算并设置SWWSR和SWCR,确保可靠访问。
  4. 配置存储体切换:根据外部存储器布局,设置BSCR寄存器(通常CONSEC=0, BH=1)。
  5. 初始化堆栈指针:将堆栈(SP)指向片上DARAM中一个安全的区域。
  6. 配置中断:设置PMST中的IPTR,将中断向量表重定位到片上RAM的某个段(如0080h开始),然后填充中断服务程序地址。
  7. 初始化外设:按需初始化McBSP、HPI、定时器等。注意先使外设软件复位,再配置,最后释放复位
  8. 启用中断:设置INTM寄存器(全局中断屏蔽位)为0,打开全局中断。
  9. 跳转到主循环:完成初始化,进入应用程序主循环。

4.2 内存链接命令文件(.cmd)编写要点

链接命令文件是告诉链接器如何将代码段和数据段放置到物理内存的关键。一个针对5409A优化过的.cmd文件片段可能如下所示:

MEMORY { PAGE 0: /* 程序空间 */ VECS : origin = 0x0080, length = 0x0080 /* 中断向量表重定位于此 */ PRAM : origin = 0x0100, length = 0x3F00 /* 片上DARAM,放关键代码 */ PEXT : origin = 0x4000, length = 0xC000 /* 外部Flash区域 */ PAGE 1: /* 数据空间 */ REGS : origin = 0x0000, length = 0x0060 /* MMR区,编译器自动管理 */ SCRATCH : origin = 0x0060, length = 0x0020 /* 暂存区 */ DRAM0 : origin = 0x0080, length = 0x1F80 /* DARAM0块 */ DRAM1 : origin = 0x2000, length = 0x2000 /* DARAM1块 */ /* ... 其他DARAM块 */ } SECTIONS { .vectors : {} > VECS PAGE 0 /* 中断向量表 */ .text : {} > PRAM PAGE 0 /* 可执行代码 */ .cinit : {} > PEXT PAGE 0 /* 初始化表(只读) */ .switch : {} > PEXT PAGE 0 /* 开关语句表 */ .bss : {} > DRAM0 PAGE 1 /* 未初始化全局/静态变量 */ .data : {} > DRAM1 PAGE 1 /* 已初始化全局/静态变量 */ .stack : {} > DRAM0 PAGE 1 /* 系统堆栈 */ .sysmem : {} > DRAM1 PAGE 1 /* 动态内存堆(malloc用) */ /* 用户自定义段 */ .myCoeffs: {} > DRAM0 PAGE 1 /* 滤波器系数表 */ .myBuffer: {} > DRAM1 PAGE 1 align = 256 /* 数据缓冲区,256字节对齐 */ }

4.3 常见问题与排查技巧实录

问题1:程序在片外Flash运行正常,搬到片内RAM后跑飞。

  • 排查:首先检查OVLY位是否设置为1。然后,用仿真器查看PC指针,如果程序跑飞后PC值很小(如0000h, 0001h),很可能是发生了非法中断,而中断向量表没有正确初始化或重映射。检查PMST寄存器的IPTR字段,并确认中断向量表所在的内存区域在程序空间是有效的、可执行的(例如在片上RAM且OVLY=1)。

问题2:McBSP无法收发数据,或数据错位。

  • 排查
    1. 时钟和帧同步:用示波器测量BCLKX/R和BFSX/R引脚,确认时钟频率、极性、相位是否符合配置和外部设备要求。帧同步脉冲宽度和延迟是否匹配。
    2. 寄存器配置:逐项核对RCR/XCR(接收/发送配置)、SRGR(采样率生成)、PCR(引脚控制)寄存器。特别注意字长、帧长度、时钟停止模式等设置。
    3. 多通道使能:如果使用了多通道,检查RCER/XCER寄存器是否正确使能了目标通道。一个常见的错误是使能了通道但数据字长配置不匹配。
    4. DMA/中断:如果使用DMA搬运McBSP数据,检查DMA配置是否正确(源/目的地址、传输计数、同步事件)。如果使用CPU中断,检查中断是否使能,以及DRR/DXR数据寄存器是否及时被读取/写入。

问题3:通过HPI加载程序后,DSP不运行。

  • 排查
    1. 启动模式引脚:确认在HPI启动模式下,MP/MC引脚是否被正确拉高(微处理器模式),否则DSP会尝试从片内ROM启动。
    2. HPI访问冲突:主机在加载完代码后,是否正确地写入了DSP的程序入口点地址到某个约定位置(或直接修改了DSP的PC寄存器)?主机是否清除了HPI控制寄存器中可能阻止DSP运行的状态位?
    3. DSP状态:用仿真器连接DSP,查看其是否处于IDLE状态或停留在某个地址。检查HPI相关的控制寄存器(HPIC),看是否有错误标志。

问题4:系统功耗偏高。

  • 优化
    1. 关闭未用外设时钟:通过外设寄存器禁用不使用的McBSP、HPI、定时器等模块的时钟输入。
    2. 降低频率:在满足性能要求的前提下,通过CLKMD寄存器降低CPU主频。功耗与频率大致成线性关系。
    3. 使用IDLE指令:在任务间隙调用IDLE指令,让CPU进入低功耗等待状态,由中断唤醒。
    4. 优化等待状态:在保证可靠性的前提下,尽量减少SWWSR中的等待状态数,缩短总线活动时间。
    5. 启用总线保持器:设置BSCR中的BH位,减少总线翻转功耗。

问题5:扩展程序空间(XPC)使用异常。

  • 排查:确保远调用/跳转使用了正确的指令(FCALL,FBACC等)。这些指令会同时操作PC和XPC。手动修改PC而不更新XPC,或者使用近跳转指令(如CALL)跳转到其他页的地址,都会导致程序跑飞。在调试时,密切关注PC和XPC两个寄存器的值是否同步变化。