пятница, 27 сентября 2013 г.

Урок 6. USB. Сторона компьютера

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

В прошлом уроке мы собирали прошивку для контроллера, чтобы он работал через USB. Но для взаимодействия с компьютером нам нужна еще и специальная программа, которая будет запускаться на компьютере.
Вот сейчас мы и будем ее создавать.
Опять же в пакете Microchip solutions есть пример, для нашего контроллера, но я переписал его по своему. Во-первых я сделал без использования графического интерфейса, и размер кода уменьшился раза в 3-4. Что намного лучше для изучения. Тем не менее, принцип работы один. код в стандартном примере от microchip работает так же как этот.
Программа написана в C++. Проект собран в бесплатной студенческой версии Visual C++ express 2010. Я буду давать общие идеи и комментарии по коду, но подразумеваю, что вы уже имеете хоть какой-то опыт программирования в C++.
Итак, начинаем

Здесь находится весь проект, включая исходный текст ссылка

Для того, чтобы читать и записывать данные через USB порт нам нужно получить указатель на наше устройство. Поскольку в отличие от старых портов, подключено может быть устройств свыше сотни, то получить этот указатель не так-то просто. Для того, чтобы это сделать мы будем обращаться к драйверам windows, а именно SetupAPI. Кстати, как только мы получим указатель, то будем общаться с USB портом, будто бы это файл.
Передача данных будет занимать лишь пару команд. Но вот подготовка!
Поскольку мы программируем в С++ то нам нужно быть очень аккуратными с типами данных.
Создаем консольный проект win32. И добавляем туда единственный файл main.cpp

Итак, нам необходимо подключить некоторые библиотеки.
#include <iostream>
#include <Windows.h>
#include <setupapi.h>

Так же подключаем внешнюю библиотеку:
#pragma comment (lib, "Setupapi.lib")

Первая описанная функция в программе - это getUSBHandle(). Ее описание - в комментариях кода. Да и вообще основные комментарии приведены в коде. Она служит для того, чтобы найти наше устройство и подготовить указатели, чтобы мы могли записывать в устройство и читать из него.
Если в двух словах, то она использует стандартные windows функции для доступа к драйверам USB и через них получает указатель на само устройство.
Если интересно, что все эти функции делают и как, то обращайтесь к MSDN или к книге Агурова, что лежит в оглавлении. Что важно знать: у каждого устройства есть путь, и нам важно получить его. Мы сначала проверяем, совпадает ли ID с устройством, что мы ищем. А потом находим путь устройства.Мы ищем только среди устройств HID класса. это определяется в переменной Guid. Остальное см в комментариях программы
Следующая функция - writeReadUSB. Это просто вспомогательная функция, которая записывает в наше устройство. Обращаю внимание, что запись и чтение устройства после того, как мы создали указатель на него реализуется с помощью стандартных комманд WriteFile и ReadFile
И после этого уже мы видим функцию main с которой и начинается выполнение программы. Она вызывает getUSBHandle, пока мы не получим указатель на устройство, потом читает с клавиатуры комманду и в зависимости от нее, передает и читает данные с USB устройства.
В проекте по ссылке выше лежит исходный код с комментариями и сама скомпилированная программа. Удачи.

В процессе поиска ошибки я наткнулся на библиотеку hidapi. Она является кроссплатформенной. И Только для работы с hid устройствами. Очень проста в использовании. Привожу проект под нее. ссылка.
Hidapi скачан с официального сайта. Для того чтобы начать проект нужно добавить setupapi.lib в линковщик. project->properties->linker->input и подписать туда setupapi.lib;
Удачи.
Нашел пристойное описание библиотеки здесь: http://microsin.net/programming/PC/multi-platform-hid-api.html.
Спасибо!

вторник, 20 августа 2013 г.

Урок 5. USB. Сторона контроллера

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

ВНИМАНИЕ!!! ЭТО УСТАРЕВШАЯ СТАТЬЯ. НОВАЯ ЗДЕСЬ

