在使用Cortex M0的Arduino.cc草图中,如何声明SysTick处理程序?

时间:2015-05-15 19:14:48

标签: arduino interrupt cortex-m

非常简单的设置 - 我在基于Cortex M0的arduino上使用Arduino.cc的Arduino Sketches。

在setup()方法中,我调用:

void setup()
{
SysTick_Config(SystemCoreClock / 1000 ); //for a 1ms timer
}

在草图正文中,我声明:

void SysTick_Handler(void)
{
// print a message to serial port 
}

永远不会调用此处理程序(loop()函数正在运行)。 Cortex M0技术参考手册说明了这是如何做到的,但是Arduino草图编程语言并没有记录这些内容在草图中的暴露程度。我正在为我的电路板导入电路板接口,它会编译并运行,但不会调用处理程序。

这里有关于如何弄清楚方法声明应该是什么,或者为什么不被调用的提示?

我应该使用自己的IRQ吗?我试过了,但也找不到配置IRQ处理程序的功能的方法。

3 个答案:

答案 0 :(得分:0)

有几点想法:

1 - SysTick_Config实际上是否启用了SYSTICK中断?

2 - 我们必须将中断向量“连接”到你的处理程序;通常这是在汇编程序文件中完成的。也许Arduino的attachInterrupt()可以在这里工作。

答案 1 :(得分:0)

如果您的程序可以正常工作,那么您每秒会调用1000次处理程序。这会混淆串口。我相当确定。

我有一个链接:https://wiki.nottinghack.org.uk/wiki/Project:Arduino_Due。搜索SysTick。你会发现一个使用SysTick和串行打印的arduino程序。

答案 2 :(得分:0)

我也有这个问题。首先,对于上述问题

  

1 - SysTick_Config实际上是否启用了SYSTICK中断?

是。这是一个CMSIS功能:

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */

  SysTick->LOAD  = ticks - 1;                                  /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */
  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                  /* Function successful */
}
  

2 - 我们必须&#34;连接&#34;处理程序的中断向量;经常   这是在汇编程序文件中完成的。也许是Arduino的   attachInterrupt()可以在这里工作。

Systick_Handler函数与Atmel库中的Systick中断向量相关联。很确定这部分已经完成。

这里有一个指导性的主题https://groups.google.com/a/arduino.cc/forum/#!msg/developers/ziJQT2SX1eI/jiml1rcHHZIJ

这表明为什么不会调用用户草图中Systick_Handler的定义(因为cortex_handlers.c中的默认实现未定义为弱)。在这种情况下,草图应该实现

int sysTickHook(void);

在实现中返回1将导致绕过默认的Arduino处理程序,并允许您实现自己的处理程序代码。返回0将导致在实现后执行默认处理程序。

看来,cortex_handlers.c中的默认实现是为了在USB端口检测到1200波特的连接时重置处理器。您可以在CDC.cpp中看到这一点,其中调用了cancelReset和initiateReset(在Reset.cpp中定义)。默认情况下,Reset.cpp中禁用重置,因为本地变量&#34; ticks&#34;初始化为-1。 cortex_handlers.c中的默认实现也调用了TimeTick_Increment,这是delay()工作所必需的(注意延迟在main.cpp中调用,所以它需要工作!)。所以你可能想从sysTickHook()返回一个0。

考虑到所有这一切,delay()在我的主板上不起作用,我不知道为什么。似乎没有在cortex_handlers.c中调用Systick_Handler()。所以问题类似于OP。

更新:在这个帖子Can weak symbol be resolved among libraries during linking?中遇到harper的答案后,这个工作得到了解决 Arduino将弱定义从startup_sam3xa.c移动到cortex_handlers.c,如果你移植到不同的山姆,你需要做同样的事情。

另外,我不知道为什么,我必须在main.cpp中delay(1)的初始化上游的某处添加cpu_irq_enable()。否则SysTick_Handler拒绝解雇。看起来像Due代码不会这样做。

希望这有帮助。