目前,我正在使用ASF库提供的usart_read_buffer_job函数。我把这个函数放在while(1)循环中,如下所示:
int main()
{
Some pieces of code for initialization;
while(1)
{
usart_read_buffer_job();
while(1) // The second infinite loop
{
Some other pieces of code;
}
}
}
它适用于第一个中断处理程序调用。但是,从处理程序返回后,我不再能够调用中断处理程序。程序在第二个无限循环内继续运行,无法再次执行usart_read_buffer_job()。这可能是处理程序故障的原因。
在这种情况下,我的目的是跳转到USART中断处理程序,而不管main()中执行的无限循环的数量。当然,通过不使用ASF,可以通过手动设置处理程序来解决问题,但我仍然想知道ASF提供的其他功能如何解决这个问题。
期待很快得到社区的回复。谢谢,
感谢您的快速回复。
我正在处理的代码是保密。因此,我只能与您共享ASF库函数,并简要解释它们的工作原理。
在ASF中,通常我们有两个处理中断的函数,即usart_read_buffer_job和usart_read_job
在使用这两个函数之前,处理程序调用由两个函数定义:
usart_register_callback:注册一个由用户实现的回调函数。
usart_enable_callback:当满足回调类型的条件时,将从中断处理程序调用回调函数。
上面这两个函数放在初始化代码中,如问题所示。
然后,根据设计目的,只要分别使用usart_read_buffer_job / usart_read_job通过UART外设接收字符或一组字符,就会调用处理程序。
usart_read_buffer_job:设置驱动程序以从USART读取到给定缓冲区。如果已注册并启用,则将调用回调函数。
usart_read_job:设置驱动程序以将USART模块中的数据读取到给定的数据指针。如果已注册并启用,则在接收完成时将调用回调。
您可以在http://asf.atmel.com/docs/latest/samd21/html/group__asfdoc__sam0__sercom__usart__group.html上找到有关这些功能的更多详细信息
在这种情况下,假设主程序由于某些意外的无限循环而停止,处理程序在接收到从UART外设调用的命令后仍应该在任何时候工作,并执行一些重要任务来解决问题。
希望这个解释能让我以前的问题更加清晰。并希望尽快得到你们所有人的回应。
首先,不要在无限循环中放置无限循环!!如果您发现自己这样做,这表明可能的设计流程。请修改你的设计。 (我们称之为第一条规则)
其次,您似乎通过注册处理程序/回调来使用事件驱动的I / O(而不是轮询)。这是第二条规则,你永远不会自己打电话给处理程序。您注册在事件发生时要调用的回调函数(处理程序)。
如果您正在进行正确的初始化和配置,则代码应遵循以下方案:
void initialization()
{
/*Device and other initialization*/
...
usart_register_callback(...); /*Register usart_read_callback() here*/
usart_enable_callback(...);
}
int main()
{
initialization();
while(1)
{
/*Some other pieces of code*/
}
}
void usart_read_callback(...)
{
usart_write_buffer_job(...); /*Read data into your read data buffer*/
}
usart_read_buffer_job()
只会调用一次回调,所以在回调处理之后,你必须再次调用usart_read_buffer_job()
(如果处理完成,可能在回调结束时)。
只有一个无限循环才能运行,除非您有某种独立的任务(例如在FreeRTOS中),每个任务都有自己的循环。