在您的设计中添加第二个 MCU 的原因有很多,一旦您这样做了,就有很多错误要避免。本文考虑了论点和选项,同时指出了沿途的陷阱。
鉴于当今可用的处理器种类繁多,您可能会发现通过在您的应用中引入第二个微控制器 (MCU) 或微处理器 (MPU) 来为应用程序添加新功能是一种更具成本效益的选择,原因有很多。设计而不是试图在单个更高性能的处理器上执行每项任务:
成本:与添加 8 位或 16 位 MCU 以承担增加的负载相比,迁移到更高性能的系统 MPU 可能具有更高的成本差异。
电源:与其消耗电源让主应用处理器不断地自行开启以执行相对简单的操作,例如监控传感器组或检查是否已按下某个键,可以引入一个 8 位处理器来执行这些任务。 从本质上讲,8 位处理器通过让主处理器休眠并仅在需要其注意的事件发生时才唤醒它来充当“电源门”。这对于电阻式和表面电容式触摸屏尤其有效。
确定性:涉及计算密集型任务(如动画或音频)的用户界面 (UI) 功能可能会强调系统的实时确定性行为。第二个 MCU 可以承担所有“实时”UI 职责,而不是冒着电机控制等关键任务的可靠性的风险。
多样性:许多系统都可以从模块化设计中受益。例如,可以使用不同的处理器来实现显示模块,以提供额外的图形或流式视频功能。通过采用模块化方法,无需更改主要应用程序代码即可向系统添加新功能或支持不同的模型。
简单:一条产品线可以提供多种选择。例如,一个产品可能有四个屏幕、三个键盘和三个连接选项。当使用单个处理器时,设计团队必须为每个可能的变体(4x3x3=36 个不同的变体)维护、测试和验证单独的代码版本。使用辅助处理器实现新功能时,只需对每个选项(4+3+3=10)进行维护。请注意,使用第一个选项时,需要使用每个变体对整个系统进行测试和验证,这是一个复杂且耗时的过程。使用第二个选项时,主应用程序代码只需要验证一次。每个选项都可以单独验证,并且复杂性大大降低。
I/O 保护:一个 MCU 可以通过响应多个地址在一个接口上看起来是多个设备。例如,主应用处理器可以发出命令打开风扇,该命令被用作虚拟集线器的 MCU 拦截。这是一种在主应用处理器上节省 I/O 的有效方法,因为只需一个通信外围设备即可读取和控制多个设备。
认证:更改用户界面或在主系统中引入新的界面(如 Wi-Fi)需要对某些市场的整个设计进行重新认证。将这些功能作为具有单独处理器的附加模块来实施,可简化重新认证过程,显着加快开发和上市时间。
UART、I 2 C 和 SPI
有许多选项可用于互连处理器。用于此目的的最基本接口是通用异步收发器 (UART)、内部集成电路 (I 2 C) 和串行外设接口 (SPI)。今天,许多处理器为这些接口中的一个或多个提供硬件和软件支持。例如,意法半导体的 STM32 Cortex-M3 32 位处理器和 8 位STM8L MCU 支持所有这三种。或者,赛普拉斯的PSoC可编程片上系统处理器系列具有模拟和数字模块,可配置为提供每个接口的多个实例,允许根据不同目标市场的需要更改接口组合。问题变成了您需要多少接口。
UART 的运行速度高达 250 kbps,而 I 2 C 的运行速度为 100 至 400 kbps。提供自己的时钟的 SPI 可以以超过 1 Mbps 的速度运行。UART 链接通常可以使用基于中断的驱动程序在软件中实现,只要驱动程序不会根据应用程序的需要在处理器上施加过多的负载或延迟。一个我2C 主机通常可以用软件实现,但由于涉及的数据速率,从机需要用硬件实现。SPI 还需要基于硬件。多主机系统也需要基于硬件。
除了数据速率之外,每个接口都提供了可能使其更适合特定应用的特定功能。UART 实现起来非常简单,并且是全双工的。我2C 语言很受欢迎,因为它只需要两条线,可以有一个简单的主控,并提供各种高级选项,包括支持寻址、多主控、广播和时钟延长。例如,时钟延长允许 I2C 从机在处理接收到的数据时保持时钟并停止数据流,从而防止潜在的溢出问题。相比之下,SPI 从设备受 SPI 主设备的支配。借助 I 2
C 和 SPI 的所有各种可用选项,许多芯片供应商提供示例代码,您需要将其用作创建自己的代码的模型。幸运的是,这些接口的驱动程序相当简单——I 2C驱动可以是15行代码,让你在短时间内实现一个接口。但是,重要的是要确定需要支持哪些特性,正确实现它们,并且主从实现相同的特性。例如,在创建 I 2
C 驱动程序 时,您需要确定许多参数,例如 7 位或 11 位寻址、单主机或多主机(具有冲突检测和恢复)、数据速率、是否使用 ACK/NAK 协议,支持地址保持,以及一系列其他选项。因此,任何两个特定的 I 2 C 接口都可能非常不同。例如,开发人员遇到的一个常见问题是将笔记本电脑中使用的系统管理总线 (SMBus) 误认为是一种简单的 I2C总线。尽管 SMBus 在 I 2 C 接口上运行,但它通常使用固定电压来表示高值和低值,而通用 I 2 C 接口使用的阈值通常基于 MCU 电源的百分比,因此表示潜在的差异两者之间可能会产生难以调试的间歇性错误。
还要注意,UART,我2C和SPI只是物理接口。您仍然需要提供在物理层之上运行的逻辑协议。如果接口位于您设计的两个 MCU 之间,则此协议可以是您想要的任何协议。如果 MCU 正在与串行 EEPROM 之类的设备通信,那么协议已经为您定义好了。因此,考虑到不同设备的数量及其可能与之通信的协议,主设备的驱动程序可能比从设备更复杂。此外,如果您的 master 不支持 slave 支持的所有协议功能(或者相反,尝试使用 slave 不支持的功能),兼容性问题最终会浮出水面。
这些接口中的每一个的简单性都是它的优点和缺点。您可以实现复杂的协议,这使接口更加高效和强大,但这也可能使调试更加困难。如果您不小心,简单性为您提供了挂起系统所需的所有绳索。
例如,考虑一个接口正在控制一个模拟多路复用器的应用,该多路复用器需要在两个音频流之间平滑转换。根据过渡的实施方式,可能会出现不受欢迎且可听到的副作用;即,从柔和的流切换到响亮的流会导致响亮的“Pop!” 此外,命令延迟可能会影响转换。理想情况下,您需要关闭音频,切换流,然后重新运行音频。但是,这对您的应用程序可能并不总是很方便。如果您同时使用多个电源,也会遇到同样的困难。
为了促进初始驱动程序设计和验证,许多供应商提供了强大的开发工具来实现和验证接口功能。例如,微芯片提供 PICkit 串行分析器,可连接到您的系统和 PC,您可以使用该 PC 将链路配置为具有 UART、I 2 C 和 SPI 的任何标准接口选项的主设备或从设备。接口设计中的一个经典问题是需要预先存在的 master 来设计 slave 或预先存在的 slave 来设计 master。PICkit 通过提供可靠的另一半链路来进行设计,从而消除了这个问题,并且可以查看通过链路两侧发送的内容。PICkit 还能够模拟各种 I 2 C 外设,如 ADC 和风扇控制器。
许多 MCU 供应商还提供各种功能齐全的开发套件和库,以方便将 LCD 显示器、触摸屏或其他外围设备等子系统引入系统。例如,TI 提供了 RDKIDML-35 智能显示模块参考设计套件,可以相对轻松地将 3.5 英寸 QVGA 触摸屏添加到通过 I 2 C 或 SPI 链路连接的系统。该套件还包括一个具有各种 GUI 功能的软件库,以加快用户界面设计。
避免常见
的陷阱 最后,学习实现 UART、I 2 C 或 SPI 链接的最佳方法是自己动手。来自各种 MCU 制造商的专家建议了以下提示和技巧列表,以帮助您避免开发人员在实现他们的第一个处理器到处理器接口时经常犯的一些更常见的错误、误解和失误。
分阶段引入复杂性:不要试图从一开始就实现整个系统。从基本驱动程序开始并验证其操作。然后添加协议层并再次验证。介绍应用层。最后,运行整个系统及其所有各种并发任务和相互依赖关系。
设计您的系统以抽象功能:例如,使用通用 UI 界面允许主系统连接到机械按钮、键盘或触摸屏,而无需知道实际连接的是哪个。这种方法还允许您从根本上修改功能的执行方式,而无需对主系统进行任何代码更改。考虑一台具有单独处理器处理硬币和票据收集的自动售货机。如果出现安全问题(即客户想出了办法欺骗机器),只需要重新设计用于监控收集的硬件和软件来防止这种情况发生;系统的其余部分保持不变。
认识到外围设备不同于处理器:连接到外围设备与连接到另一个处理器不同。当您控制接口两侧的软件时,您定义了两侧的接口细节和协议,因此可以保证兼容性。当您只设计接口的一侧时,您需要设计接口以匹配您所连接的外围设备的要求。这会引起许多潜在的问题。最常见的是外设的数据表不准确地描述了接口是如何实现的。为避免此问题,请验证接口是如何实现的。还要注意各种接口选项,例如 11 位寻址、时钟延长、
指定足够的数据速率:确认接口的数据速率将满足您当前和未来的数据需求。例如,与较大的显示器或同等触摸屏相比,小型显示器需要较低的数据速率。如果您计划在下一代设计中支持更大的显示器,请保持您的界面选项开放。
计算超支:获得 I 2C 或 SPI 连接起来非常简单。您可能会遇到困难的地方是极端情况。例如,接口可以正常运行到某个频率,此时它开始出现故障。问题可能来自系统中的太多噪音或数据溢出。数据溢出可能是本地问题;一系列特定类型的数据包可能需要更多的处理时间,导致处理器无法足够快地清空缓冲区。更常见的是,溢出是由系统级问题引起的。例如,接口使用的 DMA 或 FIFO 可能是共享资源。根据系统正在处理的其他内容(即实时操作系统同时管理多个实时任务),延迟可能大于估计值,从而导致溢出。
首先验证驱动程序:当出现问题时,可能很难确定错误的原因。在管理多个接口或实时任务的系统中尤其如此,因为系统中发生的其他事情可能会出现错误。通过在引入应用程序级功能之前验证您的驱动程序,首先让系统可靠地进行通信。这使您可以在以后的调试过程中更自信地消除驱动程序作为问题的根源。
使用代码检测进行调试:调试接口的两侧可能会很棘手,因为您正在使用多个处理器。虽然有调试多处理器系统的工具,但它们通常只允许您暂停链路的一侧,从而难以利用传统的调试技术。如果您在链路的两侧使用相同类型的处理器,您可以选择让一个处理器发送然后接收它自己的信号;这使您可以观察链接的两侧并同时停止它们。如果您通过 JTAG 进行调试,您可以将两个处理器连接到同一个 JTAG 链。
但是,一旦混合了架构,您可能会发现自己不得不一次调试链接的一侧。为了简化调试,通过创建一个允许您分阶段测试基本功能的简单存根驱动程序来限制链接另一端的复杂性。当您开始在链路的两侧使用实时系统时,您可以在链路的一侧使用调试器并在链路的另一侧使用代码检测技术来促进调试。链接的检测端可以使用链接本身将状态信息(例如变量值、接收到的数据和其他重要信息)发送回被调试的处理器。
利用你的调试器:一些工程师试图在没有调试器的情况下解决编程问题。当他们遇到错误时,他们会在代码中尝试不同的东西。然而,许多接口问题是在系统级别引起的,重写接口驱动程序代码不是解决方案。观察这些系统级交互可能需要调试器。
检查您的连接:在调试问题之前三重检查您的连接。例如,一个容易犯的错误是连接接口的控制信号,但没有共同接地。这样做,您可能会发现自己花费数小时试图解决一个不存在的问题。
记录您的代码:花时间编写带有完整注释的干净代码。一个简单的我2C 驱动程序可能只运行 15 行,并且似乎不需要文档。但是,如果您是 I 2 C 的新手,您可能会错过一个稍后会进一步了解的关键参数。完整的文档为您提供了一个可靠的途径来跟踪您的思维变化,并且不会随着应用程序复杂性的增加而迷失方向。
质疑规格表:由于其更大的灵活性,开发人员通常会遇到更多关于 I 2的问题C比用SPI。例如,从机可以通过降低时钟、使用不同的寻址模式或以不同的方式实现启动/停止序列来对主机产生不利影响。即使您连接到带有详细数据表的传感器等外围设备,也要小心。外围设备可能不符合规范,因此如果您无法使接口正常工作,请不要立即假设您的驱动程序或 MCU 有故障。在这种情况下,您可能需要逻辑分析仪来定位问题的真正根源。
可以访问逻辑分析仪:当您必须使用现有接口和协议连接到另一台设备时,此工具特别有用。当连接到具有并行接口(如显示器)的外围设备时,它还可以加速开发。请务必检查您的逻辑分析仪是否支持您正在使用的接口的适当解码。自动解码可以大大简化调试,因为您可以将接口作为逻辑信号进行观察,而不必自己将物理信号转换为逻辑信号。
共存设计:在多主机系统中,有时您需要确保将数据发送到多个目的地,而不会冒着将总线放弃给另一个主机的风险。为此,您可以在每次传输之间使用重新启动条件来保持对总线的控制。类似地,您可以使用重新启动来改变数据的方向以从从机(即 EEPROM)接收数据,而无需松开总线。然而,以这种方式锁定总线的主机可能会为其他执行同样时间关键任务的主机产生延迟问题。谨慎使用此类技术并彻底测试主控器之间的相互作用,以确保它们彼此之间运行良好。
设计具有从/主功能的驱动程序:考虑让你的奴隶成为主人。这在系统故障的情况下很有用,允许从机接管总线并启动恢复机制,其延迟明显低于从机必须等到它被寻址才能发出警报的情况。
将数据处理与数据传输分开:通常,收集的数据(即来自温度传感器的电压)与需要传输的数据(即是否已超过温度阈值)有很大不同。考虑一个触摸屏模块的接口,其中作为主系统的主系统请求当前手指位置数据。该模块收集原始数据并将其存储,直到主站请求位置数据。此时,模块检索原始数据,对其进行处理,然后传输。
这种特殊的架构可能会无意中造成溢出情况。考虑到为了保持响应能力,主系统可能会以比原始数据实际更改的频率更高的频率询问信息。这意味着对于每个请求,模块必须使用数据密集型算法重新计算位置数据,即使数据没有改变。由于要多次计算原始数据,结果是巨大的开销,可能会影响模块的响应能力。
有几种方法可以消除这种开销。例如,可以在计算位置数据之前检查原始数据是否已充分改变。如果原始数据没有改变,则使用之前的计算。另一种方法是让触摸屏模块充当链接上的主模块,并在位置发生变化时发送更新。
保持接口简单:如果只有一主一从,则无需实现地址冲突。当然,还要考虑未来的扩展以及部署的设备是否可能需要支持这样的功能才能与未来几代设备兼容。
借助当今的集成 MCU 和 MPU,再加上强大的开发工具,设计您的第一个处理器到处理器接口可以是一个简单的过程,让您可以快速地将第二个处理器引入现有设计。通过谨慎设计,您可以避免许多常见的陷阱,从而创建一个可靠且高效的界面,以满足您当前和未来应用程序的性能需求。
评论
查看更多