Программирование avr контроллеров с чего начать. CodeVisionAVR. Общие сведения, для начинающих программировать на языке Си. Так что же такое, микроконтроллер

Принципиальная схема программатора на LPT порт показана на рисунке. В качестве шинного формирователя используйте микросхему 74AC 244 или 74HC244 (К1564АП5), 74LS244 (К555АП5) либо 74ALS244 (К1533АП5).

Светодиод VD1 индицирует режим записи микроконтроллера,

светодиод VD2 - чтения,

светодиод VD3 - наличие питания схемы.

Напряжение, необходимое для питания схема берёт с разъёма ISP, т.е. от программируемого устройства. Эта схема является переработанной схемой программатора STK200/300 (добавлены светодиоды для удобства работы), поэтому она совместима со всеми программами программаторов на PC, работающих со схемой STK200/300. Для работы с этим программатором используйтепрограмму CVAVR

Программатор можно выполнить на печатной плате и поместить её в корпус разъёма LPT, как показано на рисунках:




Для работы с программатором удобно использовать удлинитель LPT порта, который несложно изготовить самому (к примеру, из кабеля Centronix для принтера), главное "не жалеть" проводников для земли (18-25 ноги разъёма) или купить. Кабель между программатором и программируемой микросхемой не должен превышать 20-30 см.
В этом учебном курсе по avr я постарался описать все самое основное для начинающих программировать микроконтроллеры avr . Все примеры построены на микроконтроллере atmega8 . Это значит, что для повторения всех уроков вам понадобится всего один МК. В качестве эмулятора электронных схем используется Proteus - на мой взгляд, - лучший вариант для начинающих. Программы во всех примерах написаны на компиляторе C для avr CodeVision AVR. Почему не на каком-нибудь ассемблере? Потому что начинающий и так загружен информацией, а программа, которая умножает два числа, на ассемблере занимает около ста строк, да и в сложных жирных проектах используют С. Компилятор CodeVision AVR заточен под микроконтроллеры atmel, имеет удобный генератор кода, неплохой интерфейс и прямо с него можно прошить микроконтроллер.

В этом учебном курсе будет рассказано и показано на простых примерах как:

  • Начать программировать микроконтроллеры, с чего начать, что для этого нужно.
  • Какие программы использовать для написания прошивки для avr, для симуляции и отладки кода на ПК,
  • Какие периферийные устройства находятся внутри МК, как ими управлять с помощью вашей программы
  • Как записать готовую прошивку в микроконтроллер и как ее отладить
  • Как сделать печатную плату для вашего устройства
Для того, чтобы сделать первые шаги на пути программирования МК, вам потребуются всего две программы:
  • Proteus - программа-эмулятор (в ней можно разработать схему, не прибегая к реальной пайке и потом на этой схеме протестировать нашу программу). Мы все проекты сначала будем запускать в протеусе, а потом уже можно и паять реальное устройство.
  • CodeVisionAVR - компилятор языка программирования С для AVR. В нем мы будем разрабатывать программы для микроконтроллера, и прямо с него же можно будет прошить реальный МК.
После установки Proteus, запускаем его
Он нам предлагает посмотреть проекты которые идут с ним, мы вежливо отказываемся. Теперь давайте создадим в ней самую простую схему. Для этого кликнем на значок визуально ничего не происходит. Теперь нужно нажать на маленькую букву Р (выбрать из библиотеки) в панели списка компонентов, откроется окно выбора компонентов
в поле маска вводим название компонента, который мы хотим найти в библиотеке. Например, нам нужно добавить микроконтроллер mega8
в списке результатов тыкаем на mega8 и нажимаем кнопку ОК . У нас в списке компонентов появляется микроконтроллер mega8
Таким образом добавляем в список компонентов еще резистор, введя в поле маска слово res и светодиод led

Чтобы разместить детали на схеме, кликаем на деталь, далее кликаем по полю схемы, выбираем место расположения компонента и еще раз кликаем. Для добавления земли или общего минуса на схему слева кликаем "Терминал" и выбираем Ground. Таким образом, добавив все компоненты и соединив их, получаем вот такую простенькую схемку
Все, теперь наша первая схема готова! Но вы, наверное, спросите, а что она может делать? А ничего. Ничего, потому что для того, чтобы микроконтроллер заработал, для него нужно написать программу. Программа - это список команд, которые будет выполнять микроконтроллер. Нам нужно, чтобы микроконтроллер устанавливал на ножке PC0 логический 0 (0 вольт) и логическую 1 (5 вольт).