Все, теперь добрались мы до чего-то интересного. Протокол USB.
Наша схема будет аналогична приведенной в уроке 3 про бутлоадер. Только еще пару ножек контроллера мы будем использовать, как датчики, чтобы проверить, правда ли все у нас работает.
Нам понадобится пакет Microchip Libraries for applications ссылка Зеркало
(на данный момент актуальная версия v2013-06-15)
Качаем этот файл и устанавливаем. Для компиляции проекта нам понадобятся эти библиотеки.
Мы будем собирать пример HID - custom demos
лежит он в папке с установленной программой:
\microchip_solutions_v2013-06-15\USB\Device - HID - Custom Demos\
Внутри в папке firmware - прошивка для контроллера. В остальных - программы для компьютера.
Дело в том, что в Microchip libraries каждый проект создан для десятка разных контроллеров, и учиться на этом коде довольно проблематично. Он очень громоздкий и не последовательный.
Страница кода одна и та же, но в зависимости от того, какой проект вы откроете, для такого контроллера и будет создаваться прошивка. Изначально из наших контроллеров там присутствует только pic18f4550 и для этого нужно открыть файл проекта USB Device - HID - Simple Custom Demo - C18 - PICDEM FSUSB.mcp
Это по идее для такой учебной платы picdem fsusb. Она как раз работает на контроллере pic18f4550.
Я для удобства восприятия удалил "лишний" код, необходимый для настройки других контроллеров и чуть изменил программу, чтобы она корректно работала под pic18f2550 ссылка. Для того, чтобы программа работала, архив нужно распаковать в
\microchip_solutions_v2013-06-15\USB\Device - HID - Custom Demos\любойкаталог
, поскольку пути к библиотекам прописаны относительно к текущему каталогу.
Не дурно бы было почитать документацию к USB библиотеке. Но почему-то microchip уже давно не выпускает новый нормальный user guide. Придется воспользоваться старым. Тем не менее он даст нам идею, как работает библиотека.
лежит он по адресу ссылка  зеркало
Этот файл за 2007 год! Так что уже многие функции библиотеки даже называются по-другому.
Примерно философия работы следующая:
Контроллер наш, поскольку имеет аппаратную поддержку протокола USB имеет в своей памяти определенные места, в которые нужно записать настройки usb. это первый главный момент. В основном все это находится в файле usb_descriptors.c. Вы можете открыть этот файл и посмотреть комментарии или даже отредактировать.
Потом, важно грамотно настроить биты конфигурации. И в теле программы мы будем вызывать функцию USBDeviceTasks(), которая выполняет в общем-то всю работу по обмену информации через USB.
Плюс, нужно определить некоторые стандартные функции, которые вызываются при получении нашим устройством различных команд, в момент подключения к хосту например. без них, устройство так и не сможет обнаружиться. Эти команды находятся в самом низу файла main.c и особенно здесь не рассматриваются, так как они осуществляют рутинную стандартную работу и вы будете вряд ли их менять.
На данный момент библиотека работает следующим образом:

Функция USBDeviceTasks()

Для того, чтобы поддерживать работу USB, когда хост обращается к устройству с сообщением, в течение определенного времени устройство должно дать ответ. В случае, если это не происходит, хост может просто отключить наше устройство, посчитав его сломанным.
Чтобы обработать usb сообщение и выслать ответ, нужно вызвать функцию этой библиотеки:
USBDeviceTasks(); ну и чтобы отправилось правильное сообщение надо подготовить буферы вывода и прочее.
В нашем примере мы просто циклически будем вызывать эту функцию. Есть и другой выбор: для того, чтобы вовремя давать ответ хосту, можно использовать прерывания, но я опишу это потом, если будет время.
Если мы просто периодически вызываем функцию USBDeviceTasks(), то обычно ее надо вызывать не реже, чем 1.8мс. Иногда бывают исключения из этого правила. Смотри комментарии usb_device.c для тог, чтобы узнать, что это за исключения.
Обычно вызвать USBDeviceTask() не требует много времени. Около 100 тактов процессора.

USB дескрипторы

Для корректной работы нашего устройства нужно будет задать USB дескрипторы. В общем-то это описание нашего устройства. Они содерждат класс устройства, в нашем случае это - HID (Human Interface Device, которым могут быть мышки, клавиатуры, или вообще любое устройство) и имя устройства. Все эти параметры заданы в файле usb_descriptors.c, который уже добавлен в проект. Перед началом работы хост с устройством обмениваются дескрипторами, это дает понять, каким образом будет осуществляться взаимодействие устройств.

Hardware profile

Файл hardware profile содержит информацию о том, какой контроллер или плату мы используем. Плюсо к нему microchip обычно добавляет файл конкретного контроллера. Например HardwareProfile - PICDEM FSUSB.h. В этом файле хранятся различные функции и адреса, связанные с аппаратной частью контроллера. Например, функция инициализации АЦП. В ней непосредственно указано, какое значение должно быть присвоено регистрам АЦП и на какую ножку будет подаваться напряжение.

Комментарии к программе

