Кодим жесть Долин Сергей Хакер, номер #093, стр. 093-024-3 Первая программа для микроконтроллера. Все программисты начинали писать свои творения с примитивной программы «Hello World». Своеобразный «Hello World» для микроконтроллера – это процесс моргания светодиодом. Собираем данную схему. У нас в арсенале имеются и разъем программирования, и светодиоды. Теперь нам нужен пакет для разработчиков на ассемблере – AVR Studio. Ставим, запускаем и жмем кнопку «New project». Выбиваем AVR Assembler и называем проект, например, Hello World. Жмем Next, выбираем AVR Simulator и тип микроконтроллера (в нашем случае — ATmega8535). Все. Теперь ваяем программу. Начинать кодинг следует с инклудника: .include "m8535def.inc" Данное включение определяет имена регистров, параметры стека и всякую системную инфу, которую можно посмотреть, заглянув в него. Данный инклуд для каждого МК будет свой, его необходимо найти самостоятельно, в папке с AVR Studio, или покопаться в инете. Далее следует описание переменных, но это необязательный процесс. Однако он облегчает читабельность и отладку нашей программы. Потом по нулевому адресу мы ставим безусловный переход на основной код. .org 0 rjmp START За переходом обычно находится таблица прерываний, но в нашей программе она не используется. Потом у нас идет инициализация стека. START: ldi R16,low(RAMEND) out SPL,R16 ldi R16,high(RAMEND) out SPH,R16 Это стандартная процедура, где мы определяем адресное пространство, где будет располагаться стек. Значения low(RAMEND) и high(RAMEND) определены в нашем подключаемом файле m8535def.inc. Затем мы инициализируем порты ввода/вывода. В нашем случае мы ставим PORTA на вывод. ser R16 out DDRA, R16 Командой ser мы загружаем в регистр R16 значение FF. Далее мы устанавливаем в регистре DDRA все пины порта А на вывод. Если установить какой-либо бит в ноль, то это будет означать, что данный пин порта будет работать на ввод. После всех инициализаций начинается основная программа, которая бегает в бесконечном цикле. LOOP: ldi R17, 1 out PORTA,R17 ldi R20,50 rcall WAIT ... rjmp LOOP Тут мы по очереди загружаем в регистр R17 значение 1,2,4,8 и выводим их в порт, затем вызываем процедуру задержки (весь листинг программы лежит на диске). Получается, что у нас по очереди будут зажигаться светодиоды сначала на нулевой ножке порта А, потом на первой и т.д. С некоторой задержкой, определяемой в процедуре WAIT: WAIT: dec R18 brne WAIT dec R19 brne WAIT dec R20 brne WAIT ret Данная процедура работает следующим образом: уменьшает регистр-счетчик R18 и переходит на метку WAIT, если он не стал нулем. Если он стал нулем, то пропускает эту команду и уменьшает регистр R19 и снова начинает уменьшать регистр R18. Данная процедура рассчитывается по тактам. То есть верхняя часть будет равна числу 256*3, потом умножаем это число снова на 256, потом умножаем на число, записанное в регистр R20, перед вызовом процедуры (у нас 50). Получаем 9830400 тактов, что при частоте внутреннего таймера 1 МГц даст задержку примерно 10 секунд. При частоте 4 МГц будет уже 2,5 секунды. |