Написание программы для микроконтроллера

Программу мы будем писать на языке С в компиляторе CodeVisionAVR. После запуска CV, он спрашивает нас, что мы хотим создать: Source или Project Мы выбираем последнее и нажимаем кнопку ОК. Далее нам будет предложено запустить мастер CVAVR CodeWizard (это бесценный инструмент для начинающего, потому как в нем можно генерировать основной скелет программы) выбираем Yes
Мастер запускается с активной вкладкой Chip, здесь мы можем выбрать модель нашего МК - это mega8, и частоту, на которой будет работать МК (по умолчанию mega8 выставлена на частоту 1 мегагерц), поэтому выставляем все, как показано на скриншоте выше. Переходим во вкладку Ports
У микроконтроллера atmega8 3 порта: Port C, Port D, Port B. У каждого порта 8 ножек. Ножки портов могут находиться в двух состояниях:
  • Выход
С помощью регистра DDRx.y мы можем устанавливать ножку входом или выходом. Если в
  • DDRx.y = 0 - вывод работает как ВХОД
  • DDRx.y = 1 вывод работает на ВЫХОД
Когда ножка сконфигурирована как выход, мы можем выставлять на ней лог 1 (+5 вольт) и логический 0 (0 вольт). Это делается записью в регистр PORTx.y. Далее будет подробно рассказано про порты ввода-вывода. А сейчас выставляем все, как показано на скриншоте, и кликаем File->Generate, Save and Exit. Дальше CodeWizard предложит нам сохранить проект, мы его сохраняем и смотрим на код:

#include //библиотека для создания временных задержек void main(void) { PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x01; // делаем ножку PC0 выходом PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization TCCR0=0x00; TCNT0=0x00; // Timer/Counter 1 initialization TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; // Analog Comparator initialization ACSR=0x80; SFIOR=0x00; while (1) { }; }


Здесь вам может показаться все страшным и незнакомым, но на самом деле все не так. Код можно упростить, выкинув инициализацию неиспользуемых нами периферийных устройств МК. После упрощения он выглядит так:

#include //библиотека для работы с микроконтроллером mega8 #include //библиотека для создания временных задержек void main(void) { DDRC=0x01; /* делаем ножку PC0 выходом запись 0x01 может показаться вам незнакомой, а это всего лишь число 1 в шестнадцатиричной форме, эта строка будет эквивалентна 0b00000001 в двоичной, далее я буду писать именно так.*/ while (1) { }; }


Всё хорошо. Но для того, чтобы светодиод замигал, нам нужно менять логический уровень на ножке PC0. Для этого в главный цикл нужно добавить несколько строк:

#include //библиотека для работы с микроконтроллером mega8 #include //библиотека для создания временных задержек void main(void) { DDRC=0x01; /* делаем ножку PC0 выходом запись 0x01 может показаться вам незнакомой, а это всего лишь число 1 в шестнадцатиричной форме, эта строка будет эквивалентна 0b00000001 в двоичной, далее я буду писать именно так.*/ while (1)//главный цикл программы {// открывается операторная скобка главного цикла программы PORTC.0=1; //выставляем на ножку 0 порта С 1 delay_ms(500); //делаем задержку в 500 милисекунд PORTC.0=0; //выставляем на ножку 0 порта С 0 delay_ms(500); //делаем задержку в 500 милисекунд };// закрывается операторная скобка главного цикла программы }


Все, теперь код готов. Кликаем на пиктограму Build all Project files, чтобы скомпилировать (перевести в инструкции процессора МК) нашу программу. В папке Exe, которая находится в нашем проекте, должен появиться файл с расширением hex, это и есть наш файл прошивки для МК. Для того, чтобы нашу прошивку скормить виртуальному микроконтроллеру в Proteus, нужно два раза кликнуть на изображении микроконтроллера в протеусе. Появится вот такое окошко
кликаем на пиктограму папки в поле Program File, выбераем hex - файл нашей прошивки и нажимаем кнопку ОК. Теперь можно запустить симуляцию нашей схемы. Для этого нажимаем кнопку "Воспроизвести" в нижнем левом углу окна Протеус.

Программирование микроконтроллеров AVR для начинающих.Программирование самых популярных мк — ATMega8, ATTiny13.

