Atmel Studio 7: обработчик прерываний USART, предоставляемый библиотекой ASF, работает один раз только в случае возникновения бесконечного цикла в main ()?

В настоящее время я использую usart_read_buffer_job функция предоставлена ​​библиотекой ASF. Я поместил эту функцию внутри цикла 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

Решение

Спасибо за очень быстрый ответ.

Код, над которым я работаю, является конфиденциальным. Следовательно, я мог бы только поделиться с вами функциями библиотеки ASF и кратко объяснить, как они работают.

В ASF, как правило, у нас есть две функции для обработки прерывания, а именно usart_read_buffer_job а также usart_read_job

Перед использованием этих двух функций вызовы обработчика определяются двумя функциями:

usart_register_callback: Регистрирует функцию обратного вызова, которая реализуется пользователем.

usart_enable_callback: Функция обратного вызова будет вызываться из обработчика прерываний при выполнении условий для типа обратного вызова.

И эти две функции выше помещены в код инициализации, как показано в вопросе.

Затем, в зависимости от цели разработки, обработчики вызываются всякий раз, когда символ или группа символов принимаются через периферийные устройства UART с использованием соответственно usart_read_buffer_job / usart_read_job.

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, и выполнять, например, некоторые важные задачи для решения проблем.

Надеюсь, что это объяснение прояснит мой предыдущий вопрос. И надеюсь получить ответ от всех вас в ближайшее время.

0

Другие решения

Прежде всего, не помещайте бесконечный цикл внутри бесконечного цикла !!.
Если вы обнаружите, что делаете это, это указывает на вероятный ход проектирования. Пожалуйста, пересмотрите ваш дизайн.
(Давайте назовем это первое правило)

Во-вторых, вы, кажется, используете управляемый событиями ввод-вывод (а не опрос), регистрируя обработчик / обратный вызов.
Вот второе правило, вы никогда не вызываете обработчик самостоятельно.
Вы регистрируете функцию обратного вызова (обработчик), которая будет вызываться при возникновении события.

Если вы делаете инициализацию и настройку правильно, код должен работать по следующей схеме:

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*/
}
0

usart_read_buffer_job() будет вызывать только обратный вызов один время, поэтому после того, как обратный вызов был обработан, вы должны вызвать usart_read_buffer_job() снова (возможно, в конце обратного вызова, если обработка завершена).

Только один бесконечный цикл может выполняться, если у вас нет каких-то отдельных задач (например, в FreeRTOS), каждая из которых имеет свой собственный цикл.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector