Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

BM8036 - удаленное управление через интернет, часть 2


Здравствуйте,

Сначала – анонс. SmartHome Masterkit MP3302 поступил на склад. Напомню, это устройство, которое позволяет контролировать с мобильного телефона различные радиоуправляемые нагрузки в доме.

В этом выпуске рассылки – доработка среды Arduino  для совместимости  с BM8036.

 Статья написана на основе ныне закрытого блога Юрия Соловьева (он располагался по адресу http://aplcino.blogspot.com/2010/12/arduino-a8036b-1.html, но сейчас доступен только в кэше Google).

Итак, приступим.

К сожалению, не существует ни одной «официальной» платы Ардуино на контроллере ATmega32, и это плохая новость. С другой стороны, разработчики IDE сделали все возможное для облегчения подключения неоригинальных плат. И разобраться с этой проблемой можно даже не имея опыта программирования микроконтроллеров.

Работа делится на несколько этапов:

- определение новой платы в boards

- прописывание ножек в pins

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

- изменение Arduino загрузчика

Все написанное в этом письме относится к Arduino IDE 1.0.3. (но нет никаких проблем повторить описанное с любой другой версией IDE). В конце письма есть ссылка на уже переработанный архив с IDE и скетча, демонстрирующего его работу.

 

 Добавление новой платы

 Файл boards.txt с определениями плат лежит в папке arduino-1.0.3\hardware\arduino.  Открываем его любым текстовым редактором и видим, что он состоит из некоторого числа похожих блоков типа

##############################################################

 atmega328.name=Arduino Duemilanove w/ ATmega328

 

 atmega328.upload.protocol=arduino

atmega328.upload.maximum_size=30720

atmega328.upload.speed=57600

 

atmega328.bootloader.low_fuses=0xFF

atmega328.bootloader.high_fuses=0xDA

atmega328.bootloader.extended_fuses=0x05

atmega328.bootloader.path=atmega

atmega328.bootloader.file=ATmegaBOOT_168_atmega328.hex

atmega328.bootloader.unlock_bits=0x3F

atmega328.bootloader.lock_bits=0x0F

 

atmega328.build.mcu=atmega328p

atmega328.build.f_cpu=16000000L

atmega328.build.core=arduino

atmega328.build.variant=standard

 

Копируем один такой блок, вставляем в конце файла и вдумчиво исправляем

##############################################################

  # название платы, как оно будет отображаться в IDE

a8036b.name=MasterKit bm8036

# характеристики для загрузчика, если пользоваться ISP, то не важно

a8036b.upload.protocol=stk500

a8036b.upload.maximum_size=30720

a8036b.upload.speed=19200

a8036b.bootloader.low_fuses=0xFF

a8036b.bootloader.high_fuses=0xDA

a8036b.bootloader.path=atmega

 

# адаптированная прошивка, если пользоваться ISP, то не важно

a8036b.bootloader.file=ATmegaBOOT_168_atmega32.hex    a8036b.bootloader.unlock_bits=0x3F

a8036b.bootloader.lock_bits=0x0F

#MCU

a8036b.build.mcu=atmega32

#Рабочая частота

a8036b.build.f_cpu=16000000L

a8036b.build.core=arduino

# Папка, где расположен файл с распиновкой

a8036b.build.variant=bm8036

 

Составление карты выводов контроллера

Для каждой определенной в файле boards.txt платы должен существовать файл с описанием, какая физическая ножка микроконтроллера соответветствует  какой ножке платы. Используя этот файл, компилятор узнает, какую ножку микроконтроллера надо дернуть в ответ на нашу команду digitalWrite(led, HIGH);.

К сожалению, в инете я не нашел мануала, как правильно создавать этот файл, поэтому во многом описанное здесь является плодом сравнительного анализа файлов для различный контроллеров.

Для создания собственного файла описаний ножек, нужно войти в папку arduino-1.0.3\hardware\arduino\variants и сделать копию папки standart вместе с находящимся там файлом. Скопированную папку переименуем в bm8036, как это определено в последней строчке boards.txt.

Открываем содержащийся в папке файл pins_arduino.h  и пробуем разобраться . что в нем написано.

Начнем с конца:

В стандартном файле (из папки standart) есть определение 3 массивов наподобии этого:

const uint16_t PROGMEM port_to_mode_PGM[] = {

            NOT_A_PORT,

            NOT_A_PORT,

            (uint16_t) &DDRB,

            (uint16_t) &DDRC,

            (uint16_t) &DDRD,

};

Но это определение сделано для контроллера ATMEL ATMEGA8 & 168, имеющего меньше портов ввода-вывода. Если сравнить с описанием ножек, например, для Arduino Mega, то видно, что групп портов там определяется больше. На принципиальной схеме Atmega32 видно, что в ней 4 группы портов (ножки начинаются с PA, PB, PC, PD). Поэтому просто добавим в определение константы еще один порт:

const uint16_t PROGMEM port_to_mode_PGM[] = {

            NOT_A_PORT,

            (uint16_t) &DDRA,

            (uint16_t) &DDRB,

            (uint16_t) &DDRC,

            (uint16_t) &DDRD,

};

Точно так же поступим с массивами port_to_output_PGM и port_to_input_PGM.

Следующие два массива, digital_pin_to_port_PGM и digital_pin_to_bit_mask_PGM создают соответствие между логическими ножками Arduino и физическими ножками контроллера. В каждом из них перечисляются все ножки, которые могут быть использованы как цифровые выходы. Массив  digital_pin_to_port_PGM определяет порт для конкретной ножки, а  digital_pin_to_bit_mask_PGM конкретный бит в этом порту.

Например, первые 4 цифровых выхода определяются следующим образом

const uint8_t PROGMEM digital_pin_to_port_PGM[] = {

            PC, // OUT 0 - 3

            PC,

            PC,

            PC,

....

 

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {

            _BV(7), //  0 PC7 -- OUT0

_BV(6), //  1 PC6 -- OUT1

_BV(5), //  2 PC5 -- OUT2

_BV(4), //  3 PC4 -- OUT3

....

 

Таким образом,  выводу D0 Arduino соответствует порт С бит 7, D1 – порт С бит 6 и т.д.

В целом у меня получилась такая таблица соответствия (за основу взята таблица Юрия Соловьева, ссылку смотри выше)

Пин Arduino

Порт ATmega32

Назначение

0

PC7

OUT0 (220-1)

1

PC6

OUT1 (220-2)

2

PC5

OUT2 (220-3)

3

PC4

OUT3 (220-4)

4

PA7

OUT4 (220-5)

5

PA6

OUT5 (220-6)

6

PA5

OUT6 (220-7)

7

PA4

OUT7 (220-8)

8

PD7

DALLAS (вход для сети 1-wire)(PWM)

9

PD0

RX

10

PD1

TX

11

PD5

BEEPER0 (микродинамик) (PWM)

12

PB0

E (шина дисплея)

13

PB1

RW (шина дисплея)

14

PB2

RS (шина дисплея)

15

PB4

SS (бывшая D4 (шина дисплея)

16

PB5

MOSI (бывшая D5 (шина дисплея)

17

PB6

MISO (бывшая D6 (шина дисплея)

18

PB7

SCK (бывшая D7 (шина дисплея)

19

PD4

BR (подсветка дисплея) (PWM)

20

PD2

TACT1S (подключен к SQW/OUT DS1307)

21

PC0

SCL (подключен к SCL DS1307)

22

PC1

SDA (подключен к SDA DS1307)

23

PA0

BAT (напряжение батареи RTC)

24

PA1

KEYS (аналоговые кнопки)

25

PA3

IN1 (вход АЦП 1 на колодке)

26

PA2

IN1 (вход АЦП 0 на колодке)

27

PD3

INT1 (свободен)припаиваем D4 (шина дисплея)

28

PD6

ICP (свободен)припаиваем D5 (шина дисплея)

29

PC2

TCK (свободен)припаиваем D6 (шина дисплея)

30

PC3

TMS (свободен)припаиваем D7 (шина дисплея)

31

PB3

OC0 (бывшая контрастность) (PWM) Выбор Ethernet контроллера

В таблице учтено, что для освобождения шины SPI потребуется переключить дисплей на свободные ножки контроллера.

ATmega32 имеет 4 аппаратных таймера, которые нужно определить в массиве digital_pin_to_timer_PGM. На принципиальной схеме нажки с таймером имеют в описании строчку типа OCxx. Для всех ножек без таймера должно быть установлено значение NOT_ON_TIMER, для ножек с таймером – TIMERxx (xx совпадает с определением таймера на принципиальной схеме).

Остальные константы в файле pins_arduino.h  определяются на основании уже созданной таблицы соответствия – по сути, это просто текстовые определения для номеров логических выводов.

 

Изменение ядра Arduino IDE

Среда Arduino подразумевает достаточно легкое подключение плат сторонних производителей на микроконтроллерах Atmel. Все, что нужно, это разобраться с директивами условной компиляции. MCU ATmega32 очень похож на микроконтроллер ATmega8, но обладает большим количеством памяти. Поэтому для обеспечения совместимости BM8036 и Arduino можно воспользоваться советом из интернета  и дополнить  директивы для контроллера ATmega8 аналогичными директивами для контроллера ATmega32.

В коде встречается два варианта директив: #if defined(__AVR_ATmega8__) и #if !defined(__AVR_ATmega8__)

 

Во всех файлах из папки arduino-1.0.3\hardware\arduino\cores\arduino сделать следующее:

 

#if defined(__AVR_ATmega8__)

надо заменить на

#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega32__)

а

#if !defined(__AVR_ATmega8__)

надо заменить на

#if !defined(__AVR_ATmega8__) && !defined(__AVR_ATmega32__)

 

Я нашел такие директивы в 5 файлах:

Arduino.h

HardwareSerial.cpp

Tone.cpp

wiring_analog.c

wiring_digital.c

Также нужно немного доработать ядро для корректной обработки TIMER0.

И небольшую доработку нужно сделать в библиотеке Servo.

Уже рабочую Arduino IDE версии 1.0.3 можно скачать здесь.

После выполненных доработок можно открыть IDE и попробовать скомпилировать какой нибудь простой скетч типа Blink. Если все пройдет без ошибок, можно приступать к следующему шагу – собственно программированию BM8036.

 

Bootloader

Bootloader – это специальная программа, позволяющая заливать скетчи прямо из среды Arduino. Написание загрузчика описано во многих статьях в интернете, я воспользуюсь текстом опять таки Юрия Соловьева из его блога:

 «Заглянем внутрь файла mkit/bootloaders/atmega/ATmegaBOOT_168.c - среди прочего, мы увидим там такой фрагмент:


#elif defined __AVR_ATmega32__
#define SIG2    0x95
#define SIG3    0x02
#define PAGE_SIZE       0x40U   //64 words

 

Думаю, нетрудно догадаться, что код бутлоадера универсален и должен работать и с ATmega32 (да что там - даже с ATmega8515 должен, если читать дальше ;).

atmega32: TARGET = atmega32
atmega32: MCU_TARGET = atmega32
atmega32: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' 
atmega32: AVR_FREQ = 16000000
atmega32: LDSECTION  = --section-start=.text=0x7800
atmega32: $(PROGRAM)_atmega32.hex


atmega32_isp: atmega32
atmega32_isp: TARGET = atmega32
atmega32_isp: MCU_TARGET = atmega32
atmega32_isp: HFUSE = DA
atmega32_isp: LFUSE = FF
atmega32_isp: isp

и проверим, как компилируется результат (в каталоге с исходником
bootloader-а):

make atmega32

Если все в порядке, там же должен появиться файл ATmegaBOOT_168_atmega32.hex

От себя добавлю, что если немного доработать код загрузчика, то BM8036 начнет мигать расположенными на плате светодиодами подсветки клавиатуры. Для этого в блоке определения светодиодов нужно добавить директиву условной компиляции для Atmega32 и скорректировать цели:

#elif defined __AVR_ATmega32__

/* только для bm8036 */

#define LED_DDR  DDRD

#define LED_PORT PORTD

#define LED_PIN  PIND

#define LED      PIND4

 

atmega32: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=4'

Правда, ложка дегтя – у меня загрузчик так и не заработал, хотя лампочками и мигал. Подозреваю, что это связано с ноутбуком, на котором работает IDE, но проверить пока не могу.


То, что будет делаться дальше, будет необратимо  для ВМ8036, так как закачать оригинальную прошивку обратно  не получится, производитель ее не дает. (Правда, можно будет купить уже прошитый MCU ATmega с оригинальной прошивкой).

 

Прошивка загрузчика

 Подготовленный  hex файл нужно прошить в микроконтроллер с помощью любого ISP программатора. Обратите внимание, что первая ножка шлейфа должна быть обращена к дисплею.

После завершения процесса плата должна замигать светодиодами.

 

Загрузка скетчей

 Если борьба с загрузчиком у вас закончится победой, то загрузка скетчей в BM8036 не будет представлять собой никаких трудностей. Нужно будет выбрать плату, com порт, и, не забывая про таблицу соответствия  выводов, загрузить скетч в контроллер.  Я опишу вариант загрузки hex файлов с помощью программатора, т.к., несмотря на работающий сом порт, Arduino мне пишет, что программатор не найден.

Для того, что бы получить hex-файл для прошивки контроллера, нужно нажать в среде Arduino кнопку Verify (левая кнопка с галочкой). После успешной компиляции проекта переходим в папку с временными файлами типа C:\Users\Administrator\AppData\Local\Temp\ и ищем в ней подпапку типа buildxxxxxxxxxxxxxxxxxx.tmp с текущей датой. Самый новый файл в этой папке и есть искомы hex файл. Он должен иметь вид project.cpp.hex, где project – название вашего проекта. Этот файл можно загрузить в Arduino/BM8036 с помощью ISP программатора. Конечно, надо не забыть выставить фьюзы:

low_fuses=0xFF

high_fuses=0xDA

В архиве вы можете скачать пример, демонстрирующий взаимодействие микроконтроллера с установленной переферией – часами реального времени, портами ввода-вывода, дисплеем, аналоговой клавиатурой, датчиком температуры.

В следующем выпуске рассылки – взаимодействие BM8036 и Ethernet Shield.

 С уважением, Сергей Китаин

electronshik.ru   единственный в России гипермаркет для электронщиков

 P.S. Обсудить тему рассылки, предложить темы  для следующих выпусков, задать вопросы можно в группе ВКонтакте или по электронной почте kitain@domko.ru

 

Приложения:

Для эксперимента использовались:

Многоканальный терморегулятор BM-8036

ISP программатор

Для следующих экспериментов нужен будет Ethernet Shield и Raspberry Pi

Переработанная Arduino 1.0.3 для работы с BM8036.

Скетч для BM8036

 


В избранное