Что такое микроконтроллер? Микроконтроллер это по сути микрокомпьютер с процессором, оперативной и постоянной памятью, портами ввода-вывода, во многих микроконтроллерах имеется аналого цифровой преобразователь.

Прежде всего для написания программ под Atmel AVR нужно установить программу Atmel Studio, скачать ее можно с официального сайта Atmel сайта Microchip (Microchip выкупил Atmel), программа полностью бесплатна:

http://www.microchip.com/mplab/avr-support/atmel-studio-7

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

(Примечание — иногда результат работы на реальном железе может отличаться от результата эмуляции железа, так что при окончательном, финальном варианте написанной программы, проверка на реальном железе — обязательна).

Atmel Studio установлена.

(если при запуске или установке возникает ошибка «Cannot find one or more components.Please reinstall the application» (Не найден один или несколько компонентов.Пожалуйста, переустановите приложение.)- необходимо удалить программу, переименовать папку C:\ProgramData\Package Cache (не следует ее удалять, так как в случае чего, можно ее снова переименовать в исходное имя, если некоторые приложения после этого перестали работать), тогда программа установится и запустится нормально).

Запустили.

В левом верхнем углу выбираем:

File => New => Project

Выбираем GCC C Executable Project (на изображении под цифрой 1 ), В низу, в поле Name(2 ) указываем имя нашего проекта, в поле Location(3 ) можем выбрать местоположение проекта или оставить путь по умолчанию, нажимаем OK.

Затем выбираем модель нашего микроконтроллера из списка, в нашем случае это ATMEGA8(можно выбрать Attiny13 или другой нужный и имеющийся у вас микроконтроллер):

В окне появится среда разработки написания кода, где уже будет стандартный код на Си и несколько закомментированных строк с указанием авторства и даты:

Под цифрой 1 находится окно написания кода, под цифрой 2 файлы с исходным кодом, библиотеки и все файлы, связанные с исходным кодом, в файле main.c находится текст нашего кода.

Что же делает этот код?

строка #include подключает стандартную библиотеку портов ввода, вывода микроконтроллеров AVR,

ее можно найти по пути(если вы не поменяли путь при установке) «C:\Program Files\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr»

Функция main — стандартная входная функция Си, с который программа и начинает работу.

Внутри функции main находится цикл while, который длится бесконечно.

А в теле цикла ничего нет т.е. программа ничего не делает, просто идет бесконечный цикл, и выхода из функции main не происходит, поэтому там нет ключевого слова return, которое возвращает указанное значение.

Для того, чтобы скомпилировать написанный код, необходимо выбрать вверху Build => Build «Имя_Вашего_Проекта».

Если код без ошибок, то программа скомпилируется и внизу будет написано Build succeeded.

В итоге скомпилированная прошивка будет в формате.HEX и будет лежать по адресу(опять же, если вы не изменили стандартное месторасположение):

C:\Users\Имя Пользователя\Documents\Atmel Studio\7.0\ИмяПроекта\ИмяПроекта\Debug\ИмяПроекта.hex

Примечание.Если выбрать вариант сборки Release, то прошивка будет лежать в соответствующей папке т.е. не в папке Debug, а в папке Rele ase.

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

#define F_CPU 1000000UL // 1 MHz Здесь задаем частоту микроконтроллера #include //библиотека ввода\вывода #include //библиотека задержки int main(void ) // начало основой программы { DDRD = 0xff ; // установить все порты D(смотрите распиновку мк) как выводы while (1 ) { // бесконечный цикл PORTD = 0xff ; // установить "1"(вкл) на всех линиях порта D _delay_ms(250 ) ; // ждем 250 миллисекуд PORTD = 0x00 ; // установить "0"(выкл) на всех линиях порта D _delay_ms(250 ) ; // ждем 250 миллисекунд } //закрывающая скобка бесконечного цикла } //скобка входной функции main

#define F_CPU 1000000UL // 1 MHz Здесь задаем частоту микроконтроллера #include //библиотека ввода\вывода #include //библиотека задержки int main(void) // начало основой программы { DDRD = 0xff; // установить все порты D(смотрите распиновку мк) как выводы while (1) { // бесконечный цикл PORTD = 0xff; // установить "1"(вкл) на всех линиях порта D _delay_ms(250); // ждем 250 миллисекуд PORTD = 0x00; // установить "0"(выкл) на всех линиях порта D _delay_ms(250); // ждем 250 миллисекунд } //закрывающая скобка бесконечного цикла } //скобка входной функции main

Компилируем код, получаем готовую прошивку.

Прошиваем этой прошивкой микроконтроллер, собираем схему на железе.

Если не знаете как прошивать, узнать можно здесь:

В следующей статье узнаем как проверить написанный код в Proteus т.е. будем эмулировать работу железа.

Решил написать небольшую вводную статейку для тех, кто впервые взялся за программирование микроконтроллеров и никогда раньше не был знаком с языком Си. В подробности влезать не будем, обо всем понемногу, чтобы получить общее представление по работе с CodeVisionAVR.

Более подробную информацию можно посмотреть на английском языке в CodeVision User Manual, а также рекомендую сайт http://somecode.ru с видеоуроками по Си для микроконтроллеров и книгу «Как программировать на С» автор Дейтель, это единственная годная книга, с которой я сам начинал.

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

Сама прошивка имеет расширение.hex и представляет собой набор инструкций, в виде единиц и нулей, который понятен микроконтроллеру. Откуда взять прошивку? Ее можно скачать с сайтов по электронике, либо написать самому. Написать ее можно в специальных программах, которые называются средой разработки. Из наиболее известных мне AVR Studio, IAR, CodeVision, WinAVR… Нельзя сказать, что какая из этих сред лучше или хуже, каждому свое. Можно сказать, что различаются эти программы в основном удобством, языком программирования и ценой. В пределах данного сайта, рассматривается только CodeVision.

Со средой разобрались, теперь разберемся с процессом написания прошивки. В CodeVision изначально нужно создать проект. Его можно создать при помощи мастера кода или пустой. В любом случае, нужно выбрать тип используемого микроконтроллера и указать его частоту. При использовании мастера, вам будет предложено выбрать начальные настройки и сгенерировать исходный код с настройками. Далее появится окно, в котором можно редактировать этот код. Хотя вы можете написать свой исходный код, в блокноте и потом прицепить его к проекту в настройках.

Файл с исходным кодом является набором команд на языке программирования, задача CodeVision`а перевести эти команды в двоичный код, ваша задача написать этот исходный код. CodeVision понимает язык Си, файлы с исходным кодом имеют расширение «.c». Но у CodeVision есть некоторые конструкции, которые не используются в Си, за это его многие программисты не любят, а используемый язык называют Си подобным. Однако, это не мешает писать серьезные проекты. Множество примеров, генератор кода, большой набор библиотек дает большой плюс CodeVision`у. Единственный минус, то что он платный, хотя есть бесплатные версии с ограничением кода.

Исходный код должен содержать заголовок с используемым типом микроконтроллера и функцию main. Например, используется ATtiny13

#include void main(void ) { } ;

#include void main(void) { };

До функции main можно подключить необходимые библиотеки, объявить глобальные переменные, константы, настройки. Библиотека это отдельный файл, обычно с расширением «.h», в котором уже есть заранее написанный код. В одних проектах этот код может быть нам нужен, а в других не нужен. Например, в одном проекте мы используем жк дислей, а в другом не используем. Подключить библиотеку для работы с жк дисплеем «alcd.h», можно так:

#include #include void main(void ) { } ;

#include #include void main(void) { };

Переменные это участки памяти, в которые можно поместить некие значения. Например, сложили два числа, результат нужно, где то сохранить, чтобы использовать в дальнейшем. Сначала необходимо объявить переменную, т.е. выделить под нее память, например:
int i=0;
т.е. мы объявили переменную i и поместили в нее значение 0, int – тип переменной, или проще говоря, означает размер выделенной памяти. Каждый тип переменных может хранить только определенный диапазон значений. Например, int можно записать числа от -32768 до 32767. Если нужно использовать числа с дробной частью значит, переменную нужно объявлять как float, для символов используют тип char.

bit, _Bit 0 или 1 char от -128 до 127 unsigned char от 0 до 255 int от -32768 до 32767 unsigned int от 0 до 65535 long int от -2147483648 до 2147483647 unsigned long int от 0 до 4294967295 float от ±1.175e-38 до ±3.402e38

Внутри функции main уже выполняется основная программа. После выполнения функции программа остановится, поэтому делают бесконечный цикл while, который крутит одну и ту же программу постоянно.