Все основные комментарии приведены мной в коде в файле main.c. Здесь лишь пара слов.
Когда мы открываем проект, перед нами будет следующий набор файлов:
lkr файл - файл линковщика. Он говорит о том, как и которую память можно использовать.
Плюс некоторые настройки usb протокола задаются в файле usb_config.h
На мой взгляд это дерево файлов и логика - далеко не идеальные, но это то, что предлагает microchip.
Далее логика работы программы сохранена, чтобы разобравшись с этой программой вам было легче понять другой похожий пример от microchip.
Основные функции программы:
void YourHighPriorityISRCode() - прерывание высокого уровня
void YourLowPriorityISRCode() - прерывание низкого уровня
void main(void) - главная функция
static void InitializeSystem(void) - инициализация контроллера (задание настроек)
void UserInit(void) - то же самое
void ProcessIO(void) - тело программы, где происходит вся обработка и расчеты
WORD_VAL ReadPOT(void) - функция вызова Аналого Цифрового Преобразователя
Далее будем рассматривать файл main.c, в котором находится наш исполняемый код. это сделано в самом файле в комментариях. 

проект для контроллеров pic18f4550 и pic18f2550 ссылка
Здесь для поддержки USB интерфейса используются прерывания.
Так же выкладываю проект, где еще больше кода удалено, чтобы дать идею, как программа работает. Здесь прерывания не используются, а просто периодически вызывается функция поддержки usb интерфейса.
Уменьшенный вариант: ссылка
Проект обязательно нужно распаковать в папку 
\microchip_solutions_v2013-06-15\USB\Device - HID - Custom Demos\любойкаталог
потому что там довольно жестко задаются пути к библиотекам
Этот проект работает с обоими контроллерами (только что проверил) с бутлоадером и без него.
Для того, чтобы проверить, работает ли наш пример, запускаем утилитку 
\microchip_solutions_v2013-06-15\USB\Device - HID - Custom Demos\HID PnP Demo.exe
она должна найти ваш контроллер.
В следующем уроке мы будем рассматривать как раз эту программу для компьютера, которая пересылает информацию контроллеру. То есть USB интерфейс на стороне компьютера.

среда, 10 июля 2013 г.

Урок 4. Простая программа на C

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

ВНИМАНИЕ! ЭТО УСТАРЕВШАЯ СТАТЬЯ! НОВАЯ ЗДЕСЬ

Для нашей следующей программы понадобится компилятор Си. Его можно скачать в оглавлении. Так же понадобится файл линковщика для нашего контроллера. На всякий случай выкладываю его сюда.
pic18f2550
без бутлоадера Ссылка
с HID бутлоадером Ссылка
pic18f4550 
без бутлоадера Ссылка
с HID бутлоадером Ссылка
Файл линковщика .lkr говорит компилятору, какие библиотеки подключать и как использовать память контроллера. Например, если мы используем описанный в прошлом уроке бутлоадер, то мы должны подключить файл lkr с HID бутлоадером, и он сообщит компилятору, что программа должна располагаться после бутлоадера - с адреса 0x1000.

Итак, создаем проект в MPLAB
Это делается примерно так же как во втором уроке, только выбираем проект C и добавляем файл линковщика
Файл линковщика говорит о том, как мы собираемся использовать память контроллера. Поэтому и отличаются эти файлы, если мы используем бутлоадер или нет.
Далее привожу код программы. Это аналог программе, написанной в уроке 2.
#include <p18f2550.h>

#pragma config WDT = OFF //
#pragma config FOSC=INTOSCIO_EC // Выбран внутренний генератор
#pragma config MCLRE = OFF // отключаем сигнал сброса



#define REMAPPED_RESET_VECTOR_ADDRESS         0x1000
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x1008
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS         0x1018
void main (void);

#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
void _reset (void)
{
   main();
}
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS

void Remapped_High_ISR (void)
{
    _asm NOP _endasm
}
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS

void Remapped_Low_ISR (void)
{
    _asm NOP _endasm
}

#pragma code page
void delay(void)
{
long i;
for (i=0;i<100000;i++);
}

void main (void)
{
  
  TRISA = 0;

  PORTA = 0;

  while (1)
  {
  PORTAbits.RA2 = 1;
  delay();
  PORTAbits.RA2 = 0;
  delay();
}
    ;
}

Все обозначения вроде портов и встроенных устройств можно найти в файле p18f2550.h или p18f4550.h.
директива #include <p18f2550.h> подключает заголовки для контроллера
#pragma config - Это опять же выбор конфигурационных битов для контроллера. См урок №2.

#define REMAPPED_RESET_VECTOR_ADDRESS         0x1000
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x1008
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS         0x1018

Эти три похожие строки говорят нам, что программа будет начинаться с адреса 0x1000, высокоприоритетное прерывание - с 0x1008 низкоприоритетное - с 0x1018. 
Это сделано с одной целью - для того, чтобы программа могла быть прошита с помощью бутлоадера. Как было написано в предыдущем уроке, бутлоадер занимает ячейки до адреса 0x1000 и следовательно наша программа должна начинаться после его кода. 
Ну и все прерывания бутлоадер будет отправлять по алресу 0x1008 и 0x1018

#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
void _reset (void)
{
    main();
}

