Ревич, Ю.В. Программирование микроконтроллеров AVR: от Arduino к ассемблеру
Глава 7. Система команд АVR 181 Непосредственная установка через константу заставляет рыться в справочнике или в inс-файлах в поиске номеров поименованных битов : ldi temp , Ob0 0 0 1 1 0 0 0 ; TXEN=l , RXEN=l А при использовании «законной» команды sЬi пришлось бы делать то же самое, но еще и предварительно обнулять регистр . Понятно, что установить биты в рабочем регистре temp для инициализации UART недостаточно. Потому следующей по тексту программы командой мы обязаны пе ренести установленное значение в соответствующий РВВ, называющийся в таком случае ucsRВ (см. главу 15) . Это делается традиционной для всех ассемблеров командой out : out UCSRB , temp В паре к out идет симметричная команда in - чтение данных из РВВ . Эти две команды также относят к командам переноса данных. В отличие от команд sЬi /сЬi, коман,,цы in/out действуют на все 64 «обычных» регистра - с номерами до $ ЗF (ад ресами до $ 5F, - см. рис. 2 . 2 в главе 2). Что происходит в контроллерах, имеющих «дополнительные» регистры (Extended 1/0) сверх этого адресного пространства, мы рассмотрим далее. Очень важный момент касается чтения и записи регистров ввода/вывода, которые составляют пару, образующую двухбайтное число. Если они меняются в реальном времени, то во время чтения или записи таких регистров одного за другим возмож ны коллизии. Например, если вы случайно «словите» в момент чтения прибавление 1 к числу $ O O FF (следующее значение $ 0 1 0 0 ) , то, прочитав сначала старший, потом младший, получите $ 0 0 00, а если наоборот - получите $ 0 1 FF. Потому в AVR для критичных к этому пар регистров имеется специальный мех анизм буферизации, который работает по следующему правилу: При чтении необходимо сначала прочесть младший байт L, потом старший н, а при записи - сначала записать старший байт н, потом младший L. К счастью, таких регистров немного : это прежде всего содержимое счетчиков 1 6-разрядных таймеров TCNTxH : TCNTxL, регистры захвата этих таймеров ICRxH : ICRxL и сравнения OCRxxH : OCRxxL, а также регистры данных АЦП ADCH : ADCL. Иными сло вами, это те 1 6-битные регистры, изменение которых в реальном времени способно повлиять на результат операции их чтения или нарушить функционирование при их неверной записи. Обратим внимание, что в языке С для АVR (в том числе и в Arduino) эта проблема решена за вас : там регистры TCNTlL и TCNTlH обрабатываются как единый двухбай товый TCNTl . То же касается и других упомянутых здесь 1 6-разрядных регистров. Следующими по важности командами пересылки данных будут команды загрузки и чтения SRAM: ld/ lds и st / sts . С этими командами связаны такие «жуткие» по нятия, как «прямая» и «косвенная» адресации, а также «относительная косвенная адресация» и т. п. (по моему убеждению, этот раздел в описаниях МК АVR спокой но можно при чтении пропускать) . Мы постараемся термин «адресацию> вообще не
Made with FlippingBook
RkJQdWJsaXNoZXIy MTExODQxMg==