Семейство 8-битных PIC (я работаю с pic18f46k22) предлагает несколько таймеров (таймеры 1/3/5), которые могут работать как в асинхронном, так и в синхронном режимах при тактировании от внешнего источника.
Очевидные отличия:
а что касается преимуществ синхронизации с внешним источником часов... ну я их не вижу. Одним из недостатков, о котором следует подумать, является возможное повреждение данных, если ЦП пытается прочитать счетчик во время его увеличения, но в таблице данных указано:
12.5.1 ЧТЕНИЕ И ЗАПИСЬ ТАЙМЕРА 1/3/5 В РЕЖИМЕ АСИНХРОННОГО СЧЕТЧИКА: Чтение TMRxH или TMRxL во время работы таймера от внешних асинхронных часов обеспечит правильное чтение (об этом заботится аппаратно).
Может кто-нибудь объяснить, почему они добавили возможность синхронизации внешнего источника часов с внутренними фазовыми часами? Я чувствую, что что-то упускаю. Большое спасибо
Некоторые операции с таймером не работают, когда он может измениться в середине цикла. Этот таймер также используется в сочетании с модулями CCP. Прочтите раздел описания модулей CCP, и вы, вероятно, найдете ограничения на то, когда он должен работать в синхронном режиме.
Например, сравнение с определенным значением может быть нестабильным, если значение таймера может измениться в середине операции сравнения или увеличиться после точки сравнения между проверками.
Если вам нужен таймер для работы в спящем режиме, он должен быть установлен в асинхронный режим, а если таймер установлен в асинхронный режим, то любое изменение его состояния под контролем процессора (включая переключение между синхронным и асинхронным режимом), которое происходит в в то же время входящий импульс может привести к произвольному искажению его состояния.
Если у вас есть два асинхронных таймера, я бы посоветовал вам настроить один из них на непрерывную работу и ничего с ним не делать, кроме чтения его значения. Такие чтения должны выполняться путем чтения младшего байта, затем старшего байта, а затем снова младшего байта. Если младший байт изменился между двумя чтениями, повторите процесс. Другой таймер можно настроить для событий пробуждения, но с некоторыми оговорками:
Запишите младший байт таймера, прежде чем делать что-либо еще, чтобы изменить его, а затем прочитайте его. Если младший байт изменился, предположите, что таймер мог быть произвольно поврежден, и начните снова с нуля.
По крайней мере, в некоторых частях прерывание таймера происходит по фронту тактового сигнала после фронта тактового сигнала, который переводит таймер с 0xFFFE на 0xFFFF. Программирование таймера со значением 0xFFFF вызовет прерывание не на первом такте после такого действия, а на 65 537-м такте. Я не знаю, есть ли способ установить таймер для прерывания на следующем тике.
Используя эти методы вместе, можно логически объединить два асинхронных таймера, чтобы получить функциональность, которая была бы доступна на таймере с возможностью асинхронного сравнения.
supercat упомянул о чтении ошибок микрочипов ... посмотрите на PIC18 (L) F26 / 46K22 Rev. A2 / A4 Silicon Errata и уточнение таблицы данных (этот микроконтроллер, который вы используете):
- Модуль: Таймер 1/3/5
Когда Таймер 1, Таймер 3 или Таймер 5 работают в режиме асинхронного внешнего ввода, может произойти непредвиденная генерация флага прерывания, если фронт внешнего тактового сигнала поступит слишком рано после записи прошивки в регистры TMRxH:TMRxL. Непредвиденное событие флага прерывания также может произойти при включении модуля или переключении из синхронного в асинхронный режим.
Обойти:
Эта проблема возникает только при работе таймера в асинхронном режиме. По возможности используйте модуль таймера в синхронном режиме, чтобы избежать ложных прерываний таймера.
Быстрый поиск в Google также показывает другие проблемы с режимом асинхронного таймера с другими микроконтроллерами (пример: pic18f4550 errata-сбой механизма буферизованного чтения и ошибки семейства pic18f97j60), поэтому, вероятно, это хороший момент, чтобы не слишком доверять асинхронному таймеру и добавьте дополнительные две строки кода, чтобы проверить любое чтение/запись. и не забудьте пример кода, представленный в errata, чтобы очистить генерацию флага неожиданного прерывания при записи таймера
фхлб