裸机嵌入式系统中的多任务处理

问题描述 投票:0回答:2

我有一个基于 16 位微控制器 PIC18 的裸机系统。系统通过 2 个模拟输入、2 个数字输入和 CAN 接收输入,然后根据这些输入运行算法。我必须根据接收到的模拟和数字输入每 10 毫秒通过 CAN 传输数据,对接收到的数字输入进行开关去抖,并在 CAN 中接收数据并基于模拟输入时关闭或打开数字输出,时间间隔为 x 秒/ 收到数字输入。 我能够通过 CAN 发送和接收数据,并能够在 while(1) 循环中对输入和输出进行编程 我不确定如何构建这个系统并保持时间限制。我正在使用 C,并且没有操作系统或调度程序。

我需要使用某种计时器,但不确定如何创建状态机或任务。

c architecture embedded bare-metal
2个回答
0
投票

基于我在 https://owd.tcnj.edu/~hernande/ELC343/Chapter_08.pdf 找到的关于 PIC18 定时器的 PDF 文件我编写了一个 n*10ms 延迟的函数。我担心多次使用时,错误可能会累积,但这可能会激发更好的解决方案。

void delay (char cx){
  int i;
  T0CON = 0x83; /* for TMR0, instruction clock, & prescaler=16 */
  for (i = 0; i < cx; i++) {
    TMR0 = 60535; /* it rolls over in 5000 clock cycles as 16-bit timer */
    INTCONbits.TMR0IF = 0;
    while(!(INTCONbits.TMR0IF)) doOtherTask(); /* until TMR0 rolls over */
  }
  return;
}

0
投票

经验丰富的开发人员在几乎任何项目中所做的第一件事就是创建计时器驱动程序和一个 HAL(他们甚至会从以前的项目中准备好 HAL),这允许您为事物注册简单的回调函数例如去抖动或 10ms 循环通信。 HAL 不是必需的,但它有帮助。

无论哪种方式,您都需要一个或多个“基于中断”的硬件计时器 - 忙等待轮询将不起作用。您可以将它们设置为每 1 毫秒触发一次、每 10 毫秒触发一次或任何可行的方式。中断必须是简约的 - 您可以将 GPIO 读取/去抖动压缩到一个中断中,但不能将 CAN 通信内容放入 ISR 中。因此,跟踪 ISR 的计时器必须是一个 volatile bool ready_to_send; 标志。在主应用程序中,如

main()
等,您检查此标志
if(ready_to_send)
,然后从那里执行 CAN 代码。
类似地,您可以将 ADC 代码放入计时器中,具体取决于您需要读取代码的频率以及您是否同意丢失样本。触发 ADC 转换中断会对程序产生很大的破坏,因为这些中断速度快且频繁,因此仅在计时器上使用它,以防您错过单个转换。

此外,如果这恰好是最大函数调用深度为 8 的功能失调 PIC 之一,这将对 C 代码设计产生一些重大影响。在这种情况下,强烈建议将 PIC 扔进电子回收站并改用现代 MCU。一般情况下应避免使用旧零件。

© www.soinside.com 2019 - 2024. All rights reserved.