Программы | MEGA-AVR
Популярная мощная и удобная среда разработки и отладки программ для микроконтроллеров и процессоров архитектуры ARM:
Cortex-M0, M3, M4, M7, A9
Proteus — это пакет программ для автоматизированного проектирования электронных схем, версии 8.7 NEW!!! Continue reading →
В статье приводится USB программатор микроконтроллеров AVR и AT89S, совместимый с AVR910 — с журнала Радио №7, 2008г. Continue reading →
Новая версия(но не самая последняя) на момент публикации. Программа как всегда с ключами и лицензией).
Continue reading →
Стабильная версия Proteus Professional 8.4 SP0 без глюков и вылетов (проверено на windows 7). Continue reading →
Программа схемотехнического моделирования Micro-Cap имеет удобный, дружественный интерфейс и предъявляет достаточно скромные требования к программно-аппаратным средствам персонального компьютера. Continue reading →
Новая версия программы SinaProg 2.1.1 с русифицированным калькулятором фьюзов.
Continue reading →
Как то при разработке очередного устройства в котором данные от одного устройства к другому передавались по UART, нужно было проверить работоспособность схемы и программы. Continue reading →
LabVIEW 8.6 демонстрируют увеличение скорости работы, более эффективную загрузку процессора и повышенную надежность систем реального времени на выделенных ядрах. Continue reading →
Circuit Design Suite — одна из наиболее популярных в мире программ конструирования электронных схем, характеризуется сочетанием профессиональных возможностей и простоты, расширяемостью функций от простой настольной системы до сетевой корпоративной системы. Continue reading →
Компилятор CodeVisionAVR 2.04. Continue reading →
Новое в 8 версии: Application Framework
Теперь Proteus 8 состоит из одного приложения с большим количеством модулей (ISIS, BOM, ARES, 3D Viewer и т.д.). Continue reading →
AVR. Учебный курс. Простейшая программа.
Итак, прежде чем что то делать надо понять как вообще выполняется программа в контроллере, как работает ядро процессора. Для этого нам хватит AVR Studio и его эмулятора. Не очень интересно, может даже занудно, но если этот шаг пропустить, то дальнейшие действия будут как бег в темноте.
Поскольку в демоплате Pinboard используется процессор ATmega16, то рассматривать мы будем именно его. Впрочем, как я уже говорил, для других контроллеров AVR это также будет справедливо. Отличия, конечно, есть, но они не существенные.
Запускаем AVR Studio (далее просто студия) и в выскочившем мастере сразу же создаем проект:
Откроется окно:
Увеличить
Оно может выглядеть чуток не так. Дело в том, что интерфейс студии очень легко конфигурируется и перекраивается под себя. Так что можно перетащить панели как нам удобно. Что я и сделал.
Систему команд хорошо бы распечатать себе на листочке. Их там всего около 130, кратким списком (тип команды, что делает и какие операнды) занимает пару листов формата А4. Учить не надо, прочитать раз на десять, чтобы помнить знать что у нас есть. Даже я периодически подглядываю в систему команд, хотя пишу на ассемблере уже много лет.
Я же команды которые буду использовать буду описывать по мере появления.
В центральном окне пишем код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | .include "m16def.inc" ; Используем ATMega16 ;= Start macro.inc ======================================== ; Тут будут наши макросы, потом. ;= End macro.inc ======================================== ; RAM ===================================================== .DSEG ; Сегмент ОЗУ ; FLASH =================================================== .CSEG ; Кодовый сегмент ; EEPROM ================================================== .ESEG ; Сегмент EEPROM |
.include «m16def.inc» ; Используем ATMega16 ;= Start macro.inc ======================================== ; Тут будут наши макросы, потом. ;= End macro.inc ======================================== ; RAM ===================================================== .DSEG ; Сегмент ОЗУ ; FLASH =================================================== .CSEG ; Кодовый сегмент ; EEPROM ================================================== .ESEG ; Сегмент EEPROM
Это вроде шаблона для начала любого проекта. Правда кода тут 0 байт 🙂 Только директивы.
Обрати также внимание на оформление кода. Дело в том, что в ассемблере нет никаких структурных
элементов — весь код плоский, тупо в столбик. Так что поэтому чтобы он был читабелен его надо в обязательно порядке разбивать на блоки, активно пользоваться табуляцией и расставлять комментарии. Иначе уже через пару дней ты не сможешь понять, что вообще написал.
В коде будут активно использоваться макросы. Поначалу они будут писаться в основном файле, в секции macro.inc, но потом я их вынесу в отдельный файл, чтобы не мешались. Так удобней.
Как я уже говорил, в микроконтроллере куча раздельных видов памяти. И тут используется гарвардская архитектура. Т.е. исполняемый код в одном месте, а переменные в другом. Причем это разные адресные пространства. Т.е. адрес 0000 в сегменте данных это не то же что и адрес 0000 в сегменте кода. Это дает большое преимущество в том, что данные не могут испортить код, но не дает писать полиморфные программы. Такая архитектура является традиционной для микроконтроллеров.
У обычного PC компа используется другая архитектура — Фон Неймановская. Там данные и код находятся в одном адресном пространстве. Т.е., скажем, с адреса 0000 по 0100 идет код, а с 100 до FFFF данные.
В нашей же программе и код и данные располагаются на одном листе, но чтобы компилятор понял где у нас что они выделяются директивами сегментации. Пока нас интересуют директива .CSEG после нее начинается исполняемый код. Там и будем писать нашу программу.
Возьмем и напишем:
1 2 3 4 5 | ; FLASH =================================================== .CSEG ; Кодовый сегмент NOP NOP NOP |
; FLASH =================================================== .CSEG ; Кодовый сегмент NOP NOP NOP
Что мы сделали? А ничего! Команда NOP это команда затычка. Она не делает ничего, просто занимает 2 байта и 1 такт.
Речь не о команде NOP (там и обсуждать то нечего), а о том как оно все будет выполняться.
Запускай симуляцию (Ctrl+F7) когда пробежит прогресс бар компиляции/симуляции и возле первого NOP возникнет стрелочка нажми ALT+O — выскочит диалог настройки симуляции. Там тебе надо там только выставить частоту 8Мгц. Почему 8Мгц? Просто на Pinboard частота главного проца по дефолту 8Мгц. Если у тебя свои идеи на этот счет — можешь поправить как угодно. На симуляцию это не влияет.
Вернемся к нашей симуляции. Давай посмотрим как выглядит наша программа с точки зрения машинных кодов, как размещается в памяти. Интерес, по большей части, чисто теоретический, редко когда пригождается и по этому во многих учебных курсах по AVR на это даже внимание не заостряют. А зря! Т.к. упускается глубинное ощущение кода. Открой окно просмотра программ. View — Memory или Alt+4.
Там выбери тип памяти Programm. Это и есть наш Flash сегмент. Выставим в списке cols две колонки, чтобы было наглядней.
Это наша память программ. На голубом фоне идут адреса, они, как видишь, в словах. Т.е. двум байтам соответствует один адрес. Но, на самом деле это интерпретация адресации компилятором, микроконтроллер же может оперировать в памяти программ с точностью до байта.
0000 это код команды NOP. У нас три команды, поэтому шесть нулей.
Обрати внимание на то, что команды идут с адреса 0000. Это потому, что мы не указали ничего иного. А кодовый сегмент начинается с адреса 0000.
Теперь смотрим на программный счетчик Programm Counter, он показывает адрес инструкции которая будет выполнена.
Поскольку мы только стартанули, то он равен нулю — нулевая инструкция. Нажми F11, процессор сделает шаг, программный счетчик изменится на 1 и покажет следующую инструкцию. И так до тех пор, пока не дойдет до третьего NOP, а что у нас после него? А после него у нас FF до конца памяти. FF это несуществующая инструкция, на ней виртуальный контроллер перезагрузится с ошибкой invalid opcode, а реальный контроллер ее проигнорирует, пробежав по ним, как по NOP, до конца памяти.
Сбрось симуляцию микроконтроллера (Shift+F5) и вручную выстави в Program Counter адрес 0x000002 — проц сам перепрыгнет на последнюю команду NOP. Если менять Program Counter то проц будет выполнять те команды, которые мы ему укажем. Но как это сделать в реальном контроллере? В него то мышкой не залезешь!
Программный счетчик меняется командами переходов. Их много (условные, безусловные, относительные), о них я расскажу подробней чуть позже, пока же приведу один пример.
Добавим в наш код команду JMP и ее аргумент — адрес 0x000001.
1 2 3 4 5 | .CSEG ; Кодовый сегмент NOP NOP NOP JMP 0x000001 |
.CSEG ; Кодовый сегмент NOP NOP NOP JMP 0x000001
Команда JMP, как и все команды перехода, работает просто — записывает в Program Counter свой аргумент. В нашем случае — 0x000001.
Перекомпиль проект и посмотри на то, как меняется Program Counter (далее буду звать его PC) и вообще как теперь идет процесс выполнения программы. Видишь, после JMP в программный счетчик заносится новый адрес и процессор сразу же перепрыгивает в начало кода, но не на первую, а на вторую инструкцию. Программа зациклилась.
Это называется абсолютный переход. Он может сигануть куда угодно, в любую область памяти программ. Но за такую дальнобойность приходится платить. Если заглянешь в память, то увидишь там такую картину:
OC 94 — это код нашей комады, а 01 00 адрес перехода. Длина команды стала четыре байта. Два байта ушло на адрес. Вот, кстати, особенность памяти в том, что там данные записываются зеркально, т.е. младший байт числа по младшему адресу (порядок little-endian).
Но поскольку дальнобойные команды применяются редко, основной командой перехода в AVR является относительный переход RJMP. Основное отличие тут в том, что в PC не записывается не точный адрес куда надо перейти, а просто к PC прибавляется смещение. Вот так:
1 2 3 4 5 6 7 8 9 | .CSEG ; Кодовый сегмент NOP NOP NOP RJMP PC+2 NOP NOP RJMP PC-6 NOP |
.CSEG ; Кодовый сегмент NOP NOP NOP RJMP PC+2 NOP NOP RJMP PC-6 NOP
По идее, должно работать напрямую, т.е. RJMP +2. Но компилятор такую запись не понимает, он оперирует абсолютными адресами, приводя их потом в нужные смещения машинного кода. Поэтому применим макроопределение PC — это текущее значение счетчика в данном месте программы. Т.е.
Наглухо зациклит программу в этой строчке.
Благодаря относительному переходу, смещение можно запихать в те же два байта, что занимает команда. При этом код относительного перехода выглядит так Сх хх, где ххх это смещение от +/-2047 команд. Что обычно хватает с лихвой. В памяти же команда перехода выглядит как хх Сх, то есть байты переставлены.
Таким образом, длина команды у относительного перехода составляет 2 байта, против четырех у абсолютного. Экономия!!! Учитывая что в обычной программе подобные переходы на каждом шагу.
Вот только что же, каждый раз самому вручную высчитывать длину перехода? Ладно тут программка в три команды, а если их сотни? Да если дописал чуток то все переходы заново высчитывать?
Угу. Когда то давно, когда компиляторов еще не было так и делали. Cейчас же все куда проще — компилятор все сделает сам. Ему только надо указать откуда и куда. Делается это с помощью меток.
1 2 3 4 5 6 7 8 9 | .CSEG ; Кодовый сегмент M1: NOP NOP NOP RJMP M2 NOP M2: NOP RJMP M1 NOP |
.CSEG ; Кодовый сегмент M1: NOP NOP NOP RJMP M2 NOP M2: NOP RJMP M1 NOP
Метки могут быть из букв или цифр, без пробелов и не начинаться с цифр. Заканчиваются двоеточием. По факту, метка означает текущий адрес в словах. Так что ее можно использовать и в операциях. Надо только помнить, что она двубайтная, а наш контроллер однобайтный. Разобрать двубайтное значение по байтам можно с помощью директивы компилятора Low и High
Например,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | .CSEG ; Кодовый сегмент M1: NOP NOP LDI ZL,low(M2) ; Загрузили в индекс LDI ZH,High(M2) IJMP NOP NOP NOP M2: NOP RJMP M1 NOP |
.CSEG ; Кодовый сегмент M1: NOP NOP LDI ZL,low(M2) ; Загрузили в индекс LDI ZH,High(M2) IJMP NOP NOP NOP M2: NOP RJMP M1 NOP
Команда LDI загружает непосредственное значение в регистр старшей (от R16 до R31) группы. Например, LDI R17,3 и в R17 будет число 3. А тут мы в регистры R30 (ZL) загрузили младший байт адреса на который указывает метка М2, а в R31 (ZH) старший байт адреса. Если протрассируешь выполнение (F11) этого кода, то увидишь как меняются значения регистров R30 и R31 (впрочем 31 может и не поменяться, т.к. там был ноль, а мы туда ноль и запишем — адрес то мал). Смену значений регистров можно поглядеть в том же окне где и Program Counter в разделе Registers.
Команда IJMP это косвенный переход. Т.е. он переходит не по адресу который заложен в коде операции или идет после него, а по адресу который лежит в индексной регистровой паре Z. Помните я говорил, что шесть последних регистров старшей регистровой группы образуют три регистровые пары X,Y,Z используются для адресации? Вот это я и имел ввиду.
После IJMP мы переходим на нашу же М2, но хитровывернутым способом. Зачем вообще так? Не проще ли применить RJMP и JMP. В этом случае да, проще.
Но вот благодаря косвенному переходу мы можем программно менять точку перехода. И это просто зверский метод при обработке всяких таблиц и создании switch-case структур или конечных автоматов. Примеры будут позже, пока попробуйте придумать сами.
Давай подвинем нашу кодовую конструкцию в памяти на десяток байт. Добавь в код директиву ORG
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ; FLASH =================================================== .CSEG ; Кодовый сегмент NOP .ORG 0x0010 M1: NOP NOP LDI ZL,low(M2) ; Загрузили в индекс LDI ZH,High(M2) IJMP NOP NOP NOP M2: NOP RJMP M1 NOP |
; FLASH =================================================== .CSEG ; Кодовый сегмент NOP .ORG 0x0010 M1: NOP NOP LDI ZL,low(M2) ; Загрузили в индекс LDI ZH,High(M2) IJMP NOP NOP NOP M2: NOP RJMP M1 NOP
Скомпиль и запусти. Открой память и увидишь что в точке с адресом 0000 у нас стоит наш NOP (Точка входа должна быть, иначе симулятор скукожит от такого когнитивного диссонанса. А вот дальше сплошные FF FF и лишь начиная с нашего адреса 0x0010 пошли коды остальных команд.
То есть мы разбили код, заставив директивой ORG компилятор перетащить его дальше, начиная с 0x0010 адреса.
Зачем это нам потребовалось? Ну, в первую очередь, это требуется чтобы перешагнуть таблицу векторов прерываний. Она находится в первых адресах.
Во-вторых, такая мера нужна чтобы записать код в конец флеша, при написании бутлоадеров (о них тоже дальше в курсе будет).
А еще таким образом можно прятать в коде данные, перемешивая данные с кодом. Тогда дизассемблирование такой программы превратится в ад =) своего рода, обфускация публичной прошивки, сильно затрудняющая реверс инженеринг.
Да, у кристалла есть биты защиты. Выставил которые и все, программу можно считать только спилив крышку кристалла с помощью электронных микроскопов, что очень и очень недешево. Но иногда надо оставить прошивку на виду, но не дать сорцов. И вот тогда превращение прошивки в кашу очень даже поможет =)
Ну или написать ее на Си ;))))))) (Есть вариант шифровки прошивки и дешифровки ее на лету бутлоадером, но это отдельная тема. О ней может быть расскажу)
Еще, там, в студии, же где и программный счетчик, есть ряд интересных параметров.
Во-первых, там отдельно вынесены наши индексные пары X,Y,Z и можно не лазать на дно раздела Registers.
Во-вторых, там есть Cycle counter — он показывает сколько машинных циклов протикал наш контроллер. Один машинный цикл в AVR равен одному такту. Frequency содержит частоту контроллера в данный момент, но мы задаем ее вручную.
А в-третьих, есть Stop Watch который показывает время выполнения. В микросекундах. Но можно переключить и в миллисекунды (пошарь в контекстном меню).
Если тебе кажется, что все слишком просто и я чрезмерно все разжевываю. Хы, не расслабляйся, у меня сложность растет по экспоненте. Скоро пойдет работа на прерываниях, а потом будем писать свою операционную систему :))))))
AVR. Учебный курс. Скелет программы
При написании прошивки надо очень внимательно подходить к процессу организации архитектуры будущей программы. Программа должна быть быстрой, не допускать задержек главного цикла и легко расширяться. Оптимально использовать аппаратные ресурсы и стараться выжать максимум возможного из имеющихся ресурсов.
Вообще, архитектура программ это отдельная тема и ближе к концу курса, в его Сишной части я подробней рассказываю о разных типах организации прошивки. Можешь забежать вперед и поглядеть, что да как.
В ассемблерной же части, я расскажу о одном из самых простых вариантов — флаговом автомате, а позже, когда ты уже будешь вовсю ориентироваться в моем коде, дам пример на основе конвейерного диспетчера, с подробным описанием его работы.
Суперцикл
Все программы на микроконтроллерах обычно зацикленные. Т.е. у нас есть какой то главный цикл, который вращается непрерывно.
Структура же программы при этом следующая:
- Макросы и макроопредения
- Сегмент ОЗУ
- Точка входа — ORG 0000
- Таблица векторов — и вектора, ведущие в секцию обработчиков прерываний
- Обработчики прерываний — тела обработчиков, возврат отсюда только по RETI
- Инициализация памяти — а вот уже отсюда начинается активная часть программы
- Инициализация стека
- Инициализация внутренней периферии — программирование и запуск в работу всяких таймеров, интерфейсов, выставление портов ввода-вывода в нужные уровни. Разрешение прерываний.
- Инициализация внешней периферии — инициализация дисплеев, внешней памяти, разных аппаратных примочек, что подключены к микроконтроллеру извне.
- Запуск фоновых процессов — процессы работающие непрерывно, вне зависимости от условий. Такие как сканирование клавиатуры, обновление экрана и так далее.
- Главный цикл — тут уже идет вся управляющая логика программы.
- Сегмент ЕЕПРОМ
Начинается все с макросов, их пока не много, если что по ходу добавим.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | .include "m16def.inc" ; Используем ATMega16 ;= Start macro.inc ======================================== .macro OUTI LDI R16,@1 .if @0 < 0x40 OUT @0,R16 .else STS @0,R16 .endif .endm .macro UOUT .if @0 < 0x40 OUT @0,@1 .else STS @0,@1 .endif .endm ;= End macro.inc ======================================= |
.include «m16def.inc» ; Используем ATMega16 ;= Start macro.inc ======================================== .macro OUTI LDI R16,@1 .if @0 < 0x40 OUT @0,R16 .else STS @0,R16 .endif .endm .macro UOUT .if @0 < 0x40 OUT @0,@1 .else STS @0,@1 .endif .endm ;= End macro.inc =======================================
В оперативке пока ничего не размечаем. Нечего.
1 2 3 | ; RAM =================================================== .DSEG ; END RAM =============================================== |
; RAM =================================================== .DSEG ; END RAM ===============================================
С точкой входа и таблицей векторов все понятно, следуя нашему давнему шаблону, берем его оттуда:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | ; FLASH ====================================================== .CSEG .ORG $000 ; (RESET) RJMP Reset .ORG $002 RETI ; (INT0) External Interrupt Request 0 .ORG $004 RETI ; (INT1) External Interrupt Request 1 .ORG $006 RETI ; (TIMER2 COMP) Timer/Counter2 Compare Match .ORG $008 RETI ; (TIMER2 OVF) Timer/Counter2 Overflow .ORG $00A RETI ; (TIMER1 CAPT) Timer/Counter1 Capture Event .ORG $00C RETI ; (TIMER1 COMPA) Timer/Counter1 Compare Match A .ORG $00E RETI ; (TIMER1 COMPB) Timer/Counter1 Compare Match B .ORG $010 RETI ; (TIMER1 OVF) Timer/Counter1 Overflow .ORG $012 RETI ; (TIMER0 OVF) Timer/Counter0 Overflow .ORG $014 RETI ; (SPI,STC) Serial Transfer Complete .ORG $016 RETI ; (USART,RXC) USART, Rx Complete .ORG $018 RETI ; (USART,UDRE) USART Data Register Empty .ORG $01A RETI ; (USART,TXC) USART, Tx Complete .ORG $01C RETI ; (ADC) ADC Conversion Complete .ORG $01E RETI ; (EE_RDY) EEPROM Ready .ORG $020 RETI ; (ANA_COMP) Analog Comparator .ORG $022 RETI ; (TWI) 2-wire Serial Interface .ORG $024 RETI ; (INT2) External Interrupt Request 2 .ORG $026 RETI ; (TIMER0 COMP) Timer/Counter0 Compare Match .ORG $028 RETI ; (SPM_RDY) Store Program Memory Ready .ORG INT_VECTORS_SIZE ; Конец таблицы прерываний |
; FLASH ====================================================== .CSEG .ORG $000 ; (RESET) RJMP Reset .ORG $002 RETI ; (INT0) External Interrupt Request 0 .ORG $004 RETI ; (INT1) External Interrupt Request 1 .ORG $006 RETI ; (TIMER2 COMP) Timer/Counter2 Compare Match .ORG $008 RETI ; (TIMER2 OVF) Timer/Counter2 Overflow .ORG $00A RETI ; (TIMER1 CAPT) Timer/Counter1 Capture Event .ORG $00C RETI ; (TIMER1 COMPA) Timer/Counter1 Compare Match A .ORG $00E RETI ; (TIMER1 COMPB) Timer/Counter1 Compare Match B .ORG $010 RETI ; (TIMER1 OVF) Timer/Counter1 Overflow .ORG $012 RETI ; (TIMER0 OVF) Timer/Counter0 Overflow .ORG $014 RETI ; (SPI,STC) Serial Transfer Complete .ORG $016 RETI ; (USART,RXC) USART, Rx Complete .ORG $018 RETI ; (USART,UDRE) USART Data Register Empty .ORG $01A RETI ; (USART,TXC) USART, Tx Complete .ORG $01C RETI ; (ADC) ADC Conversion Complete .ORG $01E RETI ; (EE_RDY) EEPROM Ready .ORG $020 RETI ; (ANA_COMP) Analog Comparator .ORG $022 RETI ; (TWI) 2-wire Serial Interface .ORG $024 RETI ; (INT2) External Interrupt Request 2 .ORG $026 RETI ; (TIMER0 COMP) Timer/Counter0 Compare Match .ORG $028 RETI ; (SPM_RDY) Store Program Memory Ready .ORG INT_VECTORS_SIZE ; Конец таблицы прерываний
Обработчики пока тоже пусты, но потом добавим
1 2 | ; Interrupts ============================================== ; End Interrupts ========================================== |
; Interrupts ============================================== ; End Interrupts ==========================================
Инициализация ядра. Память, стек, регистры:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | Reset: LDI R16,Low(RAMEND) ; Инициализация стека OUT SPL,R16 ; Обязательно!!! LDI R16,High(RAMEND) OUT SPH,R16 ; Start coreinit.inc RAM_Flush: LDI ZL,Low(SRAM_START) ; Адрес начала ОЗУ в индекс LDI ZH,High(SRAM_START) CLR R16 ; Очищаем R16 Flush: ST Z+,R16 ; Сохраняем 0 в ячейку памяти CPI ZH,High(RAMEND) ; Достигли конца оперативки? BRNE Flush ; Нет? Крутимся дальше! CPI ZL,Low(RAMEND) ; А младший байт достиг конца? BRNE Flush CLR ZL ; Очищаем индекс CLR ZH CLR R0 CLR R1 CLR R2 CLR R3 CLR R4 CLR R5 CLR R6 CLR R7 CLR R8 CLR R9 CLR R10 CLR R11 CLR R12 CLR R13 CLR R14 CLR R15 CLR R16 CLR R17 CLR R18 CLR R19 CLR R20 CLR R21 CLR R22 CLR R23 CLR R24 CLR R25 CLR R26 CLR R27 CLR R28 CLR R29 ; End coreinit.inc |
Reset: LDI R16,Low(RAMEND) ; Инициализация стека OUT SPL,R16 ; Обязательно!!! LDI R16,High(RAMEND) OUT SPH,R16 ; Start coreinit.inc RAM_Flush: LDI ZL,Low(SRAM_START) ; Адрес начала ОЗУ в индекс LDI ZH,High(SRAM_START) CLR R16 ; Очищаем R16 Flush: ST Z+,R16 ; Сохраняем 0 в ячейку памяти CPI ZH,High(RAMEND) ; Достигли конца оперативки? BRNE Flush ; Нет? Крутимся дальше! CPI ZL,Low(RAMEND) ; А младший байт достиг конца? BRNE Flush CLR ZL ; Очищаем индекс CLR ZH CLR R0 CLR R1 CLR R2 CLR R3 CLR R4 CLR R5 CLR R6 CLR R7 CLR R8 CLR R9 CLR R10 CLR R11 CLR R12 CLR R13 CLR R14 CLR R15 CLR R16 CLR R17 CLR R18 CLR R19 CLR R20 CLR R21 CLR R22 CLR R23 CLR R24 CLR R25 CLR R26 CLR R27 CLR R28 CLR R29 ; End coreinit.inc
Всю эту портянку можно и нужно спрятать в inc файл и больше не трогать.
Секции внешней и внутренней инициализации переферии пока пусты, но ненадолго. Равно как и запуск фоновых программ. Потом я просто буду говорить, что мол добавьте эту ботву в секцию Internal Hardware Init и все 🙂
1 2 3 4 5 6 7 8 9 10 11 | ; Internal Hardware Init ====================================== ; End Internal Hardware Init =================================== ; External Hardware Init ====================================== ; End Internal Hardware Init =================================== ; Run ========================================================== ; End Run ====================================================== |
; Internal Hardware Init ====================================== ; End Internal Hardware Init =================================== ; External Hardware Init ====================================== ; End Internal Hardware Init =================================== ; Run ========================================================== ; End Run ======================================================
А теперь, собственно, сам главный цикл.
1 2 3 4 5 | ; Main ========================================================= Main: JMP Main ; End Main ===================================================== |
; Main ========================================================= Main: JMP Main ; End Main =====================================================
Все процедуры располагаются в отдельной секции, не смешиваясь с главным циклом. Так удобней, потом можно их по частям вынести в библиотечные файлы и разделить исходник на несколько файлов. Но мы пока это делать не будем. Разделим их просто логически.
1 2 3 | ; Procedure ==================================================== ; End Procedure ================================================ |
; Procedure ==================================================== ; End Procedure ================================================
Ну и вот тебе файлик с уже готовым проектом под этот шаблон
Микроконтроллеры и Технологии — Занятие №1. Простейшая программа
Дата публикации: .
Задача: Разработаем программу управления одним светодиодом. При нажатии на кнопку светодиод горит, при отпускании гаснет.
Для начала разработаем принципиальную схему устройства. Для подключения к микроконтроллеру любых внешних устройств используются порты ввода-вывода. Каждый из портов способен работать как на вход так и на выход. Подключим светодиод к одному из портов, а кнопку к другому. Для этого опыта мы будем использовать контроллер Atmega8. Эта микросхема содержит 3 порта ввода-вывода, имеет 2 восьмиразрядных и 1 шестнадцатиразрядный таймер/счетчик. Также на борту имеется 3-х канальный ШИМ, 6-ти канальный 10-ти битный аналого-цифровой преобразователь и многое другое. По моему мнению микроконтроллер прекрасно подходит для изучения основ программирования.
Для подключения светодиода мы будем использовать линию PB0, а для считывания информации с кнопки воспользуемся линией PD0. Схема приведена на рис.1.
Рис. 1
Через резистор R2 на вход PD0 подается плюс напряжения питания, что соответствует сигналу логической единице. При замыкании кнопки напряжение падает до нуля, что соответствует логическому нулю. В дальнейшем R2 можно исключить из схемы, заменяя его на внутренний нагрузочный резистор, введя необходимые настройки в программе. Светодиод подключен к выходу порта PB0 через токоограничивающий резистор R3. Для того чтобы зажечь светодиод надо подать в линию PB0 сигнал логической единицы. Задающий тактовый генератор будем использовать внутренний на 4MHz, так как в устройстве нет высоких требований к стабильности частоты.
Теперь пишем программу. Для написания программ я использую программную среду AVR Studio и WinAvr. Открываем AVR Studio, всплывает окошко приветствия, нажимаем кнопку «Создать новый проект» (New project), далее выбираем тип проекта — AVR GCC, пишем имя проекта например «cod1», ставим обе галочки «Создать папку проекта» и «Создать файл инициализации», нажимаем кнопку «Далее», в левом окошке выбираем «AVR Simulator», а в правом тип микроконтроллера «Atmega8», нажимаем кнопку «Финиш», открывается редактор и дерево категорий проекта — начальные установки закончены.
Для начала добавим стандартный текст описаний для Atmega8 с помощью оператора присоединения внешних файлов: #include
синтаксис директивы #include
#include <имя_файла.h>
#include “имя_файла.h”
Угловые скобки < и > указывают компилятору, что подключаемые файлы нужно сначала искать в стандартной папке WinAvr с именем include. Двойные кавычки “ и “ указывают компилятору начинать поиск с директории, в которой хранится проект.
Для каждого типа микроконтроллера есть свой заголовочный файл. Для ATMega8 этот файл называется iom8.h, для ATtiny2313 – iotn2313.h. В начале каждой программы мы должны подключать заголовочный файл того микроконтроллера, который мы используем. Но есть и общий заголовочный файл io.h. Препроцессор обрабатывает этот файл и в зависимости от настроек проекта включает в нашу программу нужный заголовочный файл.
Для нас первая строчка программы будет выглядеть вот так:
#include <avr/io.h>
Любая программа на языке Си должна обязательно содержать одну главную функцию. Она имеет имя main. Выполнение программы всегда начинается с выполнения функции main. У функции есть заголовок – int main(void) и тело – оно ограниченно фигурными скобками {}.
int main(void)
{
тело функции
}
В тело функции мы и будем добавлять наш код. Перед именем функции указывается тип возвращаемого значения. Если функция не возвращает значение – используется ключевое void.
int – это целое 2-х байтное число, диапазон значений от – 32768 до 32767
После имени функции в скобках () указываются параметры, которые передаются функции при ее вызове. Если функция без параметров – используется ключевое слово void. Функция main содержит в себе набор команд, настройки системы и главный цикл программы.
Далее настраиваем порт D на вход. Режим работы порта определяется содержимым регистра DDRD(регистр направления передачи информации). Записываем в этот регистр число «0x00» (0b0000000 – в двоичном виде), кроме кнопки к этому порту ничего не подключено, поэтому настраиваем весь порт D на вход. Настроить порт поразрядно можно записав в каждый бит регистра числа 0 или 1 (0-вход, 1-выход), например DDRD = 0x81 (0b10000001) — первая и последняя линия порта D работают на выход, остальные на вход. Необходимо также подключить внутренний нагрузочный резистор. Включением и отключением внутренних резисторов управляет регистр PORTx, если порт находится в режиме ввода. Запишем туда единицы.
Настраиваем порт B на выход. Режим работы порта определяется содержимым регистра DDRB. Ничего кроме светодиода к порту B не подключено, поэтому можно весь порт настроить на выход. Это делается записью в регистр DDRB числа «0xFF». Для того чтобы при первом включении светодиод не загорелся запишем в порт B логические нули. Это делается записью PORTB = 0x00;
Для присвоения значений используется символ «=» и называется оператором присваивания, нельзя путать со знаком «равно»
Настройка портов будет выглядеть так:
DDRD = 0x00;
PORTD = 0xFF;
DDRB = 0xFF;
PORTB = 0x00;
Пишем основной цикл программы. while («пока» с англ.) — эта команда организует цикл, многократно повторяя тело цикла до тех пор пока выполняется условие, т. е пока выражение в скобках является истинным. В языке Си принято считать , что выражение истинно, если оно не равно нулю, и ложно, если равно.
Команда выглядит следующим образом:
while (условие)
{
тело цикла
}
В нашем случае основной цикл будет состоять лишь из одной команды. Эта команда присваивает регистру PORTB инвертируемое значение регистра PORTD.
PORTB = ~PIND; //взять значение из порта D, проинвертировать его и присвоить PORTB (записать в PORTB)
// выражения на языке Си читаются справа налево
PIND регистр ввода информации. Для того, чтобы прочитать информацию с внешнего вывода контроллера, нужно сначала перевести нужный разряд порта в режим ввода. То есть записать в соответствующий бит регистра DDRx ноль. Только после этого на данный вывод можно подавать цифровой сигнал с внешнего устройства. Далее микроконтроллер прочитает байт из регистра PINx. Содержимое соответствующего бита соответствует сигналу на внешнем выводе порта. Наша программа готова и выглядит так:
#include <avr/io.h> int main (void) { DDRD = 0x00; //порт D - вход PORTD = 0xFF; //подключаем нагрузочный резистор DDRB = 0xFF; //порт B - выход PORTB = 0x00; //устанавливаем 0 на выходе while(1) { PORTB = ~PIND; //~ знак поразрядного инвертирования } }
В языке Си широко используются комментарии. Есть два способа написания.
/*Комментарий*/
//Комментарий
При этом компилятор не будет обращать внимание на то что написано в комментарии.
Если используя эту же программу и подключить к микроконтроллеру 8 кнопок и 8 светодиодов, как показано на рисунке 2, то будет понятно что каждый бит порта D соответствует своему биту порта B. Нажимая кнопку SB1 — загорается HL1, нажимая кнопку SB2 — загорается HL2 и т.д.
Рисунок 2
В статье были использованы материалы из книги Белова А.В. «Самоучитель разработчика устройств на AVR»
Простейшая программа для AVR — Меандр — занимательная электроника
Первое, что хочется сделать после сборки программатора это помигать светодиодиком. В этой статье я подробно опишу, как написать такую простенькую программку и расскажу как она работает.
Для начала я познакомлю Вас со средой программирования Algorithm Builder, которая на мой взгляд очень удобна для написания программ на языке ассемблер. Скачать её можно на сайте автора. Она полностью бесплатна. Далее установите её и после того, как установили, откройте её и появится вот такое окно:
Эта программа является хорошей графической средой программирования на ассемблере. В отличии от классического ассемблера здесь пишется не сам код программы на ассемблере, а рисуется алгоритм работы этой программы, а компилятор при компиляции сам составит и скомпилирует код. Инструкций по работе с программой давать не буду – основы работы с ней описаны в родном руководстве на русском языке. Для того, чтобы открыть руководство по программе нужно нажать на знак вопроса, который находится на верху программы и нажать на пункт “manual.pdf”. В руководстве всё отлично расписано и даже есть пример вольтметра.
Теперь перейдем к нашей программке, которая будет мигать светодиодом. Для начала разберём алгоритм работы программы. Для того, чтобы помигать светодиодом нужно его подключить к какому-либо порту ввода-вывода микроконтроллера. Что же такое порты ввода-вывода? Порты ввода-вывода (далее порты в/в) это выводы микроконтроллера, состоянием которых можно управлять из программы, прошитой в мк. Они могут быть в трёх состояниях:
- Высокий уровень – логическая единица (это состояние вывода, при котором порт в/в подключён напряжению питания, то есть на этом выводе уровень напряжения, равный напряжению питания)
- Низкий уровень – логический ноль ( в этом состоянии порт в/в подключён напрямую к земле (минусу питания) и напряжение на нём равно 0 Вольт)
- Высокоомное HI-Z состояние (в этом состоянии ножка не подключена ни к чему т.е на ней не 0 и не 1)
Эти порты есть у каждого микроконтроллера AVR и почти все выводы контроллера (кроме земли и питания) могут работать в режиме порта в/в. А теперь откроем даташит на микроконтроллер, и посмотрим где же у него располагаются эти сами порты в/в. Для примера будем использовать микроконтроллер ATmega16. Итак, заходи на atmel.com, находим даташит на ATmega16 и открываем его. Далее идём на вторую страницу документа и видим там распиновку микроконтроллера в разных корпусах. Нас интересует распиновка контроллера в DIP корпусе. Вот она:
Видите выводы PD1,2,3 PC1,2,3, и т.д.? Вот это и есть порты в/в. Например, PC0 расшифровывается как Port C 0. Как видно, у данного микроконтроллера 4 порта в/в и каждый из них имеет по 8 выводов, значит всего в нашем распоряжении 32 ножки.
Теперь раздерём как эти выводы настраиваются и как с ними работать. Порты в/в можно настроить на вход или на выход. Делается это установкой соответствующих бит в регистре DDR (Data Direction Register – регистр направления порта в/в). Для каждого порта есть свой регистр DDR. Именуются они так: в начале идёт префикс DDR, а после него имя порта. Например, для порта A регистр будет называться DDRA. Также есть ещё регистры PORT и PIN, но о них позже. Регистр состоит из 8-ми бит, которые соответствуют ножке, например, бит 0 в регистре DDRA будет определять направление вывода PA0. Если записать в этот бит 1, то вывод PA1 будет портом вывода т.е. выходом, а если записать 0 – входом.
Итак, создадим уже наконец новый проект в Algorithm Builder и настроим вывод PA0 в режим выхода. Для этого, как я и говорил нужно записать в 0 бит регистра DDRA единицу. Для начала настроим наш проект. Заходим в опции проекта и указываем микроконтроллер и тактовую частоту в герцах (в нашем случае это 8000000 Гц = 8 мГц):
Нажимаем применить и начинаем рисовать алгоритм. Как я уже говорил нужно в бит 0 регистра DDRA записать 1. Делается это вот так:
Чёрточка, которая находится наверху – это вершина блока с алгоритмом (элемент Vertex). Разберём команду, которую я написал. DDRA.0 означает, что мы записываем в регистр DDRA, бит 0, а 1 -> — записываем единицу. Проще говоря, записываем единицу в 0 бит регистра DDRA.
Порт на выход мы настроили, теперь нужно записать в него единичку, тем самым зажечь светодиод. Чтобы записать единицу в порт, нужно записать единицу в регистр PORT. Именуется он также, как и DDR т.е. порту А соответствует регистр PORTA. Запишем в 0 бит порта A единичку:
Скомпилируем программу, нажав в верхнем меню Программа -> Компилировать. Если в нашем алгоритме нет ошибок, программа скомпилируется и вылезет вот такое окошко:
Как видно, программа занимает в памяти контроллера 2 слова. 1 слово – это 2 байта, значит наша программа занимает 4 байта. Теперь при помощи программатора загрузим нашу прогу в мк и подключим светодиод к порту A0 через резистор, сопротивлением 330 ом. Светодиод будет непрерывно гореть.
Далее давайте заставим светодиод не просто гореть, а мигать! Для этого нужно добавить ещё пару строк кода. Итак, продолжим. Чтобы потушить светодиод, нужно подать 0 на вывод PA0. Это делается точно также, как и запись единицы, но записываем мы 0:
Если сейчас скомпилить программу и зашить её в контроллер, то светодиод то мигать будет, но с бешеной скоростью, поэтому нам будет казаться, что он горит. Для того, чтобы снизить скорость мигания, нужно ввести какую-либо задержку между подачей 0 и 1. Проще всего реализовать её так: мы загружаем в три рабочих регистра (кстати, забыл упомянуть, что рабочие регистры – это, можно сказать, ячейки, в которые можно загрузить переменные. Это могут быть какие-нибудь числа или же буквы. В AVR есть 32 8-и разрядных регистра, значит в каждый из них можно загрузить по одному байту т.е. число от 0 до 255 или одну букву) r16, r17, r18 числа, а потом вычитаем их оттуда. Пока не появится 0, как только в регистре появится 0, переходим к разорению следующего регистра 🙂 и т.д., пока не опустошим все. Суть этой задержки в том, чтобы занять процессор бесполезной работой и потратить на это время. Для этой задержки мы создадим подпрограмму, которую можно будет вызывать между записью 1 и 0 в порт, а не прописывать каждый раз. Для этого сначала нужно инициализировать стек – ОЗУ. О стеке и о подпрограммах я расскажу позже, а сейчас напишем нашу подпрограмму:
Подпрограмма Delay – это и есть наша задержка. r16– означает, что мы вычитаем 1 из регистра 16, а стрелочки и -= означает, что если результат не равен нулю мы переходим по метке. Стрелочка указывает на метку. Это называется условный переход т.е. переход при каком-то условии. А теперь разберём основную программу. Между подачей 1 и 0 я написал Delay, это означает, что в этом месте мы подключаем нашу подпрограмму. А стрелочка – это безусловный переход, то есть переход произойдёт вне зависимости от чего-либо. Если сейчас прошить эту программу в мк, то светодиод опят-же будет лишь гореть т.к. мы ещё не инициализировали стек. Стек можно инициализировать с помощью настройщика. Для этого нажимаем на эту кнопочку:
Далее в появившемся меню выбираем “Stack Pointer (SP) и появится вот такое окно:
Ставим галочку и нажимаем ОК. Теперь в начале программы появится такой блок:
Это так называемый блок настройки периферии. Таким-же образом можно настроить и другую периферию, например, АЦП.
Всё компилируем программу и светодиод замигает! Кстати, о зашивке программы. После компиляции в папке с проектом появятся ещё 2 файла: один из них называется также, как и сам проект, а ко второму добавлено _EE. Первый файл нужно прошивать во flash память микроконтроллера, а второй не трогать вовсе.
Удачи Вам в прошивке!
Скачать архив с проектом.
Краткий Курс — Самоучитель — Программирование микроконтроллеров AVR — быстрый старт с нуля
Страница 4 — Краткий учебный курс — Самоучитель — AVR — быстрый старт с нуля.
ПРОГРАММА для AVR
ПО для микроконтроллеров AVR
Компиляторы Си и
Симуляторы
для микроконтроллеров AVR
ATmega ATtiny
Книги и учебники по электронике и микроконтроллерам
Страницы курса : заглавная 1 2 3 4 5 6 7 8 9
Задачи-упражнения курса по AVR — там
Микроконтроллыры AVR — параметрическая таблица
Скачать весь курс по
AVR одним архивом
на заглавной странице курса.
Это уже 4-я
страница краткого курса !
Вы уже должны представлять себе
1) что такое МК AVR и в чем его особенности
2) как МК взаимодействует с электроникой подключенной к нему
3) как МК преобразует напряжения на его ножках в «1» или «0»
4) что является посредником в общении программы с МК
5) какие напряжения на своих выводах может создавать МК AVR
6) с чего нужно начать разработку эл. устройства
7) какая документация по МК особенно полезна и необходима
8) где найти книги и дополнительные материалы
Если вы читаете курс
не первый раз и все равно не можете
ответить на эти вопросы — наверно вам
нужно остановится и попробовать найти
ответы в прочитанной части курса либо в
книгах.
Иначе понимание дальнейшего материала курса может оказаться затруднительным.
Список микроконтроллеров AVR
ВСЕ АКТУАЛЬНЫЕ !
Итак …
— вы определились с тем какое электронное устройство творите,
— понимаете что оно должно делать,
—
нарисовали схему устройства физически способную
выполнить вашу задумку !
—
например слепили из кусочков взятых в ДШ, АпНоутах,
опираясь на аналогичные
проекты других электронщиков найденные
в интернете и по
советам других радио Губителей.
Пора создавать программу которая, будучи загруженной (зашитой, прожженной) в МК, будет изменять физическое состояние его внутренностей и ножек делая записи в регистры МК и узнавать о физическом состоянии содержимого МК читая его регистры с целью выполнения задуманного вами.
Регистры… регистры… регистры…
Короче
—
хотите что-то
включить, выключить, поменять в МК —
найдите
в ДШ те регистры и биты которые
за это отвечают
и выясните что именно
нужно записать в них !
и у вас все получится…
Особенно просто и правильно вы этого добьетесь с помощью мастера интерактивного создания кода программы.
Про мастерконфигурации МК написано ниже.
Программу
для МК удобно создавать в специальных программах
— называются
они компиляторы.
Если кроме компилятора в пакете есть
отладчик-симулятор и/или программатор
то это уже IDE (интегрированная среда
разработки).
Компилятор
позволяет написать программу для МК на универсальном языке программирования
— одинаковом
и для ПК и для различных
МК (кстати для МК
требуется всего 3-5%
всех возможностей
языка программирования).
Текст программы набранный вами (или другими добрыми людьми) в компиляторе называют исходным кодом (или исходником или сырцом — англ: source code)
Компилятор по вашей команде проверяет отсутствие ошибок в набранном исходнике и, если ошибок нет, преобразует исходник (компилирует его) в специальный файл обычно с расширением .hex — его называют «прошивка».
Прошивку с
помощью программатора (для AVR это
например 5 проводков с параллельного
порта ПК) помещают во FLASH память программ
МК и при
необходимости частично в его EEPROM.
Реклама недорогих радиодеталей почтой:
Очень
трудно написать программу
сразу правильно и без ошибок
поэтому
Важнейшим этапом разработки электронного устройства является отладка программы МК.
(программа МК называется — firmware).
Для отладки вы :
— включаете ваше устройство с прошитым
МК (либо симулятор МК)
— находите отклонения от требуемого
алгоритма вызванные ошибками проги,
— выявляете хитрыми способами эти ошибки,
— вносите соответствующие изменения в
исходный текст программы
— опять компилируете
— прошиваете новый .hex в МК и опять на верхний пункт
этого списка
И
так до победного конца — т.е. до тех
пор
пока устройство заработает так как вам нужно.
Не всегда
допустимо включить устройство не зная
наверняка правильно ли
работает
программа МК — в некоторых случаях могут
произойти серьезные и дорогостоящие
повреждения обвязки МК и другой
аппаратуры.
Иногда
требуется проверить работу МК не имея
его и
вообще какой либо реально спаянной
схемы и самого МК.
В этих
случаях я рекомендую использовать
специальные программы — Симуляторы.
Симулятор приблизительно моделирует на ПК работу «прошитого» вашей программой МК и его обвязки — т.е. электронных компонентов окружающих МК по схеме устройства.
Кроме того симуляторы позволяют вам:
—
останавливать программу когда нужно —
в ручную и автоматически
— выполнять программу по шагам
— видеть как именно происходит
выполнение программы
— наблюдать и изменять значения в
регистрах МК
— наблюдать текущие значения
переменных
— использовать виртуальные
измерительные приборы с памятью
— симулировать работу МК с обвязкой
включающей различные электронные
компоненты и устройства
— виртуально обмениваться информацией с
терминалом на ПК
— делать еще много полезного !
Теперь подробнее …
Компиляторы Си для AVR
Не пугайтесь ! я не предлагаю вам изучить
еще и язык Си — мы
просто будем
использовать по мере необходимости несколько инструкций из
него — всего несколько процентов
языка.
Я сам
начинал изучать и применять МК сразу
на
Си — и очень доволен …
Считаю, что
Для начинающих наиболее удобен в работе
компилятор Си для AVR CodeVisionAVR ( или CVAVR)
Если вы еще не установили эту программу то скачайте на заглавной странице курса.
Именно для начинающих ! — Компилятор CVAVR содержит очень понятный и очень мощный генератор начального кода программы по вашим потребностям в конфигурации AVR и его периферии — встроеных электронных модулей МК — называется он :
CodeWizardAVR
Вам нужно просто выбрать МК, частоту тактирования, затем открыть ярлыки тех устройств МК которые вы будете использовать и установить нужные параметры их работы.
Затем мастер («визад») создаст файл проекта .prj и файл исходного текста программы на языке Си с расширением .c — в нем уже будет содержаться код на Си конфигурирующий МК по сделанному вами «заказу».
Вам нужно будет добавить лишь код реализующий нужный вам алгоритм работы устройства.
Используйте этот мастер и далее по ходу работы программы — точно так же как и в начале, но не генерируйте новые файлы а просто откройте меню «файлы — просмотр» и посмотрите нужный кусок программы на Си, возьмите что вам нужно и вставьте в вашу программу.
Подробно
и с картинками работу с КодВизадом —
мастером начального кода
CodeVisionAVR | ||
Обязательно читайте Help к компилятору — по сути это одновременно и учебник по Си для AVR и именно в нужном вам объеме !
Это относится и к другим используемым вами программам.
Читайте инструкцию и помощь !
Смотрите пробуйте изучайте ПРИМЕРЫ к программе !
Компилятор CodeVisionAVR имеет и встроенный программный модуль для прошивки МК и конфигурирования фьюзов AVR fuse прямо в схеме устройства.
Компания Atmel подсказывает как начать
работать
с этим компилятором Си для AVR:
AN AVR033 «Getting Started with the CodeVisionAVR C Compiler»
Это
АпНоуто Atmel — надеюсь вы
уже скачали хотя бы их список !
Если нет то скачайте обязательно их перечень.
Они ВСЕ нужны ВАМ !!! как справочник конкретно по AVR.
Для
полного цикла разработки устройства
достаточно
только одного
компилятора CodeVisionAVR.
Однако, я рекомендую вам, скачать
еще один
компилятор:
ICC AVR от ImageСraft
Я
использую и его генератор
начального кода на Си —
конфигуратор периферии
AVR — в
паре с CodeWizardAVR.
Работая
в паре, два мастера конфигурирования МК —
идеально дополняют друг друга!
Например конфигурация
Таймеров МК по моему лучше, понятней
и
наглядней сделана в
мастере ICC.
Atmel
— подсказывает как начать работать и с
этим
компилятором Си для AVR в Апликейшн
Ноуте:
AN AVR031 «Getting Started with ImageCraft C for AVR»
В компиляторах есть отличные в CodeVisionAVR примеры в папке — CVAVR\Examples в ICC примеры находятся в папке — ICC\examples.avr Примеры — это исходные тексты программ на Си для управления периферией МК и интерфейса (общения) с популярными внешними устройствами. Исходники снабжены подробными комментариями! Комментарии это то
что написано : Не забывайте и вы комментировать тексты ваших программ! Иначе, буквально через пару месяцев, вам будет очень затруднительно понять, что делает тот или иной кусок даже ВАШЕЙ программы! | ||
Существуют и другие компиляторы.
БЕСПЛАТНЫЙ и великолепный WinAVR
Бесплатный пакет на основе компилятора GCC — о нем очень хорошие отзывы.
Создает очень правильный и компактный код!
Есть версия и под Linux. Есть вариант WinAVR в USB-флэшке.
Этот
компилятор хорошо интегрируется с
симулятором VMLAB
и фирменной средой разработки Atmel —
AVRstudio
Вы ставите на ПК WinAVR и далее работаете в AVR Studio или из симулятора VMLAB.
В нем есть пример такой интеграции, находится
в папке:
C:\VMLAB\WinAVRdemo
Работать с самим WinAVR тоже очень просто.
Компиляция проекта в WinAVR
— запустите «пуск» -> «WinAVR» -> «Programmers NotePad»
— откройте демо проект C:\WinAVR\examples\demo\demo.c
— затем меню «Tools» и «Make All»
Проект откомпилируется и в папке C:\WinAVR\examples\demo\ появятся:
demo.hex — файл для прошивки в микроконтроллер AVR
demo.lst — это листинг на ассемблере с привязкой к Си коду программы
demo.elf — файл содержит информацию для
отладки программы в симуляторе.
Например в PROTEUS.
Подробней
о настройке WinAVR читайте в низу этой страницы.
AtmanAVR C/C++ Compiler AVRGCC —
он как и WinAVR основан
на GCC но имеет отладчик и ГЛАВНОЕ
для начинающего:
прекрасный мастер генератор начального кода !
Возможно лучший и самый дорогой !
IAR — требует несколько замысловатой настройки, не имеет множества примеров в инсталляции и не имеет генератора начального кода. Хотя компания IAR явно считает генератор полезным, так как продает его в виде отдельного программного продукта.
Компилятор
IAR генерирует самый
быстрый и компактный код.
Demo версия на 30 дней — полностью рабочая
без ограничений, нет только
не нужных начинающему исходников включенных в пакет библиотек.
Вы можете скачать DEMO с сайта производителя — примерно
105 Мб.
А некоторые не брезгуют и полный IAR стянуть
ТАМ
Примеры программ на Си
подходят Так
как язык Си машино не зависимый — т.е.
программы мало Огромное
количество НУЖНЫХ исходников | ||
Скачивать большие файлы рекомендую бесплатной программой ReGet — эта качалка позволяет докачивать файлы после обрыв соединения, в несколько приемов.
|
—
записывайте возникающие вопросы ! — найдите в DataSheet (ДШ) регистры и устройства МК о которых шла речь, прочитайте о них подробней. — если вопросы остались перечитайте снова ! — если вопросы не разрешены, ищите ответ: 1) в help и документации компилятора, симулятора, других используемых программ! 2) поиском Windows в папках и help компилятора и симулятора. 3) поиском Windows в папке где сохранен у вас курс. 4) в моем не структурированном AVRFAQ — это сборник ответов на часто задаваемые мне по курсу вопросы и советы по применению МК от знающих людей.
|
|
Средства
отладки программ
и устройств содержащих
МК AVR
Симуляторы для AVR и электроники
Вы
скачали компилятор Си для AVR
CodeVisionAVR
(и надеюсь очень — АпНоуты !)
инсталлировали его и получили файл
прошивку для МК.
Естественно вы
хотите узнать — будет ли прошивка, а
значит ваша программа работать в МК так
как вам нужно. Для этого удобно использовать
специальные программы для ПК называемые
симуляторами. Не
имея МК, не покупая эл. компонентов и без
пайки
Без риска спалить что либо !
Вы можете проверить работу не только программы загруженной в модель МК но и работу модели целого электронного устройства! Записать на диск результат его работы для последующего анализа, поиска недочетов.
В задачах-упражнениях курса я использую
Бесплатный симулятор-эмулятор
для AVR —
VMLAB
скачайте
и
установите на ПК
Несмотря
на небольшой размер (около 4.2 Мб),
программа является самостоятельным
средством разработки ПО на ассемблере
для МК сразу двух производителей: ATMEL.com и
ST.com !!!
В одном флаконе!
Мультипроцессорность — это эмуляция двух МК в устройстве, у каждого своя прошивка и они работают не зависимо — это очень мощно если правильно этим воспользоваться!
Юзер дефайн компонентс — в общем
если вам нужен какой либо электронный
компонент отсутствующий в списке VMLAB, вы
можете создать его сами!
в соответствии с
ДШ или по вашим потребностям — даже
не
существующий в природе!
Если вы считаете эту информацию полезной,
пожалуйста, помогите информировать в
интернете о курсе — просто щелкните по банеру.
Большое спасибо ! Electronic Banner Exchange (ElBE) |
Я сделал упражнение — задачу 3 в которой очень подробно рассмотрел симуляцию программы на VMLAB с картинками.
Симуляция в VMLAB используется и в других задачах курса
В
поставку VMLAB включено множество примеров программ и прошивок для немедленной
симуляции — эмуляции устройства с МК. Примеры находятся в папках: Tutorial и AVR_demo Запустите их и освойтесь, поиграйте | ||
Есть пример
работы VMLAB с CodeVisionAVR !
откройте
файл проекта
C:\VMLAB\AVR_demo\codevisi.prj
и по-симулируйте !
При симуляции вы увидите движение по исходному тексту программы на Си, и можете расставлять точки останова программы, наблюдать за изменениями значений в регистрах МК, посмотреть осциллограммы сигналов на ножках МК и многое другое …
Уже
упоминал: пример
работы VMLAB с WinAVR вы устанавливаете winavr в папку по умолчанию и
больше ни когда не заглядываете в неё
!
Вся
работа от написания кода на Си до
отладки выполняется
из VMLAB — это очень удобно.
C:\VMLAB\WinAVRdemo\файлы.prj
захотите попробуете …
Совет ! Скачайте
мою заготовку (Шаблон, «РЫБА», темплэйт) компилятора
CodeVisionAVR и Скриншот симуляции программы в VMLAB Распакуйте файлы из архива в папку: С:\VMLAB\WORK Теперь откройте проект cv.prj в
компиляторе CodeVisionAVR. Для эмуляции работы устройства
откройте Вы можете проверить работу программы на Си для МК ATmega16 мигающей светодиодами и посылающей сообщение через USART на монитор-терминал VMLAB. Если добавить адаптер MK- rs232 (описан в задаче 6 курса, там же и рекомендации) то сообщения можно будет увидеть на экране ПК. В общем качайте ! — это нужно ВАМ !
Такая
же по сути заготовка — но для
компилятора | ||
|
повторю
:
На софт-эмуляторе симуляторе VMLAB мы будем проверять работу программы для разрабатываемого устройства.
Файл-прошивку для МК (расширение .hex) созданный в компиляторе будем прогонять
в симуляторе МК с внешними компонентами
и смотреть что работает, что нет, и как
работает…
При необходимости будем корректировать
исходный текст программы
на Си, опять
компилировать, и так по кругу до
достижения правильной
работы
устройства.
Этот процесс
называется — отладка программы или
дебагинн — очистка от всякой нечисти —
«тараканов» и «жучков»…
Скачав рекомендованные
программы —
установите
их на диск С:\ в каталоги :
CVAVR ICCv7avr VMLAB
тогда рабочие файлы будут находятся по тем же адресам что и в задачах-примерах.
Значит будет проще помочь, ответить на ваши вопросы.
Сделайте
архивы установленных программ целиком
— это поможет восстановить, случайно
испорченные при опробовании программ,
файлы примеров и помощи, без переИнсталляции.
Хелпы во всех рекомендуемых программах качественные и подробные! НЕ забывайте их читать! Они написаны для ВАС ! Как, в прочем, и этот курс … | ||
ОБЯЗАТЕЛЬНО используйте !
Пакет
для разработки электронных устройств
от
схемы до печатной платы
PROTEUS
Действительно супер программа !
Очень советую !
Во первых PROTEUS может симулировать несколько МК в одном устройстве, причем не только AVR но и PIC и Motorola и 8051 и даже ARM7 вперемешку !
Во вторых в поставку PROTEUS входит очень много моделей компонентов.
В третьих
вы можете симулировать любые электронные
устройства и не
содержащие МК и очень сложные и электро-механические
системы — это очень
полезно.
Вам нужно проверить
какую то идею
или вариант реализации
чего либо ?
Вы можете не паять, не искать детали, запоминающий осциллограф и другие измерительные приборы, а …
Просто
«соберите» вашу схему на ПК в PROTEUS и
посмотрите как
она будет работать, каковы будут её параметры.
PROTEUS — симулирует очень реалистично !
И главное наглядно видна работа устройства, напряжения и токи в нем.
В четвертых
PROTEUS — по сути справочник электронных компонентов
Когда вы просматриваете библиотеки для добавления компонента на схему — вам сразу показываются его основные свойства и корпус компонента — какова его площадка на плате. Просто класс !
Для поиска компонента вам достаточно ввести в окно несколько символов из его марки или описания и затем выбрать из предложенных категорий.
в
пакет включены отличные
примеры работы
в PROTEUS
примерно 80 устройств готовых к симуляции.
Это :
— дата
логер
на жесткий диск (есть модель IDE HDD ! )
— можно поиграть в шахматы с ATmega128 !!! (есть модель
«точскрина» )
— есть пример работы с графическим LCD
дисплеем
— управление шаговым двигателем
— управление электродвигателем
— управление servo
— радиочастотные схемы, трансформаторы, линии передачи.
— конечно кнопки, индикаторы, светодиоды, связь с ПК, разные датчики, память
— конечно есть виртуальные приборы.
— отладка интерфейсов UART i2c TWI SPI
Читайте — Краткий учебный Курс Самоучитель PROTEUS
Симулятор электронных устройств ПРОТЕУС, поддерживает микроконтроллеры AVR , 8051, PIC10, PIC16, PIC18, ARM7, Motorola MC68HC11
Полная система проектирования !
От идеи до
результатов работы устройства
и файлов для платы.
Быстрый старт, самые первые шаги …
А
если нет модели нужного
вам компонента ?
Вот что я придумал ! Если вы не находите модели нужного вам компонента, то вы можете изобразить ее с помощью еще одного МК и возможно некоторых существующих компонентов. Дело в том что симуляторы не против не реально высокой частоты работы симулируемого МК — я пробовал 500 МГц в PROTEUS и все работает. Думаю вычислительная мощность МК в таком режиме позволит вам изобразить что угодно.
Преимущество моего метода Вам не нужно изучать методику и иметь инструментарий для создания моделей для VMLAB или PROTEUS стандартным способом. Вы лишь лишний раз поупражняетесь в программировании МК с которым работаете. Кроме того теперь PROTEUS не работает с моделями созданными без специально полученного кода для создания модели ! А по моему методу вы сможете делать модели и при желании продавать их не имея такой лицензии и законно! Надеюсь вы попробуете такой финт ушами … | ||
Итог этой
страницы курса :
Вам необходимы две программы — CVAVR
и VMLAB
для усвоения дальнейшего материала
курса.
<- Назад Дальше ->
В низу этой страницы есть описание
настройки WinAVR и AVRstudio