Кочегаров И.И. Микроконтроллеры AVR. Лабораторный практикум (2012) (1264221), страница 6
Текст из файла (страница 6)
В этой связипрограммирование на языке ассемблера предполагает знание архитектуры и свойств микропроцессора, т.е. всего того, что входит в понятие «программная модель». Языки ассемблера различаются дляразных типов микропроцессоров, т.е. являются машинно-ориентированными. В ряде ассемблеров допускается оформление повторяющейся последовательности команд как одной макрокоманды (макроса), такие ассемблеры называют макроассемблерами.Языки высокого уровня (С, Паскаль, Бейсик и др.), как и ассемблер, обеспечивают доступ ко всем ресурсам микроконтроллера,но вместе с тем дают возможность создавать хорошо структурированные программы, снимают с программиста заботу о распределениипамяти и содержат большой набор библиотечных функций для выполнения стандартных операций.На этапе получения выполняемой программы исходный текстпрограммы с помощью специальных средств (трансляторов, компиляторов, компоновщиков и др.) преобразуется в исполняемый код.Транслятором (translator) называют программу, служащую для перевода (трансляции) программ на языке ассемблера в машинный код,«понимаемый» процессором.
Компилятор (compiler) представляетсобой программу, преобразующую в эквивалентный машинный кодтекст программы на языке высокого уровня. Результатом работытранслятора или компилятора может быть как выполняемый загрузочный модуль, так и объектный модуль (программа, команды, переменные и константы которой не «привязаны» к конкретным адресамячеек памяти).
Для построения выполняемой программы из объектных модулей применяется компоновщик (редактор связей, linker).В процессе получения выполняемой программы из исходного текстапрограммы устраняются синтаксические ошибки, состоящие в нарушении правил синтаксиса используемого языка программирования.На этапе тестирования и отладки программы производится поиск, локализация и устранение в ней логических ошибок. Тестирование служит для обнаружения в программе ошибок и выполняетсяс использованием некоторого набора тестовых данных. Тестовыеданные должны обеспечивать проверку всех ветвей алгоритма.
Притестировании программы могут подвергаться проверке также некоторые показатели системы, связанные с программой (например, объем кодов и данных). После тестирования программа должна быть28подвергнута отладке (debug), задачей которой является локализацияошибки, т.е.
нахождение места в программе, вызывающего ошибку.Тестирование и отладка программы могут привести (и, как правило, приводят) к необходимости возврата к ранним этапам процессаразработки программы для устранения ошибок в постановке задачи,разработке алгоритма, написании исходного текста и т.д. Таким образом, процесс разработки программы, как и весь процесс проектирования, является итерационным.На этапе получения загрузочной программы производится «освобождение» программы от лишних фрагментов, использовавшихсядля тестирования и отладки. Эти фрагменты увеличивают объем программы и не нужны при нормальном функционировании микропроцессорной системы.
Далее полученная загрузочная программа заносится в память микроконтроллера.По завершении процесса разработки производится документирование, т.е. составление комплекта документов, необходимых дляэксплуатации и сопровождения программы. Сопровождение программы (program maintenance) – это процесс внесения изменений,исправления оставшихся ошибок и проведения консультаций по программе, находящейся в эксплуатации. Виды программных документов регламентированы ГОСТ 19.101–77 «Единая система программной документации. Виды программ и программных документов».Разработка ПО для встраиваемых микропроцессоров производится на персональном компьютере с использованием специальныхпрограммных и аппаратных средств. Такой способ создания ПО носит название кросс-разработки.
Совокупность аппаратных и программных средств, применяемых для разработки и отладки ПО, объединяют общим наименованием средства поддержки разработки.В настоящем лабораторном практикуме процесс разработки ПО изучается на примере языка ассемблера AVR-микроконтроллеров. Создание исходного текста программы, трансляция и отладка выполняются в интегрированной среде разработки (Integrated DevelopmentEnvironment – IDE) AVR Studio. Более подробно работа с AVRStudio рассматривается в гл.
6.29Глава 5. Описание ассемблера AVR Требования к исходному кодуКомпилятор работает с исходными файлами, содержащими инструкции, метки и директивы. Инструкции и директивы, как правило,имеют один или несколько операндов.Строка кода не должна быть длиннее 120 символов.Любая строка может начинаться с метки, которая является набором символов заканчивающимся двоеточием. Метки используютсядля указания места, в которое передается управление при переходах,а также для задания имен переменных.Входная строка может иметь одну из четырех форм:[метка:] директива [операнды] [Комментарий][метка:] инструкция [операнды] [Комментарий][;Комментарий]Пустая строкаКомментарий имеет следующую форму:; [Текст]Позиции в квадратных скобках необязательны.
Текст после точки с запятой (;) и до конца строки игнорируется компилятором. Метки, инструкции и директивы более детально описываются ниже.Примеры:label: .EQU var1=10 ; Устанавливает var1 равным 10(Это директива).EQU var2=200 ; Устанавливает var2 равным 200test:rjmp test ; Бесконечный цикл (Это инструкция); Строка с одним только комментарием; Еще одна строка с комментариемКомпилятор не требует нахождения меток, директив, комментариев или инструкций в определенной колонке строки.Инструкции процессоров AVRНиже приведен набор команд процессоров AVR, более детальное описание их можно найти в описании ассемблера на официальном сайте (на английском языке, информация обновляется) [1].30Арифметические и логические инструкцииМнемоника ОперандыОписаниеОперацияФлагиЦиклыRd = Rd + RrZ,C,N,V,H,S1Rd = Rd + Rr + C Z,C,N,V,H,S1ADDRd,RrСуммированиебез переносаADCRd,RrСуммированиес переносомSUBRd,RrВычитаниебез переносаRd = Rd - RrZ,C,N,V,H,S1SUBIRd,K8Вычитание константыRd = Rd - K8Z,C,N,V,H,S1SBCRd,RrВычитаниес переносомRd = Rd - Rr - C Z,C,N,V,H,S1SBCIRd,K8Вычитаниеконстантыс переносомRd = Rd - K8 - C Z,C,N,V,H,S1ANDRd,RrЛогическое ИRd = Rd ^ RrZ,N,V,S1ANDIRd,K8Логическое Ис константойRd = Rd ^ K8Z,N,V,S1ORRd,RrЛогическое ИЛИRd = Rd V RrZ,N,V,S1ORIRd,K8Логическое ИЛИс константойRd = Rd V K8Z,N,V,S1EORRd,RrЛогическоеисключающееИЛИRd = Rd EOR RrZ,N,V,S1COMRdПобитнаяинверсияRd = $FF - RdZ,C,N,V,S1NEGRdИзменение знака(Доп.
код)Rd = $00 - RdZ,C,N,V,H,S1SBRRd,K8Установить бит(биты) в регистреRd = Rd V K8Z,C,N,V,S1CBRRd,K8Сбросить бит(биты)в регистреRd = Rd ^ ($FF K8)Z,C,N,V,S1INCRdИнкрементироватьзначение регистраRd = Rd + 1Z,N,V,S1DECRdДекрементироватьзначение регистраRd = Rd -1Z,N,V,S1RdПроверка на нольлибо отрицательностьRd = Rd ^ RdZ,C,N,V,S1TST31Мнемоника ОперандыОписаниеОперацияФлагиЦиклыCLRRdОчистить регистрRd = 0Z,C,N,V,S1SERRdУстановитьрегистрRd = $FFNone1Rdl,K6Сложитьконстантуи словоRdh:Rdl =Rdh:Rdl + K6Z,C,N,V,S2SBIWRdl,K6Вычестьконстантуиз словаRdh:Rdl =Rdh:Rdl - K 6Z,C,N,V,S2MULRd,RrУмножение чиселR1:R0 = Rd * Rrбез знакаZ,C2MULSRd,RrУмножение чиселR1:R0 = Rd * Rrсо знакомZ,C2Rd,RrУмножение числасо знакомR1:R0 = Rd * Rrс числомбез знакаZ,C2ADIWMULSUFMULFMULSFMULSURd,RrУмножениедробныхчисел без знакаR1:R0 = (Rd * Rr)<< 1Z,C2Rd,RrУмножениеR1:R0 = (Rd *Rr)дробных<< 1чисел со знакомZ,C2Rd,RrУмножениедробного числа R1:R0 = (Rd * Rr)со знаком<< 1с числом без знакаZ,C2Инструкции ветвленияМнемоника ОперандыОписаниеОперацияФлагиЦиклыRJMPkОтносительныйпереходPC = PC + k +1None2IJMPНетКосвенныйпереход на (Z)PC = ZNone2EIJMPНетРасширенныйкосвенныйпереход на (Z)STACK = PC+1,PC(15:0) = Z,PC(21:16) =EINDNone2JMPkПереходPC = kNone332Мнемоника ОперандыОписаниеОперацияОтносительныйSTACK = PC+1,вызовPC = PC + k + 1подпрограммыФлагиЦиклыNone3/4*RCALLkICALLНетКосвенныйвызов (Z)STACK = PC+1,PC = ZNone3/4*EICALLНетРасширенныйкосвенныйвызов (Z)STACK = PC+1,PC(15:0) = Z,PC(21:16) = EINDNone4*CALLkВызовподпрограммыSTACK = PC+2,PC = kNone4/5*RETНетВозвратиз подпрограммыPC = STACKNone4/5*RETIНетВозвратиз прерыванияPC = STACKI4/5*CPSERd,RrСравнить,пропустить,если равныif (Rd ==Rr) PC =PC 2 or 3None1/2/3CPRd,RrСравнитьRd -RrZ,C,N,V,H,S1CPCRd,RrСравнить с переносомRd - Rr - CZ,C,N,V,H,S1CPIRd,K8Сравнитьс константойRd - KZ,C,N,V,H,S1SBRCRr,bПропустить, еслиif(Rr(b)==0) PC =бит в регистреPC + 2 or 3очищенNone1/2/3Rr,bПропустить, еслиif(Rr(b)==1) PC =бит в регистреPC + 2 or 3установленNone1/2/3P,bПропустить, еслиif(I/O(P,b)==0)бит в портуPC = PC + 2 or 3очищенNone1/2/3P,bПропустить, еслиif(I/O(P,b)==1)бит в портуPC = PC + 2 or 3установленNone1/2/3SBRSSBICSBISBRBCBRBSs,kПерейти, еслифлаг в SREGочищенif(SREG(s)==0)PC = PC + k + 1None1/2s,kПерейти, еслифлаг в SREGустановленif(SREG(s)==1)PC = PC + k + 1None1/233Мнемоника ОперандыОписаниеОперацияФлагиЦиклыBREQkПерейти, еслиравноif(Z==1) PC = PC+k+1None1/2BRNEkПерейти, еслине равноif(Z==0) PC = PC+k+1None1/2None1/2BRCSkПерейти, еслиif(C==1) PC = PCперенос установ+k+1ленBRCCkПерейти, если if(C==0) PC = PCперенос очищен+k+1None1/2BRSHkПерейти, если if(C==0) PC = PCравно или больше+k+1None1/2BRLOkПерейти, еслименьшеif(C==1) PC = PC+k+1None1/2BRMIkПерейти, еслиминусif(N==1) PC = PC+k+1None1/2BRPLkПерейти, еслиплюсif(N==0) PC = PC+k+1None1/2Перейти, еслиif(S==0) PC = PCбольше или равно+k+1(со знаком)None1/2None1/2None1/2None1/2None1/2None1/2None1/2None1/2BRGEBRLTkkBRHSkBRHCkBRTSkBRTCkBRVSkBRVCkПерейти, еслименьше(со знаком)if(S==1) PC = PC+k+1Перейти, еслифлаг внутреннего if(H==1) PC = PC+k+1переносаустановленПерейти, если if(H==0) PC = PCфлаг внутреннего+k+1переноса очищенПерейти, если if(T==1) PC = PCфлаг T+k+1установленПерейти, если if(T==0) PC = PC+k+1флаг T очищенПерейти, если if(V==1) PC = PCфлаг переполне+k+1ния установленПерейти, если if(V==0) PC = PCфлаг переполне+k+1ния очищен34Мнемоника ОперандыBRIEkОписаниеОперацияФлагиЦиклыПерейти, еслипрерыванияразрешеныif(I==1) PC = PC+k+1None1/2Перейти, еслиif(I==0) PC = PCBRIDkпрерыванияNone1/2+k+1запрещены* Для операций доступа к данным количество циклов указано при условии доступа к внутренней памяти данных и не корректно при работе с внешнимОЗУ.
Для инструкций CALL, ICALL, EICALL, RCALL, RET и RETI, необходимо добавить три цикла плюс по два цикла для каждого ожидания в контроллерах с PC меньшим 16 бит (128 Кб памяти программ). Для устройств с памятьюпрограмм свыше 128 Кб, добавьте пять циклов плюс по три цикла на каждоеожидание.Инструкции передачи данныхМнемоника ОперандыОписаниеОперацияRd = RrФлаги ЦиклыMOVRd,RrСкопировать регистрMOVWRd,RrСкопировать парурегистровLDIRd,K8Загрузить константуLDSRd,kПрямая загрузкаRd = (k)None2*LDRd,XКосвенная загрузкаRd = (X)None2*LDRd,X+Rd = (X), X=X+1 None2*LDRd,-XX=X-1, Rd = (X) None2*LDRd,YNone2*LDRd,Y+Rd = (Y), Y=Y+1 None2*LDRd,-YY=Y-1, Rd = (Y) None2*LDDRd,Y+qRd = (Y+q)None2*LDRd,ZRd = (Z)None2*LDRd,Z+Rd = (Z), Z=Z+1 None2*LDRd,-ZZ=Z-1, Rd = (Z) None2*LDDRd,Z+qNone2*Косвенная загрузкас постинкрементомКосвенная загрузкас предекрементомКосвенная загрузкаКосвенная загрузкас постинкрементомКосвенная загрузкас предекрементомКосвенная загрузкас замещениемКосвенная загрузкаКосвенная загрузкас постинкрементомКосвенная загрузкас предекрементомКосвенная загрузкас замещением35NoneRd+1:Rd =NoneRr+1:Rr, r,d evenNoneRd = KRd = (Y)Rd = (Z+q)111Мнемоника ОперандыОписаниеОперацияФлаги ЦиклыSTSk,RrПрямое сохранение(k) = RrNone2*STX,RrКосвенное сохранение(X) = RrNone2*STX+,RrКосвенное сохранениес постинкрементом(X) = Rr, X=X+1 None2*ST-X,RrКосвенное сохранениес предекрементомX=X-1, (X)=Rr None2*STY,RrКосвенное сохранениеSTY+,RrST(Y) = RrNone2*Косвенное сохранениес постинкрементом(Y) = Rr, Y=Y+1 None2-Y,RrКосвенное сохранениес предекрементомY=Y-1, (Y) = Rr None2STY+q,RrКосвенное сохранениес замещением(Y+q) = RrNone2STZ,RrКосвенное сохранение(Z) = RrNone2STZ+,RrКосвенное сохранениес постинкрементом(Z) = Rr, Z=Z+1 None2ST-Z,RrКосвенное сохранениес предекрементомZ=Z-1, (Z) = Rr None2STZ+q,RrКосвенное сохранениес замещением(Z+q) = RrNone2LPMНетЗагрузка из программнойпамятиR0 = (Z)None3LPMRd,ZЗагрузка из программнойпамятиRd = (Z)None3LPMRd,Z+Загрузка из программнойпамятиRd = (Z), Z=Z+1 Noneс постинкрементом3ELPMНетРасширенная загрузкаR0 = (RAMPZ:Z) Noneиз программной памяти3ELPMRd,ZРасширенная загрузкаRd = (RAMPZ:Z) Noneиз программной памяти3ELPMRd,Z+Расширенная загрузкаиз программной памятис постинкрементом3SPMНетСохранениев программной памятиESPMНетRd =(RAMPZ:Z), Z = NoneZ+1(Z) = R1:R0Расширенное сохранение в (RAMPZ:Z) =программной памятиR1:R036NoneNoneМнемоника ОперандыОписаниеОперацияФлаги ЦиклыINRd,PЧтение портаRd = PNone1OUTP,RrЗапись в портP = RrNone1PUSHRrЗанесение регистра в стекSTACK = RrNone2Извлечение регистра изRd = STACK None2стека* Для операций доступа к данным количество циклов указано при условии доступа к внутренней памяти данных и не корректно при работе с внешнимОЗУ.