Так вот, пишем этот драйвер, как простую программу, которая делает эти действия, а когда, после выдачи байта в UART, надо подождать момента, когда можно будет передавать следующий байт, вызываем специальную подпрограмму ожидания, которая достает из стека и сохраняет в своей статической памяти адрес возврата, а также необходимые данные из регистров, восстанавливает из стека сохраненные регистры вызывавшей программы (той, которая выдала запрос на передачу по RS485) и возвращается в нее. Вызывавшая программа знает, что обмен только запущен, но еще не выполнен, она может заниматься чем-то другим.
Вторая половина программы ожидания запустится по прерыванию от UART'а, она сохранит нужные регистры, поднимет в них данные, сохраненные первой половиной и перейдет командой ijmp по адресу, добытому первой половиной из стека. Таким образом, драйвер продолжится с команды, следующей за вызовом специальной программы ожидания. Далее, готовим следующий байт, или готовим прием байта ответа (подтверждения от адресованного абонента) и снова вызываем ожидание. После очередного прерывания снова получит управление команда, следующая за последним вызовом ожидания, и т.д.
Используя этот приём мы, во-первых, можем писать драйвер, как простую программу, которая занимается только передачей нужных байтов (адресов, заголовков, данных и т.д.) не думая о том, что где-то там есть другие задачи, прерывания и пр. и, во-вторых, полностью снимается проблема разбирательства на тему "куда переходить, получив очередное прерывание?"


