вторник, 23 декабря 2014 г.

Второй урок. Простой код на ассемблере и устройство вкратце.


<< Назад к оглавлению

В данном тексте приведены ссылки на книги. "название книги":страница обозначает указатель на определенную страницу книги. "название книги":Гглава - главу. При этом ТО - сокращение для тех. описания контроллера (Datasheet). Например ТО:15 - 15 страница технического описания. ТО:Г3 - третья глава технического описания
 
Эта статья переработана. Существует так же старая версия с оболочкой MPLAB 8.91. Прочесть ее можно здесь.

Вот и ладушки, если вы читаете второй урок, то наверное, в первом вы смогли подготовить инструменты. Или и так без меня все умеете. Теперь небольшое отступление для начинающих. За более подробной
информацией, обращайтесь к серьезным книгам, особенно к техническому описанию контроллера.

Итак, что такое контроллер, и как он работает?
Конечно же, это просто черный жучек с ножками. За неимением никаких других членов, он общается с окружающим миром исключительно напряжением на ножках. Что в общем и демонстрировалось в программе в первом уроке. Просто с определенной переодичностью контроллер зажигал
светодиодик.
В расcматриваемых нами контроллерах память разделена. Программа записывается в отдельное пространство, именуемое памятью программы (PROGRAM MEMORY). Переменные и настройки хранятся в памяти данных (DATA MEMORY). Причем, ячейки памяти, выделенные для использования как переменные называются регистрами общего назначения (GENERAL PURPOSE REGISTERS или GPR) и настройки находятся в регистрах специального назначения (SPECIAL FUNCTIONS REGISTERS или SFR). Память данных поделена на 15 блоков и блоки меняются регистром BSR (BLOCK SELECT REGISTER).
Так же существует EEPROM memory - это флеш память, используемая для длительного хранения информации.
Подробнее о памяти контроллера смотри главу 1 ссылка.

Код программы


Для начала мы будем писать на ассемблере.
Если вы написали команду на ассемблере, то это будет ровно одна команда, записанная в контроллер.
Таким образом вы будете отлично знать, что ваш контроллер делает и как. А вот если вы пишете на C, то на каждую строчку, написанную вами могут приходиться сотни команд, выполненных контроллером. Знать-то нужно и то и другое, но ассемблер даст нам понимание того, что и как работает в контроллере.

Ладно, начнем.

Открываем MPLABX IDE жмем File->New Project. В открывшемся окне выбираем Microchip Embedded Standalone Project


 выбираем семейство контроллеров advanced 8 bit MRUs и наш контроллер, например pic18f2550
Next, Next.Теперь компилятор предлагает нам выбрать соответствующий набор для разработки. К этому моменту должно быть установлено все необходимое.
Первый урок на ассемблере, поэтому выбираем MPASM. Далее. Задаем имя и прочие свойства. Укажите кодировку с русским. Например. UTF-8. Иначе ваши комментарии на кириллице не сохранятся.

И вот проект открыт. По началу в нем есть только makefile. Это файл для сборки проекта. Поэтому щелкаем на Source files->new->empty file

Ну назовем его например main.asm
Переписываем туда программу. Вот код:

Листинг source.asm


  #include <p18f2550.inc> ;подключение заголовков
list p=18f2550 ; выбор контроллера
CONFIG FOSC=INTOSCIO_EC ; Выбран внутренний генератор
  CONFIG MCLRE = OFF ; отключаем сигнал сброса
  CONFIG WDT   = OFF ; отключаем сторожевой таймер

DELAYCOUNTER EQU 0x00  ; задаем две переменные для создания задержки (паузы)
DELAYCOUNTER1 EQU 0x01; в программе. Они по адресу 0x00 и 0x01
A EQU 0; под буквой A будем подразумевать, что используется access bank

ORG 0 ; начинаем с 0 адреса памяти программы
  GOTO main ; перейти на метку main
  ORG 28h ; теперь пишем с 28 адреса. (сделано это для работы с прерываниями)
main ;(начинается программа main- просто метка для нашего удобства)


  CLRF BSR,A;       ; - выбираем нулевой блок памяти данных
  CLRF PORTA,A       ; - обнуляем выход на порту а    ;

  CLRF WDTCON,A; выключаем сторожевой таймер
  MOVLW 0x0F       ; записываем 0x0F в аккумулятор
  MOVWF ADCON1,A    ; перебрасываем значение в ADCON1 - настраиваем порт A на цифровой вход/выход
  CLRF TRISA,A ;- настраиваем порт а - только на выход
  
endloop ; это цикл, в который будет без конца гонять наша программа
  BTG LATA,2,A; мигнуть светодиодом 
  CALL delay255; вызвать паузу
  GOTO endloop; вернуться к началу цикла