Вот эти строки говорят, что следующий код будет начинаться именно с указанного адреса. В данном случая директива #pragma работает как команда ассемблера .ORG - то есть просит компилятор записать следующий код с определенной ячейки памяти. Вообще программа начнется с функции _reset. Потому что она идет первая по порядку. адрес 0x1000. Но после нее следуют еще прерывания. Поэтому когда происходит сброс контроллера, эта функция просто "перепрыгивает" код прерываний и запускает код за ними.
Но можно задать расположение программы в памяти еще с помощью скрипта линковшика. Посмотрите на эту строку.
#pragma code page
Это обозначает, что дальше будет программа записана в ту область, которая размечена в файле *lkr, как page

void delay(void)
{
long i;
for (i=0;i<100000;i++);
}
Вот это задается функция задержки. Она просто мотает переменную i до 100000 и ничего при этом не делает.
Вызывается функция следующей командой
delay();

void Remapped_High_ISR (void)
{
     _asm NOP _endasm
}

Эта функция - прерывание. В нашем случае она ничего не делает. Но вы можете добавить код обработки прерываний сюда.
 _asm

_endasm
Это позволяет использовать код ассемблера внутри программы на С

Файлы проекта:
 кода на С ссылка
https://yadi.sk/d/OeZ6mXRHVMZcF

суббота, 6 июля 2013 г.

Урок 3. Использование Bootloader'a

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

Окей, это будет первый шаг к освоению USB интерфейса.
Есть такая интересная штука. Называется бутлоадер. Что это такое?
Это программа, которая вшивается в начало памяти контроллера и позволяет его программировать.
То есть, для того, чтобы прошить контроллер теперь не нужно будет подключать программатор. Но мы с вами при этом расплатимся памятью программ, так как 0x1000 ячеек будет занято бутлоадером. Итак, к делу.
Интерфейс USB довольно капризный, так что все, что связано со стабильностью USB должно быть собрано очень аккуратно. Кварц должен быть добротно соединен с ножками контроллера.
Я вообще советую вам купить USB розетку, примонтировать ее на плату, чтобы всегда быть уверенным, что контроллер качественно соединен с портом USB.
на всякий случай даю вам распиновку порта
Взято из википедии.
Схема подключения контроллера pic18f2550

Сразу поясню, что когда мы выключатель sw2 замыкаем на землю, наш контроллер будет входить в режим бутлоадера, то есть прошивать. А если sw2 переключен на +5 то, контроллер будет пытаться запустить нашу программу
Схема подключения контроллера pic18f4550

Прошиваем контроллер следующим файлом
для pic18f2550 ссылка
для pic18f4550 ссылка
это прошивки, скомпилированные из исходников из официального пакета microchip solutions. Правда я поменял некоторые настройки.
Теперь качаем программу для работы с бутлоадером
linux ссылка
Для линукса я пока что не проверил.
Так вот, запускаем эту программу и в идеале мы должны увидеть это:
Кроме того, контроллер должен замигать светодиодом. Если программа не определяет ваш контроллер, то проверьте полярности и ищите ошибку в схеме.

Теперь о том, как это работает. Мы попробуем запустить нашу программу из урока №2. Только ее нужно немного изменить. 
Если бутлоадер получает команду запустить нашу с вами программу (sw2 замкнут на +), то он делает переход на адрес 0x1000 откуда, и будет начинаться теперь наша программа. А векторы прерывание соответственно будут перемещены из 0x8 в 0x1008 и из 0x18 в 0x1018
для того, чтобы изменить нашу программу нужно поменять 
org 0 на org 0x1000
и org 0x28 на org 0x1028
И программа теперь будет начинаться в аккурат после бутлоадера
Вот исходный код новой программы
Причем мы можем использовать для прошивки этих двух контроллеров через бутлоадер один и тот же HEX файл, так как он не будет проверять соответствие контроллера и не будет менять конфигурационные биты.
Если у вас все получилось, то у вас при запуске контроллера должен мигать светодиод на порту RA2 как в уроке 2. 
Для того, чтобы снова прошить контроллер через бутлоадер, замкните переключатель sw2 на землю.
Чтобы прошить выбираем
File->import firmware image 
выбираем hex файл
После этого нажимаем program->Erase/Program/Verify device
перезагружаем контроллер
Поздравляю - у вас работает первая USB программа, хоть пока что и написанная не вами

Собрать бутлоадер самому

