Аббревиатура ЧМЗ — это не Челябинский (или Черниговский) Машиностроительный Завод. ЧМЗ расшифровывается как Чтение-Модификация Запись. Все, кто изучает программирование микроконтроллеров (МК) компании Microchip, рано или поздно сталкиваются с, так называемой, проблемой ЧМЗ (анг. RMW- Read-Modificatioп-Write). Иногда непонимание причин возникновения этой проблемы вводит начинающих программистов МК в ступор. После многочисленных переправерок выясняется, что код, вроде бы, не содержит ошибок, но, тем не менее, поведение МК остается непредсказуемым. Природа возникновения этой «ошибки» и способы борьбы с ней рассмотрены в настоящей статье.
Проблема ЧМЗ наблюдается для большинства МК фирмы Microchip. Для полного понимания рассмотрим один из случаев возникновения «ошибки». Заметим, что эта проблема возникает как при программировании на языке ассемблера, так и на языках высокого уровня. На рис.1 показан фрагмент схемы с выводами порта В (PORTB). Линия 3 (РВЗ) этого порта «Подтянута» к плюсу источника питания. Пройдем в пошаговом режиме приведенный в листинге код на языке Си, который создан специально для этой схемы. Этот код является вполне достаточным для наблюдения ошибки, вызванной «проблемой ЧМЗ». Желающие могут скомпилировать код в MPLAB, прогнать его в «железе» и проверить, тем самым, справед ливость выводов автора. Структурная схема порта (один разряд из восьми) микроконтроллера среднего семейства PIC16 показана на рис.2. Все операции записи в порт выполняются по принципу «Чтение-Модификация-Запись», сначала производится чтение состояния всех выводов порта, затем изменение (модификация) и запись в защелку. Из приведенной схемы видно, что запись (WR) МК производит в защелку данных, а чтение (RD) от внешних устройств непосредственно с выводовмикроконтроллера.Теперь рассмотрим, как выполняется код из листинга. Изначально обнуляется регистр порта(TRISB=O), т.е. записали лог. «О» в защелку.Этим линия RВЗ переведена для работы как вход. При этом на входе RВЗ по явилась лог. «1» благодаря подтягивающему резистору R1. При изменении RBO предварительно производится чтение порта. Так как на RВЗ присутствует лог. «1»,то МК считывает значение всего порта, равное 00001000, в двоичной системе счисления. Далее производится модификация данных, т.е. меняется значение RBO. Получаем 00001001. И полученные данные записываются в защелки порта.
Таким образом, можно сделать вывод, что данная проблема возникает, когда в процессе выполнения программы меняется направление работы портов и при этом применяются бит-ориентированные команды. Исключая одно из этих условий, можно избавиться от подобного поведения микроконтроллера. Если избежать изменения направления работы портов в некоторых случаях невозможно, то отказаться от бит-ориентированных команд – просто. Для этого применяется буферный регистр, изменения битов производится в буферном регистре, а запись в порт производится копированием значения буферного регистра в регистр порта.
Есть еще один случай возникновения подобной ошибки, но при котором не происходит переключение направления работы портов. Это может наблюдаться тогда, когда тактовая частота микроконтроллера высокая и подряд выполняются две и более бит-ориентированные команды. При этом из-за высокой нагрузки порта может не успеть установиться уровень лог. «1» вовремя. Считываются неверные данные, и последующее поведение программы становится не таким, как предполагалось разработчиком.
Фирма Microchip, зная об этой проблеме, предлагает разделять такие команды NOP-ами.
Более правильным решением следует считать использование буферного регистра.
Для исключения подобных ошибок в современных микроконтроллерах PIC производитель ввел аппаратный виртуальный регистр LATх.
Структурная схема порта такого микроконтроллера (один разряд из восьми) показана на рис.3. Из этой схемы видно, что при использовании регистра LATх считывание данных производится непосредственно с выходом защелок. Для чтения данных с выводов порта используется регистр PORTх, а для записи данных в порт – LATх. При таком использовании регистров проблема ЧМЗ невозможна в принципе.
Автор надеется, что данная статья поможет начинающим программистам МК обойти «грабли», расставленные производителем микроконтроллера, и глубже разобраться в работе МК.
Автор: Анатопий Медведев, г. Екатеринбург
Источник: Радиоаматор, №4, 2014