目前,我正在使用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提供的其他功能如何解决这个问题。
期待很快得到社区的回复。 谢谢,
答案 0 :(得分:0)
感谢您的快速回复。
我正在处理的代码是保密信息。因此,我只能与您共享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外设调用的命令后仍然可以随时工作,并执行一些重要任务来解决问题,例如。 / p>
希望这个解释能让我前一个问题更加清晰。并希望尽快得到你们所有人的回应。
答案 1 :(得分:0)
首先,不要在无限循环中放置无限循环!! 如果您发现自己这样做,这表明可能的设计流程。请修改你的设计。 (让我们称之为第一条规则)
其次,您似乎通过注册处理程序/回调来使用事件驱动的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*/
}
答案 2 :(得分:0)
usart_read_buffer_job()
只会调用回调一个时间,所以在处理完回调之后,你必须再次调用usart_read_buffer_job()
(可能在回调结束时如果处理完成了。)
只有一个无限循环可以运行,除非您有某种单独的任务(例如在FreeRTOS中),每个任务都有自己的循环。