Ревич, Ю.В. Программирование микроконтроллеров AVR: от Arduino к ассемблеру
224 Часть 111. Практическое программирование микроконтроллеров А VR прочтем $ 0 1 FF, что, конечно, далеко от действительности. Аналогичная история может произойти и при записи в таймер какого-либо числа. Во избежание таких ситуаций в 1 6-разрядных таймерах АVR, как мы уже говорили, предусмотрен специальный механизм чтения и записи парных 1 6-разрядных регистров, который требует некоторой внимательности от программиста (см. разд. «Команды пересыл- 1ш данных» главы 7). Механизм этот следующий. При записи первым загружается значение старшего байта, которое автоматически помещается в некий (недоступный для программи ста) буферный регистр. Затем, когда поступает команда на запись младшего байта, оба значения объединяются, и запись производится одновременно в обе «половин ки» 1 6-разрядного регистра. Наоборот, при чтении первым должен быть прочитан младший байт, при этом значение старшего автоматически фиксируется помещени ем в тот же буферный регистр, и при следующей операции чтения старшего байта его значение извлекается оттуда. Таким образом, и при чтении значения байтов со ответствуют одному и тому же моменту времени . Неправильный порядок чтения либо записи может привести к непредсказуемым результатам - например, если прочесть младший байт TCNTlL последним, то в этот момент старший TCNTlН буферизуется и так и останется в буфере. И при следующем чтении в том же порядке, когда бы оно ни производилось, сначала будет прочитано это значение, которое, естественно, никак не соответствует прочитанному значе нию младшего регистра. ПОВ ТОРИМ! Чтобы манипуляции с 1 6-разрядными регистрами были успешными , при чтении необ ходимо сначала прочесть младший байт (тcNтlL) , потом старший (тст1н) , а при запи си - сначала записать старший байт (тст1н) , потом младший (тcNТlL) . При чтении и записи регистра захвата ICRlН : ICRlL и при записи регистров сравне ния ocRlxH : OCRlxL (где х - А или В, о чем далее) также следует придерживаться этого правила. Оно не действует на регистры управления тccRlA и тссюв (которые по сути есть два раздельных регистра, а не один 1 6-разрядный) и может не учиты ваться при операции чтения из регистров сравнения осюхн и OCRlxL, которые мож но читать в произвольном порядке (хотя сама по себе такая операция требуется крайне редко) . Формально говоря, при чтении содержимого этих регистров также должны быть запрещены прерывания, но на практике, если соблюдается правильный порядок чтения, то «вклинившаяся» процедура прерывания приведет лишь к небольшой от срочке получения результата. Единственное исключение составляет случай, если в самом прерывании также происходит обращение к любому из 1 6-разрядных реги стров таймера, изменяющее буфер (для всех регистров он один и тот же), - тогда на время чтения или записи такие прерывания следует запрещать . При запуске таймеров в Jтботу следует также учитывать следующее обстоятельст во: несмотря на формальную установку в ноль всех РВВ при включении питания, опыт показывает, что перед запуском таймера в работу для получения точного пер-
Made with FlippingBook
RkJQdWJsaXNoZXIy MTExODQxMg==