Ревич, Ю.В. Программирование микроконтроллеров AVR: от Arduino к ассемблеру

Глава 15. Программирование UART и обмен данными с персональным компьютером 397 записаны вами в буфер передатчика по адресу UDR, они автоматически передаются в сдвиговый регистр передатчика и начинается собственно передача. В этот момент буфер передатчика уже свободен для записи новых данных. Если при этом было включено прерывание готовности" буфера (о чем рассказано далее), то оно возника­ ет сразу же, как только вы записали первые данные. Иными словами, независимо от того, включено ли это прерывание, или запись данных происходит по «ручному» опросу состояния бита UDRE как в процедуре out_com, передача двух байтов подряд происходит, с точки зрения программы, непосредственно друг за другом (с задерж­ кой в 4 или, в случае использования прерывания, 8 тактов, необходимых для вы­ полнения соответствующих действий). То есть при одном-двух посылаемых байтах отсылка через UART любым способом практически не задержит выполнение про­ граммы. Важная особенность процедур in_сот и out_сот -то, что их можно вызывать в лю­ бой момент в любом месте программы, внутри обработчиков прерываний или вне их, безразлично (более того, в прерываниях это даже безопаснее, - см. врезку «Подробности» далее) . А так как отсылка одного-двух байтов почти не нарушает течения основной программы, то процедуру out_сот удобно применять при отладке программного кода, временно вставляя ее в те места кода, где необходимо прокон­ тролировать содержимое того или иного регистра. Нужный регистр перегружается в tетр, и сразу вызывается out_сот. Программа с такой добавкой в большинстве случаев будет работать как обычно, только в нужный момент в UART будет выда­ ваться значение контролируемого байта (в отличие, между прочим, от штатных средств отладки в Atmel Studio или Proteus, которые капитально нарушают выпол­ нение исследуемой программы в реальном времени). ПОДРОБНОСТИ Наличие внешних прерываний меняет дело только в одном отношении: экономя реги­ стры , мы в этой простейшей программе осуществляем прием и передачу через рабо­ чий регистр temp. А он у нас задействован практически везде , и при наличии посторон­ них прерываний может быть испорчен , если одно из них вклинится между приемом и отсылкой . Поэтому при размещении простейших процедур in_com и out_com в главном цикле, возможно, потребуется заменить temp на какой-то другой регистр, который в прерываниях не используется . Об этом не приходится заботиться , если сами эти процедуры вызываются изнутри прерывания, - тогда можно оставить temp, потому что внутри прерывания он случайно испорчен быть не может. Недостаток у такой организации обмена тоже имеется - он состоит в том, что в момент перезагрузки контроллера, подключения-отключения адаптера от схемы и при других подобных действиях контроллер склонен осуществлять фиктивный об­ мен, принимая и отправляя несанкционированные байты с нулевым значением или, реже, со значением $ FF. Если такая ситуация может что-то нарушить в функциони­ ровании контроллера или внешней программы, то следует принимать меры для фильтрации приема произвольных значений. Можно придумать разные способы избежать такой ситуации (например, очищать регистр UDR при выходе из сброса и т. п. ), но самый простой и надежный из них - посылать/принимать не один байт, а два, первый из которых является командой с определенным фиксированным зна-

RkJQdWJsaXNoZXIy MTExODQxMg==