void main(void ) { while (1 ) { } ; } ;

void main(void) { while (1) { }; };

В любой части исходного кода можно написать комментарий, на работу программы он влиять никак не будет, но будет помогать сделать пометки к написанному коду. Закомментировать строку можно двумя слешами //после этого компилятор будет игнорировать всю строку, либо несколько строк /**/, например:

/*Основные математические операции:*/ int i= 0 ; //объявляем переменную i и присваиваем ей значение 0 //Сложение: i = 2 + 2 ; //Вычитание: i = 2 - 2 ; //после выполнения данного выражения переменная i будет равна 0 //Умножение: i = 2 * 2 ; //после выполнения данного выражения переменная i будет равна 4 //Деление: i = 2 / 2 ; //после выполнения данного выражения переменная i будет равна 1

/*Основные математические операции:*/ int i=0; //объявляем переменную i и присваиваем ей значение 0 //Сложение: i = 2+2; //после выполнения данного выражения переменная i будет равна 4 //Вычитание: i = 2-2; //после выполнения данного выражения переменная i будет равна 0 //Умножение: i = 2*2; //после выполнения данного выражения переменная i будет равна 4 //Деление: i = 2/2; //после выполнения данного выражения переменная i будет равна 1

Зачастую в программе требуется выполнить переход от одного куска кода к другому, в зависимости от условий, для этого существует условные операции if(), например:

if(i>3) //если i больше 3, то присвоить i значение 0 { i=0; } /*если i меньше 3, то перейти к коду следующему после тела условия, т.е. после скобок {}*/

Также if можно использовать совместно с else – иначе

if(i<3) //если i меньше 3, то присвоить i значение 0 { i=0; } else { i=5; //иначе, т.е. если i больше 3, присвоить значение 5 }

Также имеется операция сравнения «==» ее нельзя путать с «=» присвоить. Обратная операция не равно «!=», допустим

if(i==3)//если i равно 3, присвоить i значение 0 { i=0; } if(i!=5) //если i не равно 5, присвоить i значение 0 { i=0; }

Перейдем к более сложным вещам – функциям. Допустим, у вас есть некий кусок кода, который повторяется несколько раз. Причем этот код довольно большой в размерах. Писать его каждый раз неудобно. Например, в программе, каким то образом изменяется переменная i, при нажатии на кнопку 0 и 3 порта D выполняется одинаковый код, который в зависимости от величины переменной i включает ножки порта B.

