При генерации прерывания логика работы процессора предусматривает
ожидание окончания исполнения текущей команды и лишь после этого переход
в прерывание..
Таким образом при генерации прерывания, попадая в
подпрограмму обработчик прерывания мы не знаем сколько времени мы уже
потеряли на вход в прерывание..
В большинстве задач это не важно,
и вы даже возможно не задумывались о таких задержках при входе в
прерывание, но например, в задаче генерации видео - важен каждый такт
работы процессора - потому что в 2х тактах процессора умещается 1
выдаваемый пиксел изображения..
Таким образом задержавшись на входе в прерывание на 4 такта - мы получим сдвиг строки изображения на 2 пиксела..
а
теперь представьте что в одно прерывание генерирующее строку мы попали с
паузой в 0 таков, а в следующее с паузой в 4 такта.... - сдвиг двух
строк относительно друг друга будет равен двум пикселам !!!!
а теперь представьте что такое происходит в каждой строке изображения !
этот
эффект может полностью испортить все выводимое изображение.. конечно
читать его с экрана можно будет, но вот только похвастаться вряд ли...
Что делать ?
Вариант 1: Я этот вариант реализовал в библиотеке avr-tv.
1. Генерируем подготовительное прерывание OCR1A - которое предшествует прерыванию выдающему строку изображения OCR1B
2. В прерывании OCR1A разрешаем прерывания и останавливаем процессор командой sleep
3. Возникающее прерывание OCR1B - всегда будет пробуждать процессор после команды sleep поэтому задержка на вход в прерывание всегда будет одинаковой
Недостаток
такого способа очевиден: мы не можем использовать другие прерывания
процессора, потому что другие прерывания (аппаратные) разбудят процессор
после команды sleep, и фактически мы будем опять ждать
исполнения какой-то (заранее предсказать нельзя) команды и опять
возникнет рассинхронизация вывода.
здесь важно отметить, что для
возможности генерации прерывания в программе обработчика другого
прерывания нужно это явно разрешить командой sei
Вариант 2:
Поскольку
у нас прерывания связаны со счетчиком T1 - то у нас есть достоверный
источник о том сколько тактов прошло с момента входа в прерывание.
Можно ли его использовать ? По моему да.. минут 10 и готов следующий код который осуществляет синхронизацию после входа в прерывание
Ну и конечно ссылка на проект /raznoe/time_test.zip
в точку after_0 процессор
всегда будет попадать через 13 тактов от момента генерации прерывания,
вне зависимости от того сколько тактов было потрачено на начало
исполнения программы прерывания (сколько времени потратили на завершение
уже исполняющейся команды основной программы)
|