На всякий случай выложу готовый проект, по которому можно собрать бутлоадер самому. Вдруг вам нужно изменить USBDIV конфигурационное слово, если у вас кварц не 20МГц, или кнопку, на которую надо нажать для пуска бутлоадера.
Пару слов о проекте. Это бутлоадер из MLA 2015_08_10. Microchip добавили такую опцию - при удачной прошивке по адресу 0x1006 записывается подпись. Это слово GOOD (0x600D). Расчет идет на то, что компилятор обычно ничего не хранит в этом адресе, а делает GOTO на основную часть программы. Тем не менее, это проблема, если вы пишете на ассемблере. Поэтому, если вы хотите нетронутую версию бутлоадера - установите MLA и соберите из него.
Еще одно. Бутлоадер собирается только с XC8 компилятором версии PRO. А воровать его с какого-нибудь всем известного сайта - это ай-яй-яй.
Ссылка на проект бутлоадера
https://yadi.sk/d/xYAFgZaDjFr4V

среда, 3 июля 2013 г.

Урок 2 глава 4 Работа со внутренними устройствами контроллера

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

Наш контроллер просто напичкан всякими трясучками и прибамбасинками.
Я вкратце расскажу как их использовать.
Смотрим на схему подключения нашего контроллера

то, что подписано рядом с ножками контроллера - это то, как их можно использовать.
так же, начиная со страницы ТО:14 дано описание возможностей ножек контроллера
Если вдруг у вас что-то работает не так, как надо, может быть, что один из этих модулей не включен или не выключен. Ну, например, у вас на ножке RA0 включен модуль АЦП, и вы не можете вывести на эту ножку сигнал плюс. Что делать?
Смотрим. На ножке, которая нас интересует есть только АЦП и цифровой ввод вывод. Отключим АЦП.
Смотрим по ТО. Ищем АЦП то есть по-буржуйски это будет ADC. Analog to Digital Converter
это у нас глава 21. Читаем. Там нам пишут регистры ADRESH и ADRESL - это для того, чтобы считывать результат с устройства.
а вот ADCON0 ADCON1 ADCON2 - есть регистры для управления этим модулем.
Читаем про них
так-с. ADCON0 bit0 = 0 -A/D converter disabled - то, что надо
А вот и включение и выключение АЦП на конкретных ножках - ADCON1 биты 3-0
мы запишем туда единички и АЦП на всех ножках будет выключен. читай ТО:262
MOVLW 0x0F 
MOVWF ADCON1 
С остальными модулями - аналогично. Читайте ТО, там все понятно.
Ну другое дело, конечно модули типа USB. Там все хуже. Но об этом в следующих уроках.

Урок 2 глава 3 Команды ассемблера

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

Я думаю, что не имеет смысла сильно расписывать то, что и так очень хорошо опубликовано.
Возьмите самоучитель за авторством Корабельникова, указанный в списке литературы в оглавлении. Там все крайне доступно объяснено.  Зеркало
Я сделаю здесь только краткий очерк. Список всех команд, поддерживаемых контроллером приведен в ТО:309 главе 26 instruction set.
Там даны краткие примеры по использованию команд.
Практические все логические операции производятся через специальный регистр - аккумулятор. Для того, чтобы записать туда число можно использовать такую команду:
MOVLW число
и потом, вы можете сложить это число с еще одним. И уже только после этого - записать его из аккумулятора в другой регистр.
Так же наш контроллер поддерживает умножение. Для умножения, надо множители записать в специальные регистры.
Управляют портом ввода-вывода те же регистры.
TRISA говорит о том, на ввод или на вывод будет работать порт А.
PORTA - выводит информацию на ножки порта А если оный работает на вывод. И с него можно считать состояние порта, если оный работает на ввод.
Кроме того могут быть дополнительные флаги, которые говорят о том, куда записывается результат выполнения команды, какую область памяти мы используем (BSR или access bank). Конкретнее смотрите в главе instructions set в ТО.

вторник, 25 июня 2013 г.

Урок 2. Глава 2. Биты конфигурации


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


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

Итак. Конфигурационные биты. или управляющее слово. Здесь мы будем подразумевать, что это одно и то же.
Грубо говоря, это - критические настройки контроллера. Без многих из них, он вообще корректно работать не будет, и это - одна из причин, почему эти настройки нельзя изменять по ходу изменения программы.
Конфигурационные биты задаются в коде с помощью директивы CONFIG
Так же их можно задать непосредственно в среде разработки MPLAB
Если слева сверху убрать галочку биты задаются в коде программы, то вы сможете менять биты прямо в этом окошке. Щелкаете - и справа будет контекстное меню, позволяющее выбрать настройки.
Обратимся к программе, написанной в уроке 2.

Генератор тактовых импульсов


Первая настройка:
CONFIG FOSC=INTOSCIO_EC ; Выбран внутренний генератор
Для того, чтобы наш контроллер работал, ему нужны тактовые импульсы. С поступлением каждого импульса, контроллер совершает одну операцию.
В нашем контроллере есть внутренний генератор импульсов. Сейчас он и выбран
если мы напишем
CONFIG FOSC=HS 
то будет выбран внешний высокоскоростной генератор. Его надо подключить между ножками OSC1 и OSC2, что и указано в первом уроке. В случае, если мы используем внутренний генератор, то мы можем использовать ножки OSC1 и OSC2 по своему усмотрению.
Типы генераторов даны в ТО:25