void main(void ) { if (PIND.0== 0 ) //проверяем нажата ли кнопка на PD0 { if (i== 0 ) //если i==0 включить PB0 { PORTB.0= 1 ; } if (i== 5 ) // если i==5 включить PB1 { PORTB.1= 1 ; } } … if (PIND.3== 0 ) // выполняем тоже самое, при проверке кнопки PD3 { if (i== 0 ) { PORTB.0= 1 ; } if (i== 5 ) { PORTB.1= 1 ; } } }

void main(void) { if(PIND.0==0) //проверяем нажата ли кнопка на PD0 { if(i==0) //если i==0 включить PB0 { PORTB.0=1; } if(i==5) // если i==5 включить PB1 { PORTB.1=1; } } … if(PIND.3==0)// выполняем тоже самое, при проверке кнопки PD3 { if(i==0) { PORTB.0=1; } if(i==5) { PORTB.1=1; } } }

В общем, то код не очень большой, но он мог бы быть еще и больше во много раз, поэтому гораздо удобнее было бы создать свою функцию.
Например:

void i_check() { if (i== 0 ) { PORTB.0= 1 ; } if (i== 5 ) { PORTB.1= 1 ; } }

void i_check() { if(i==0) { PORTB.0=1; } if(i==5) { PORTB.1=1; } }

void означает что функция ничего не возвращает, об этом чуть ниже i_check() – это название нашей функции, можете назвать как угодно, я назвал именно так – проверка i. Теперь мы можем переписать наш код:

void i_check() { if(i==0) { PORTB.0=1; } if(i==5) { PORTB.1=1; } } void main(void) { if(PIND.0==0) //проверяем нажата ли кнопка на PD0 { i_check(); } … if(PIND.3==0) { i_check(); } }

Когда код будет доходить до строчки i_check(); то он перепрыгнет внутрь функции и выполнит код внутри. Согласитесь, код компактнее и нагляднее, т.е. функции помогают заменить одинаковый код, всего на одну строчку. Обратите внимание, что функция объявляется вне основного кода, т.е. до функции main. Можно сказать, да зачем мне это надо, но изучая уроки вам часто будут попадаться функции, например очистка жк экрана lcd_clear() — функция не принимает никаких параметров и ничего не возвращает, однако очищает экран. Иногда эта функция используется чуть ли не через строчку, так что экономия кода очевидна.

Намного интереснее выглядит применение функции, когда она принимает значения, например, есть переменная c и есть функция sum, которая принимает два значения типа int. Когда основная программа будет выполнять эту функцию, то в скобках уже указаны аргументы, таким образом «a» станет равной двум, а «b» станет равной 1. Функция выполнится и «с» станет равна 3.

int c= 0 ; void sum(int a, int b) { c= a+ b; } void main(void ) { sum(2 , 1 ) ; }

int c=0; void sum(int a, int b) { c=a+b; } void main(void) { sum(2,1); }

Одна из часто встречаемых подобных функций это перевод курсора у жк дисплея lcd_gotoxy(0,0); которая, кстати, тоже принимает аргументы – координаты по х и у.

Еще один вариант использования функции, когда она возвращает значение, теперь она уже не будет void, усовершенствуем предыдущий пример функции сложения двух чисел:

int c= 0 ; int sum(int a, int b) { return a+ b; } void main(void ) { с= sum(2 , 1 ) ; }

int c=0; int sum(int a, int b) { return a+b; } void main(void) { с=sum(2,1); }

Результат будет такой же как и в прошлый раз c=3, однако обратите внимание, мы переменной «с» присваиваем значение функции, которая уже не void, а возвращает сумму двух чисел типа int. Таким образом мы не привязываемся к конкретной переменной «с», что добавляет гибкости в использовании функций. Простой пример подобной функции — чтение данных АЦП, функция возвращает измеренное значение result=read_adc();. На этом закончим с функциями.

Теперь перейдем к массивам. Массив это связанные переменные. Например, у вас есть таблица синуса с несколькими точками, не будете же вы создавать переменные int sinus1=0; int sinus2=1; и т.д. для этого используют массив. Например, создать массив из трех элементов можно так:
int sinus={0,1,5};
в квадратных скобках указывается общее количество элементов массива. Присвоить переменной «с» значение третьего элемента можно таким образом:
с=sinus;
Обратите внимание, нумерация элементов массива начинается с нуля, т.е. «с» станет равна пяти. У данного массива элемента sinus не существует!!!
Отдельному элементу можно присвоить значение так:
sinus=10;

Возможно, вы уже успели заметить, что в CodeVision нет строковых переменных. Т.е. нельзя создать переменную string hello=”привет”; для этого придется создавать массив из отдельных символов.

lcd_putchar(hello); lcd_putchar(hello); lcd_putchar(hello);

и т.д.
Получается довольно громоздко, тут на помощь приходят циклы.
Например цикл while

while(PINB.0!=0) { }

Пока кнопка не нажата ничего не делать – гонять пустой цикл.

Еще один вариант цикл for

int i; for (i= 0 ; i< 6 ; i++ ) { lcd_putchar(hello[ i] ) ; }

int i; for(i=0;i<6;i++) { lcd_putchar(hello[i]); }

Смысл точно такой же, как и у while только добавлено начальное условие i=0 и условие, выполняемое каждый цикл i++. Код внутри цикла максимально упрощен.

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

Не стоит сразу стараться использовать циклы, массивы и функции в своих прошивках. Ваша главная задача заставить прошивку работать, поэтому делайте так как вам проще не обращайте внимание на размер кода. Придет время когда захочется не просто писать рабочий код, а написать его красиво и компактно. Тогда можно будет углубиться в дебри языка Си. Желающим овладеть всем и сразу еще раз рекомендую книгу «Как программировать на Си», там много примеров и задач. Ставьте Visual Studio, создавайте консольное приложение win32 и там вволю тренируйтесь.

Микроконтроллеры (далее МК) прочно вошли в нашу жизнь, на просторах интернета можно встретить очень много интересных схем, которые исполнены на МК. Чего только нельзя собрать на МК: различные индикаторы, вольтметры, приборы для дома (устройства защиты, коммутации, термометры…), металлоискатели, разные игрушки, роботы и т.д. перечислять можно очень долго. Первую схему на микроконтроллере я увидел лет 5-6 назад в журнале радио, и практически сразу же перелистнул страницу, подумав про себя "все равно не смогу собрать". Действительно, в то время МК для меня были чем то очень сложным и непонятым устройством, я не представлял как они работают, как их прошивать, и что делать с ними в случае неправильной прошивки. Но около года назад, я впервые собрал свою первую схему на МК, это была схема цифрового вольтметра на 7 сегментных индикаторах, и микроконтроллере ATmega8. Так получилось, что микроконтроллер я купил случайно, когда стоял в отделе радиодеталей, парень передо мной покупал МК, и я тоже решил купить, и попробовать собрать что-нибудь. В своих статьях я расскажу вам про микроконтроллеры AVR , научу вас работать с ними, рассмотрим программы для прошивки, изготовим простой и надежный программатор, рассмотрим процесс прошивки и самое главное проблемы, которые могут возникнуть и не только у новичков.

Основные параметры некоторых микроконтроллеров семейства AVR:

Микроконтроллер

Память FLASH

Память ОЗУ

Память EEPROM

Порты ввода/вывода

U питания

Дополнительные параметры МК AVR mega:

Рабочая температура: -55…+125*С
Температура хранения: -65…+150*С
Напряжение на выводе RESET относительно GND: max 13В
Максимальное напряжение питания: 6.0В
Максимальный ток линии ввода/вывода: 40мА
Максимальный ток по линии питания VCC и GND: 200мА

Расположение выводов моделей ATmega 8X

Расположение выводов моделей ATmega48x, 88x, 168x

Расположение выводов у моделей ATmega8515x

Расположение выводов у моделей ATmega8535x

Расположение выводов у моделей ATmega16, 32x

Расположение выводов у моделей ATtiny2313

В конце статьи прикреплён архив с даташитами на некоторые микроконтроллеры

Установочные FUSE биты MK AVR

Запомните, запрограммированный фьюз – это 0, не запрограммированный – 1. Осторожно стоит относиться к выставлению фьюзов, ошибочно запрограммированный фьюз может заблокировать микроконтроллер. Если вы не уверены какой именно фьюз нужно запрограммировать, лучше на первый раз прошейте МК без фьюзов.

Самыми популярными микроконтроллерами у радиолюбителей являются ATmega8, затем идут ATmega48, 16, 32, ATtiny2313 и другие. Микроконтроллеры продаются в TQFP корпусах и DIP, новичкам рекомендую покупать в DIP. Если купите TQFP, будет проблематичнее их прошить, придется купить или и паять плату т.к. у них ножки располагаются очень близко друг от друга. Советую микроконтроллеры в DIP корпусах, ставить на специальные панельки, это удобно и практично, не придется выпаивать МК если приспичит перепрошить, или использовать его для другой конструкции.

Почти все современные МК имеют возможность внутрисхемного программирования ISP, т.е. если ваш микроконтроллер запаян на плату, то для того чтобы сменить прошивку нам не придется выпаивать его с платы.

Для программирования используется 6 выводов:
RESET - Вход МК
VCC - Плюс питания, 3-5В, зависит от МК
GND - Общий провод, минус питания.
MOSI - Вход МК (информационный сигнал в МК)
MISO - Выход МК (информационный сигнал из МК)
SCK - Вход МК (тактовый сигнал в МК)

Иногда еще используют вывода XTAL 1 и XTAL2, на эти вывода цепляется кварц, если МК будет работать от внешнего генератора, в ATmega 64 и 128 вывода MOSI и MISO не применяются для ISP программирования, вместо них вывода MOSI подключают к ножке PE0, a MISO к PE1. При соединении микроконтроллера с программатором, соединяющие провода должны быть как можно короче, а кабель идущий от программатора на порт LPT так-же не должен быть слишком длинным.

В маркировке микроконтроллера могут присутствовать непонятные буквы с цифрами, например Atmega 8L 16PU, 8 16AU, 8A PU и пр. Буква L означает, что МК работает от более низкого напряжения, чем МК без буквы L, обычно это 2.7В. Цифры после дефиса или пробела 16PU или 8AU говорят о внутренней частоте генератора, который есть в МК. Если фьюзы выставлены на работу от внешнего кварца, кварц должен быть установлен на частоту, не превышающей максимальную по даташиту, это 20МГц для ATmega48/88/168, и 16МГц для остальных атмег.