delay255 ; функция вызова паузы
  SETF DELAYCOUNTER,A; записать 0xFF в счетчик времени
  GOTO delay; перейти к delay
delay 
  SETF DELAYCOUNTER1,A; записать 0xFF во 2й счетчик времени
delaysub1 ;
  DECFSZ DELAYCOUNTER1,F,A; уменьшить 2й счетчик на 1. если >0
  GOTO delaysub1; то вернуться на шаг назад
  DECFSZ DELAYCOUNTER,F,A; иначе - уменьшить 1й счетчик, если >0
  GOTO delay; вернуться на метку delay
  RETLW 0; иначе - выйти из функции

END ;конец программы

Для контроллера pic18f2550
https://yadi.sk/d/1YkpyyJTVLg2V
Для контроллера pic18f4550
https://yadi.sk/d/FxMGleO_VLgp7 - к сожалению не могу сейчас проверить
для копиляции щелкаем Run->build main project

после компиляции у нас должен в папке проекта появиться HEX файл. Он находится в папке dist\default\production. Его можно и нужно прошить в контроллер. Это та же программа, что и в уроке 1.
На самом деле среда MPLABX умеет работать с программаторами, но у меня PICkit 2 и с ней она работает посредственно, поэтому я прошиваю HEX файл напрямую через PICKIT

Пояснения к коду программы



Начнем потихоньку разбирать что там написано

В самом верху указываем то, какой у нас будет контроллер
#include <pic18f2550.inc>
Мы их рлдключаем для того. чтобы вместо того, чтобы всегда и везде мы записывали цифрами. мы могли использовать некоторые уже привычные нам обозначения.
напирмер, без подключения заголовков. команда записи в регистр выбора блока (BSR) -строка 16 нашей программы выглядела бы так
MOVWF 0FE0;

так... Еще директива. 
list p=18f2550
Она просто говорит
компилятору, какой контроллер будем прошивать. 

Дальше уже интереснее. Нам нужно задать управляющее слово. это - настройки контроллера. 
Задает их директива CONFIG 
По поводу всех настроек контроллера обращаемся так же к техническому описанию. ТО:288


Конфигурационные биты


CONFIG FOSC=INTOSCIO_EC
Эта настройка говорит о том, что мы будем использовать внутренний генератор импульсов. Он - внутри контроллера. Читаем в ТО:25

CONFIG MCLRE = OFF
Здесь мы отключаем сигнал сброса. То есть контроллер будет включаться сразу с подачей на него питания.

CONFIG WDT = OFF
Отключаем сторожевой таймер. Просто. чтобы не "запариваться". Он служит защитой от зависания контроллера. Читаем в ТО:299

Более подробно конфигурационные биты рассмотрены во 2-й главе к этому уроку. ссылка

Тело программы


DELAYCOUNTER EQU 0x00
Эта директива (EQU) ставит в соответствие к DELAYCOUNTER 0x00
То есть мы пишем DELAYCOUNTER, а программа думает "0x00"
Вообще мы будем использовать DELAYCOUNTER как переменную. а 0x00 - просто адрес, где она хранится в общих регистрах.
Кстати. Забыл сказать. 0x00 - это просто число. Так мы записываем числа в 16ричной системе счисления.
то есть 0x6B = 107

Мы используем для нашей программы память, входящую в access RAM, поэтому мы вольны использовать ячейки памяти от 0x00 до 0x5F. А ячейки от 0x60 до 0xFF - это регистры общего назначения.

ORG 0
Этим мы указываем компилятору, чтобы он писал все последующие команды последовательно с адреса 0.
GOTO main
ORG 28h
main
Переходим на метку main. И начиная с 0x28 адреса пишем программу дальше. Метка main - адрес 0x28
Обратите внимание, мы оставили свободное место между адресом программы 0x1 и 0x28. Зачем? Если мы будем в последствии использовать прерывания, то в случае. если прерывание будет требовать на время приостановить программу. оно начнет выполнять команды по адресу 0x8 или 0x18. и это место нужно будет заполнить программой обработки прерывания.

Все последующие команды смотри в главе 3. Команды ассемблера. ссылка

MOVWF ADCON1
Когда мы записываем значение в регистр ADCON1. мы меняем настройки АЦП. По поводу 
использования встроенных устройств контроллера смотри главу 4. ссылка


Пожалуйста, помогите сделать статью лучше. Увидели непонятность, неточность или  ошибку, сообщите в комментарии, или напишите мне. Спасибо. Jasuramme@mail.ru

Комментариев нет:

Отправить комментарий