Сигнал сброса


Следующая настройка - сигнал сброса
CONFIG MCLRE=OFF
В случае, если сигнал сброса включен, то контроллер будет работать только в случае положительного потенциала на ножке MCLRE. А в случае, если эта ножка получит отрицательный потенциал, то контроллер перезагрузится - сбросится. Мы эту опцию отключаем. В нашем случае контроллер будет работать сразу после получения питания. а ножку MCLRE мы можем использовать как цифровой вход-выход.

Сторожевой таймер


В нашей настройке сторожевой таймер так же выключен
CONFIG WDT=OFF
Сторожевой таймер - это своеобразная защита от зависания.
Таймер отсчитывает некоторое время, если за определенный промежуток оного, он ни разу не получил от нас сигнал, что все в порядке. таймер перезагружает контроллер. С помощью команды CLRWDT мы обнуляем таймер. и как бы говорим программе, что все в поряде.
Мы пока не будем использовать сторожевой таймер.
Описание таймера: ТО:299

Ну и пока все. Это все настройки, которые использованы в примере в уроке 2. Быть может я добавлю сюда потом еще информацию.
Еще скажу, что настройки, которые вы можете задать. хранятся в файле заголовков. P18F2550.inc например. А так же можете посмотреть в configure->configuration bits.
Удачи
По поводу всех настроек контроллера обращаемся так же к техническому описанию. ТО:288

Конфигурационные биты на Си (MPlABX)

Необходимо их настроить. Для этого идем в Window->PIC memory views->configuration bits

откроется окно, и выставляем там FOSC=INTOSCIO, WDT=OFF, MCLRE=OFF
Щелкаем правой клавишей и Generate Source Code to Output. Эта опция создаст код, необходимый для задачи конфигурационных битов. 
Копируем код, создаем файл заголовков config.h и вставляем сгенерированный код в конец файла.


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

Урок 2. Глава 1 Устройство памяти


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


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

Устройство памяти контроллера


Контроллер - это лишь устройство, которое шаг за шагом выполняет команды. Команды записаны в памяти контроллера и выполняются по очереди.
Команды записаны в понятном контроллеру машинном языке - столбик 2 следующего листинга. Cправа приведено, как эти команды записываются в ассемблере
Внутри контроллера
Адрес ячейки Содержимое ячейки     
0x001               0x0e00
0x002               0x6ee0
0x003               0x6a80
0x004               0x6a92
и так далее...
Описание
Соответствующая команда ассемблера    
movlw 0           ;записываем в аккумулятор 0
movwf BSR      ;аккумулятор -> выбор блока
clrf PORTA      ;обнуляем выход порта А
clrf TRISA        ;настраиваем порт А на вывод

Второй столбик - это машинный код, в шестнадцатеричной системе счисления.
Это и есть команды, записанные в памяти программы.

Но кроме памяти программы (PROGRAM MEMORY) есть еще память данных.
В памяти данных во-первых хранятся настройки для нашего контроллера. Собственно, это просто переменные, меняя которые вы меняете какие-то установки. И еще в памяти данных мы будем создавать переменные. То есть, если программе что-либо надо запомнить, она записывает это в память данных (DATA MEMORY).
То, где хранятся настройки контроллера называется регистрами специального назначения - SPECIAL FUNCTIONS REGISTERS (SFR), а то, что мы используем, как переменные - регистры общего назначения - GENERAL PURPOSE REGISTERS (GPR).
стоит еще отметить, что память поделена на 15 банков в каждом по 16x16 ячеек. для того, чтобы выбрать другой банк данных есть регистр выбора банка BANK SELECT REGISTER (BSR).
Для многих команд можно использовать адрес напрямую, с помощью регистра BSR или же с помощью access банка. При обращении в access bank, до адрес 0x60 мы попадаем в 1й банк. В остальных адресах мы попадем в банк 15. Регистры специального назначения. Когда мы задаем команду в ассемблере мы можем поднять флаг A (0) или B (1) для указания будем ли мы использовать BSR или же access bank. Конкретнее смотрите в ТО в главе instruction set.

 Стоит вам записать в него 2, вы тут же начинаете использовать второй банк регистров.
Предлагаю вам самим это посмотреть обратитесь к Тех Описанию. ТО:59 и ТО:65


пример выбора блока регистров
movlw 0x5    ;записываем 5 сначала в аккумулятор
movwf BSR  ;из аккумулятора передаем значение в BSR регистр
Еще есть EEPROM память, которая спользуется для длительного хранения данных. Но об нёй не сейчас.

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

