В данном тексте приведены ссылки на книги. "название
книги":страница обозначает указатель на определенную страницу книги.
"название книги":Гглава - главу. При этом ТО - сокращение для тех.
описания контроллера (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