Глава 2.
Программирование микроконтроллера.
Часть 1 (теоретическая).
Приступим к программированию микроконтроллера. Это не самая сложная часть, здесь нет ничего, что могло бы стать непреодолимой преградой. Поясню почему я выбрал Bascom для AVR - это достаточная простая и понятная программа-компилятор для составления микро-программ, которые работают (и они работают кстати сразу) в микроконтроллерах. В качестве образца выберу ATMega16, почему? Потому что у него очень много полезных и программируемых вводов-выводов (ножек), хотя дальше покажу - как просто переделать нашу программу под ATMega8 (она покомпактнее и подешевле).
Запустим Bascom и создадим новую программу:
просто щелкнем по кнопке с иконкой и
создадим новый "документ".
У вас программа будет называться noname1, у меня - noname4, просто у меня было создано до этого несколько программ.
Скопируйте отсюда и перенесите в новую программу следующие строки:
$regfile = "m16def.dat"
$crystal = 4000000
$baud = 19200
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40
Так же как на рисунке:
Сразу поясню что эти строки делают: это "конфигурационные" строки, они определяют тип микроконтроллера ("m16def.dat"), частоту кварцевого резонатора (4000000, обратите внимание - частота указывается как 4 миллиона(!) Герц, Герц не пишется), 19200 - скорость, с которой будут передаваться данные по Сом-порту. Дальше может указываться тип LCD дисплея, но поскольку в нашей конструкции LCD-дисплей не предусмотрен, мы его прописывать не будем (и экономия места, и веса и времени).
Что означают цифры 10 и 40 я хрен его знает, на программный код (мой) они не влияют, но по традиции я их всегда вношу. Если кто желает копнуть глубже - мое почтение тому.
То есть, если бы мы написали не "m16def.dat" а "m8def.dat", программа составлялась бы для ATMega8 (просто да?), если мы укажем не 4000000 а 8000000, то частота микроконтроллера будет программироваться на частоту 8МГц, а если укажем не 19200 а 9600 - то скорость работы порта будет 9600 бод.
Где посмотреть название типа микроконтроллера? А прямо в той папке куда установился Bascom (У меня это путь: C:\Program Files\MCS Electronics\BASCOM-AVR). Все файлы с расширением *.def - являются файлами-конфигурациями контроллеров.
Добавим в нашу программу еще несколько строк:
Ddra = $ff
Ddrb = $ff
Ddrc = $ff
Ddrd = $ff
Portb.4 = 1
Wait 1
Portb.4 = 0
Start Adc
Waitms 100 ' Wait for UART module to stabilize
Do ' Endless loop
Loop
Так-же как на рисунке:
И нажмем кнопку для компиляции программы (обозначена стрелочкой). Поскольку мы только начали проект, программа попросит вас сохранить документ:
Выберите папку "куда" и сами запомните, иначе потом будете ее искать. Нажмите "Сохранить", после программа откомпилирует ваш код. Поскольку в коде ошибок нет, то компиляция завершится успехом. У вас появился готовый файл для прошивки в контроллер:
Это файл "noname4.hex" (у вас "noname1.hex"). Программатор понимает такой формат и его можно спокойно "залить" в контроллер, но... наша программа откомпилирована, только она ничего не умеет делать. Это учебный пример. По этому - не спешите "заливать", можно посмотреть как она работает и на компьютере (заодно исправить ошибки, если они есть или изменить код, если что-то передумали). Найдите дистрибутив Протеуса и поставьте его (его поиск, выкачивание и установка не займет слишком много времени).
Итак - Протеус у вас установлен. Запускаем его (он называется "ISIS 7 Professional", есть еще "ARES 7 Professional" - это дополнительный модуль программы-тассировщика плат, она нам не нужна) и получаем "Рабочий стол":
Он изначально пустой, для работы с программой щелкните куда указана красная стрелка и выберите компонент (наш микроконтроллер):
Нажмите "ОК":
И щелкните в любом пустом месте "рабочего стола" программы ОДИН раз, появится бледный контур компонента:
Переместите его в нужное место и щелкните еще раз, так вы его закрепите на "Рабочем столе":
Да, это вполне "настоящий" микроконтроллер ATMega16, и он-то и будет работать с написанной нами программой.
Теперь загрузим в него нашу программу, для этого на компоненте щелкните правой кнопкой мыши (этим вы вызовете контекстное дополнительное меню):
Выберите "Edit Properties" и откроется модуль настройки нашего контроллера:
Видите куда показывает красная стрелочка? Это выбор пути к файлу микропрограммы. Щелкнем и найдем его (я говорил, чтобы вы ту папку, куда в Bascom-е сохранили файл, запомнили?), найдя - выбираем:
И возвращаемся обратно в модуль настройки:
Дополнительно надо установить частоту работы микроконтроллера на 4МГц(отмечено зеленым овалом):
После чего жмем "ОК", и возвращаемся на "Рабочий стол".
Пришла пора запустить нашу программу. Для этого нажмите на кнопку справа-внизу (указана стрелкой):
Начнется эмуляция. Вот эти синие квадратики - это наши выводы контроллера, точнее их состояние (еще точнее - какое напряжение на них). Если цвет синий - ножка закорочена на землю и ее состояние "ноль", если красный - то напряжение на ножке +5В, и лучше ее в этом состоянии на землю не коротить, может и накрыться этот порт.
В общем, повнимательнее. Четыре овала - это четыре разных "порта" по 8 выводов каждый. НО, мы сконфигурировали СОМ-порт, видите в одном из овалов один вывод серый, а один красный? Красный - это вывод информации по СОМ-порту, а серый - вывод ввода информации в контроллер. Здорово да? Мы увидели как себя ведет контроллер, что называется "наглядно".
Идем дальше. В Баскоме измените значения в строках, как указано на рисунке стрелками:
Поясню - это цифры (так называемый 16-ричный формат). Заместо букв ff поставьте по два нуля - 00, еще раз нажмите кнопку компиляции, после завершения компиляции переключитесь на Протеус и снова запустите симуляцию:
Состояние выводов изменилось. Теперь они (которые очерчены зелеными овалами) окрашеты в серый цвет. Что он означает? Что ножки контроллера теперь работают на прием. Поясню:
Допустим мы встраиваем в схему переключатель. Когда переключатель разомкнут - на ножку будет подаваться ноль (именно подаваться,это важно), а когда переключатель нажат (замкнут) - будет подаваться +5В. Опрашивая эту ножку контроллера в нашей (будущей) программе мы поймем - замкнут переключатель или разомкнут (это для упирание в препятствие, пока едем - на контрольной ножке ноль, уперлись в стену, переключатель нажался, на ножке появилось +5В, контроллер опросил ее, увидел что "совершен наезд" и выключил мотор (или отъехал назад). Еще раз повторюсь - опрос возможен только тогда, когда "состояние ножек" - серое.
Как же получилось так, что ножки из "синего" состояния перешли в "серое" (то есть из замкнутых на землю - в "неопределенное")? Для этого обратим внимание на код, который мы меняли:
Ddra = $ff оставили без изменения
Ddrb = $00 поменяли
Ddrc = $ff оставили как есть
Ddrd = $00 поменяли
Ddrb = $00 поменяли
Ddrc = $ff оставили как есть
Ddrd = $00 поменяли
Что эти строки означают? Ddr - "конфигуратор"; a (b, c, d) - это порты (по 8 выводов каждый); "=" - "присвоить значение"; "$" - 16-ричный формат следующего за этим символом числа, "ff" или "00" - само число. Чтобы упростить - откройте стандартный калькулятор и переключите его в инженерный вид (нажмите слово "вид" и выберите "инженерный"), поставьте флажок на "Bin".
В этом варианте можно набирать либо "1" либо "0". Это состояние калькулятора для работы с двоичными числами.
Чтобы не заморачиваться с объяснением, забиваете нулями или единицами такое состояние порта, которое вам нужно (напомню - набирать 8 цифр) и переключаете флаже с Bin на Hex, получаете значение в 16-ричном формате и вставляете полученный результат в программу (я буду приводить пример для порта "a"):
В первом примере получили "f0", во втором "aa". Вставляем по очереди в Bascom и запускаем потом для контроля в Протеусе:
по "f0" (или 11110000):
Я совместил снимок из Протеуса с "Калькулятором".
Если "aa" (или 10101010):
Код в Bascom:
Теперь как рассчитать и определить порт для входа или для выхода вы знаете.
Продолжу по коду:
Следующая строка Portb.4 = 1. Это мы обращаемся к порту "b" пину №4 чтобы на этой ножке появилось напряжение +5В. Через строку Portb.4 = 0 - это сбросить это напряжение на ноль.
В симуляторе после запуска порт b.4 (обозначен как PB4) зажигается красным и гаснет, в реальном контроллере на 5 ножке контроллере тоже кратковременно появится +5в, а потом сбросится. Таким образом можно обратиться к любой ножке контроллера, то есть заставить на этой ножке появиться +5В или сбросить напряжение на ноль, просто написать нужную команду:
PortX.Y=1 (Включили), где X - это порт (a,b,c,d), а Y - номер пина (от нуля до восьми)
PortX.Y=0 (Выключили), где X - это порт (a,b,c,d), а Y - номер пина (от нуля до восьми).
Между этими строками есть команда: Wait 1, это команда "пауза", она останавливает контроллер на заданное время, в данном примере - на 1 секунду. Если ввести команду Wait 10, то остановит на 10 секунд. Ниже есть команда Waitms 100, эта команда тоже делает паузу, но на более короткое время - на миллисекунды. В данном случае она остановит на 100 миллисекунд (или на 0,1 секунды). Если ввести Waitms 1000, то остановит на 1000 миллисекунд (или на 1 секунду).
Еще одна строка: Start Adc, это запуск встроенного в контроллер аналого-цифрового преобразователя. При помощи этой подпрограммы можно получить значение напряжения на ножке контроллера.
Все это контроллер проделает один раз, а потом ничего делать не будет. Чтобы контроллер находился в постоянной готовности в него закладывается "вечный цикл" - команды Do и Loop. Вся основная программа будет находиться между этими двумя командами.