понедельник, 24 июня 2013 г.

ОГЛАВЛЕНИЕ. Программирование микроконтроллеров pic18f2550 pic18f4550 с нуля. USB интерфейс. CAN и PIC контроллер


Это небольшое руководство ставит своей целью обучить работе с контроллером pic18f4550 и pic18f2550 вплоть до реализации протокола USB и CAN. В уроки входят небольшое объяснение архитектуры и работы на ассемблере и языке C. Учебный пример USB устройства с комментариями. Литературы по поводу азов программирования этих контроллеров достаточно, поэтому основы даны в сжатом виде.

Если вы увидели какую-нибудь неточность, или ошибку - пожалуйста сообщите. Или спрашивайте. С уважением, автор.  Может какие-нибудь битые ссылки. jasuramme@mail.ru

Оглавление:

Работа и отладка в пакете MPLABX ссылка
1. Урок №1. Подготовка инструментов. ссылка
2. Урок №2. Простой код на ассемблере и устройство вкратце. ссылка
       2.1 Глава 1. Устройство памяти. ссылка
       2.2 Глава 2. Биты конфигурации. ссылка
       2.3 Глава 3. Команды ассемблера. ссылка
       2.4 Глава 4. Работа со внутренними устройствами контроллера ссылка
3. Урок №3. Использование Bootloader'a ссылка
4. Урок №4. Простой код на C (компилятор XC8) ссылка
5. Урок №5. USB. Сторона контроллера (Компилятор XC8) ссылка
5. Урок №6. USB. Сторона компьютера ссылка
5. Урок №7. CAN интерфейс и контроллер 18f2550 ссылка
Наши друзья:
CDC USB устройство на PIC18F4550 ссылка

Список рекомендованной литературы

1. Документация на контроллеры (техническое описание) pic18f2550 и 18f4550 ссылка  Зеркало.
2. Сайт товарища Корабельникова по программированию контроллеров . Зеркало
3.  Б.Брей. Применение микроконтроллеров PIC. Зеркало
4. Документация по программатору pickit2 ссылка

Список программного обеспечения

1. Пакет MPLABX ссылка зеркало
2. Компилятор XC8 ссылкан зеркало
3. Microchip Libraries for Applications (MLA) Ссылка зеркало

Устаревшие программы
1. Пакет MPLAB 8.91Зеркало
2. Компилятор pic18С Зеркало

Новости:

22.09.2015 Добавлен проект бутлоадера для сборки с XC8. Вырезана дебильная подпись об удачной прошивке.

12.01.2015 Переделана статья про CAN для компилятора XC8. Плюс, код стал более аккуратным, и во многом переделан

09.01.2015 Переделана статья USB сторона контроллера под компилятор XC8

28.12.2014 Переделаны статьи с простым кодом на ассемблере и на си под среду MPLABX и компилятор XC8 (для си). Старые статьи сохранены. Ссылки в новых статьях в самом начале. Старые версии уже не поддерживаются, и уже на официальном сайте их нет.  Так что в плане переделать статьи для USB и CAN. И добавить тему по отладке в MPLABX.

пятница, 21 июня 2013 г.

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


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

Внимание! статья несколько устарела. Теперь будет рассматриваться работа с более современной средой MPLABX


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

Пакет MPLAB 8.91. Можно скачать с официального сайта. Новый MPLABX довольно неповоротливый. Можно скачать здесь. Зеркало


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

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

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


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

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

Открываем MPLAB жмем project->project wizard,

 выбираем модель контроллера, и в качестве среды - MPASM Toolsuite
Далее. Щелкаем browse. указываем там папку проекта и имя. Никаких файлов пока что не добавляем. Next и finish.
File->new.
Сохраняем его в папку проекта с расширением asm.
Далее щелкаем правой на папке sources и добавляем его в проект..

Переписываем туда программу. Цифирки слева следует убрать. Вот код нашей первой программы:

Листинг 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 - к сожалению не могу сейчас проверить
для копиляции щелкаем project->make или project->build all (F10)
Программа вас спросит. какие у нас настройки, переносимые, или абсолютные. Щелкаем абсолютные. Переносимые - это для того, чтобы нашу программу можно было запускать на разных устройствах. Еще нужен будет линковщик.
после компиляции у нас должен в папке проекта появиться HEX файл. Его можно и нужно прошить в контроллер. Это та же программа, что и в уроке 1.

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



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

В самом верху указываем то, какой у нас будет контроллер
#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

четверг, 13 июня 2013 г.

Первый урок. Подготовка инструментов


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

Тут будет опубликовано несколько уроков по программированию pic18f контроллеров. Начнем с самого начала для самых чайников. Пишу я эти уроки, потому что было очень проблематично найти материал для начинающих. Очень многое устарело, или просто не описано.

