Ревич, Ю.В. Программирование микроконтроллеров 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 при выходе из сброса и т. п. ), но самый простой и надежный из них - посылать/принимать не один байт, а два, первый из которых является командой с определенным фиксированным зна-
Made with FlippingBook
RkJQdWJsaXNoZXIy MTExODQxMg==