Первый урок. Подготовка инструментов.

Внимание! Понятие "земля" для нас - это всего лишь общий провод, подключенный к +0 V (отрицательный провод USB, например). Не надо вкапывать металлическую пластину на метр в землю

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

Мы не будем здесь ничего объяснять. Только готовим все инструменты и контроллеры для работы. Весь теоретический материал - в следующих уроках.



Если вы совсем ничего не знаете про контроллеры, советовал бы вам прочитать что-либо из следующего. Для удобства буду дублировать ссылки из моего личного архива.

Вот сайт, на котором товарищ Корабельников прячет свои учебники по микроконтроллерам для новичков. Прошу только не перенимайте его мировоззрения по поводу оптимизации и написания кода. И да. Прошу прощения за вырвиглазность дизайна. Зеркало
Я начинал с книжки "Микроконтроллеры - это же просто!". Но это по другому семейству контроллеров.
Или же Б.Брей. Применение микроконтроллеров PIC. Зеркало
В общем, какую-нибудь литературу стоит поиметь под рукой, чтобы в случае каких-либо непонятностей обращаться к ней.
И качаем документацию на семейство контроллеров pic18f2550 с официального сайта. И на программатор. Зеркало Программатор

Этот блог посвящен программированию микроконтроллер семейства pic 18F. Все примеры будут рассматриваться на контроллерах pic 18f4550 и pic 18f2550.
На данном этапе примеры на ассемблере компилируются под виндой и линуксом. А на Си - только под виндой.
Что необходимо для начала? естественно, сам микроконтроллер. Как вы увидите ниже, если вы купите контроллер другого типа, то не будет особых проблем запустить программу на нем. Но это, к сожалению требует некоторых умственных усилий, и поэтому если вы раньше не имели дела с подобной техникой, то наверное стоит использовать указанное ниже.

Итак:
1. Контроллер PIC18f2550 или PIC18f4550.

2. Программатор для этого типа контроллеров: у меня - PICkit2. он шьет тучу разных PIC чипов. Более новые версии наверное еще лучше.

3.Потом нам необходима плата, на которой мы будем собирать схемы.
Я советую что-то такое. Паять в большинстве случаев не надо. Купите еще наборчик перемычек для нее. Ну если вы решите паять, то в этом конечно ничего плохого нет.
4. Набор радиодеталей для схемы, которая находится ниже.

5. Пакет MPLABX. Ранее в блоге рассматривался MPLAB 8.91. В соответствующих разделах будут указаны ссылки на статьи со старой средой. Скачать же MPLABX можно здесь зеркало

6. Компилятор PIC18 Зеркало

Если вы используете linux, то вам понадобится что-то типа pk2cmd и gputils.

Ну и конечно, скорее всего вам понадобятся такие вещи, как плоскогубчики, ножичек, изоленточка, паяльничек, и.т.д...
Питание мы будем брать от USB порта компьютера.

Схема подключения для контроллера pic18f2550:


Скажу еще, что это не просто откуда-то скачанные чертежи. Это все работает у меня на макете.
Ниже - схема для контроллера pic18F4550



В принципе, нет никаких особых требований для сбора этой схемы. Кварц желательно должен быть как можно ближе к контактам. И вообще, надо бы аккуратно собрать линию его подключения. Лично я припаял кварц вообще к сокету, в который вставляется контроллер. Но навряд ли это необходимо.

Итак, собрали?
Теперь надо будет его прошить и проверить. 
Я использовал pickit2.
Вот распиновка контроллеров из официальной документации:
И вот распиновка программатора pickit2. 

Подключаем пины программатора к соответствующим пинам на контроллере и прошиваем следующими файлами:
Естественно, на контроллер напряжение подавать не надо, втыкаем программатор в USB
Пример для pickit2.
запускаем.
Возможно, что сначала контроллер или программатор неопределен. щелкаем Tools->check communication. проверяем, правильно ли мы все подключили. Пока не появятся такие сообщения:
Рядом с device должна быть написана модель вашего контроллера, а 
Pickit found and connected.
щелкаем file->import hex выбираем hex file, и молимся об удачной прошивке.
Прошили.
это простая программа для проверки, работает ли ваша схема. Она мигает светодиодиком на порту RA2.
Поэтому чтобы проверить работу вашего микроконтроллера, подключите +светодиода на ножку RA2 микроконтроллера, и минус через резистор 1КОм на землю. А то чего доброго - сгорит светодиод. При подключении питания, он должен мигать.
Если ничего не работает, попробуйте эту прошивку
Тут используется внутренний генератор импульсов. То есть, если второй пример работает, а первый нет, то у вас какая-либо проблема с кварцем.

Работает? поздравляю с первой программой.