Среда CodeVisionAVR является, пожалуй, самой ходовой средой для программирования микроконтроллеров AVR, т.к. заточена именно под них. Проект можно создавать как с нуля, так и с помощью мастера кода (CodeWizardAVR). Для начинающего программиста среда подходит как никогда.

 

CodeVisionAVR

Итак приступим. Создать проект можно двумя способами:

  1. С нуля, записывая в ручную все необходимые заголовочные файлы, функцию main, конфигурирование портов и т.д.
  2. Использование мастера кода (CodeWizardAVR). Очень хороший и приемлемый вариант, но в процессе работы мастера формируется большое количество ненужного кода, который впоследствии приходиться редактировать.

Ниже приведен программный код сформированный мастером кода. Вкладки остаются без изменений кроме Chip:

CodeWizardAVR

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

/*****************************************************

This program was produced by the

CodeWizardAVR V1.25.3 Professional

Automatic Program Generator

© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.

http://www.hpinfotech.com

Project :

Version :

Date : 12.11.2009

Author : skiff

Company : Programming Cu

Comments:

Chip type : ATmega8

Program type : Application

Clock frequency : 4,000000 MHz

Memory model : Small

External SRAM size : 0

Data Stack size : 256

*****************************************************/

#include <mega8.h>

// declare your global variables here

void main(void)

{

// declare your local variables here

// Input/Output Ports initialization

// Port B initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTB=0x00;

DDRB=0x00;

// Port C initialization

// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTC=0x00;

DDRC=0x00;

// Port D initialization

// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In

// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T

PORTD=0x00;

DDRD=0x00;

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

TCCR0=0x00;

TCNT0=0x00;

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: Timer 1 Stopped

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer 1 Overflow Interrupt: Off

// Input Capture Interrupt: Off

// Compare A Match Interrupt: Off

// Compare B Match Interrupt: Off

TCCR1A=0x00;

TCCR1B=0x00;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;

// Timer/Counter 2 initialization

// Clock source: System Clock

// Clock value: Timer 2 Stopped

// Mode: Normal top=FFh

// OC2 output: Disconnected

ASSR=0x00;

TCCR2=0x00;

TCNT2=0x00;

OCR2=0x00;

// External Interrupt(s) initialization

// INT0: Off

// INT1: Off

MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x00;

// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0x80;

SFIOR=0x00;

while (1)

{

// Place your code here

};

}

Как видно, много пустого кода, который приходиться удалять. Вообще в действительности CodeWizardAVR помогает создавать код, не занимаясь ручным набором. Приведу программный код сгенерированный CodeWizardAVR, где будет использована вкладка USART – включим работу передатчика, разрешим обработчик прерывания по окончанию передачи:

CodeWizardAVR, настройка USART

/************************************************/

/************************************************/

#include <mega8.h>

#define RXB8 1

#define TXB8 0

#define UPE 2

#define OVR 3

#define FE 4

#define UDRE 5

#define RXC 7

#define FRAMING_ERROR (1<<FE)

#define PARITY_ERROR (1<<UPE)

#define DATA_OVERRUN (1<<OVR)

#define DATA_REGISTER_EMPTY (1<<UDRE)

#define RX_COMPLETE (1<<RXC)

 

// USART Transmitter buffer

#define TX_BUFFER_SIZE 8

char tx_buffer[TX_BUFFER_SIZE];

 

#if TX_BUFFER_SIZE<256

unsigned char tx_wr_index,tx_rd_index,tx_counter;

#else

unsigned int tx_wr_index,tx_rd_index,tx_counter;

#endif

 

// USART Transmitter interrupt service routine

interrupt [USART_TXC] void usart_tx_isr(void)

{

if(tx_counter)

{

--tx_counter;

UDR=tx_buffer[tx_rd_index];

if(++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;

};

}

#ifndef _DEBUG_TERMINAL_IO_

// Write a character to the USART Transmitter buffer

#define _ALTERNATE_PUTCHAR_

#pragma used+

void putchar(char c)

{

while(tx_counter == TX_BUFFER_SIZE);

#asm("cli")

if(tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))

{

tx_buffer[tx_wr_index]=c;

if(++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;

++tx_counter;

}

else

UDR=c;

#asm("sei")

}

#pragma used-

#endif

 

// Standard Input/Output functions

#include <stdio.h>

// Declare your global variables here

void main(void)

{

// USART initialization

// Communication Parameters: 8 Data, 1 Stop, No Parity

// USART Receiver: Off

// USART Transmitter: On

// USART Mode: Asynchronous

// USART Baud rate: 9600

UCSRA=0x00;

UCSRB=0x48;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x19;

// Global enable interrupts

#asm("sei")

while(1)

{

// Place your code here

};

}

Лишний код был удален, оставлен только необходимый. Как видно мастер создал довольно объемный код, который особо и не хотелось вводить вручную.

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

#define RXB8 1

#define TXB8 0

#define UPE 2

#define OVR 3

. . . . .

Использование аргументов с #define – макроопределения:

#define PARITY_ERROR (1<<UPE)

#define DATA_OVERRUN (1<<OVR)

#define DATA_REGISTER_EMPTY (1<<UDRE)

. . . . . .

 

Обработчик прерывания по завершению передачи:

interrupt [USART_TXC] void usart_tx_isr(void)

{

// некоторый программный код для обработчика

}

 

Инициализация модуля USART:

UCSRA=0x00;

UCSRB=0x48;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x19;

 

Разрешение глобального прерывания:

#asm("sei")

 

Объявление переменных для хранения значений:

unsigned char tx_wr_index,tx_rd_index,tx_counter;

unsigned int tx_wr_index,tx_rd_index,tx_counter;

 

Стандартные типы данных языка С

 


Название

Тип

Диапазон

Шестнадцатеричный диапазон

Размер, бит

char

символ

-128 ... 127

-0x80 ... 0x7F

8

 

unsigned char

Беззнаковый символ или логическое значение

0 ... 255

 

True, False

 

0x00 ... 0xFF

8

Unsigned int

Беззнаковое число

0 ... 65535

0x0000 ... 0xFFFF

16

Long int

Длинное целое

-2147483648…

2147483647

-80000000…7FFFFFFF

 

32

int

Целое число

-32768…32767

-8000…7FFF

16

Unsigned Long int

 

Беззнаковое длинное целое

0…4294967295

0…FFFFFFFF

32

float

Вещественное

число

-+1,175*10-38

-+3,402*1038

 

-

32

 

Создадим проект без CodeWizardAVR.

Запускаем приложение CodeVisionAVR C Compiler. Если открылся какой-либо проект, то его закрываем: File -> Close Project.

На панели инструментов нажимаем по значку значок - создать новый файл - create new file или в меню File -> New.

В форме create new project выбираем Project (проект), на предложение создать код с помощью мастера – жмем кнопочку No.

CodeVisionAVR - создание нового проекта

Сохраняем проект как Prog1.

сохранение проекта в CodeVisionAVR

Выбираем микроконтроллер, определяем частоту кварца и, нажимаем OK:

настройка проекта CodVisionAVR - выбор чипа и тактовой частоты

Список File Output Format(s) определяет, какие файлы будут созданы при компиляции проекта. Наиболее интересны два файла: откомпилированный файл HEX, который «зашивается» в микроконтроллер и откомпилированный файл COF, который можно открыть в среде AVR studio и с помощью симулятора проанализировать работу программы.

Снова выбираем File -> New и File Type -> Source (Исходный текст программы). Появилось пустое окно кода, сохраняем его как Prog1.c.

Открываем окно Configure Project кнопка настройка проекта в CodeVisionAVR и на вкладке Files добавляем ранее сохраненный файл Prog1.c:

добавление файлов в проект CodeVisionAVR

Теперь в окне кода набираем любой необходимый код (соблюдая синтаксис языка), в зависимости от решаемой задачи:

код на Си для AVR

Компилируемкнопка -компилирование проектапроект, для выявления всевозможных ошибок и предупреждений компилятора. В процессе компиляции создается исходный файл ассемблера Prog1.asm, который можно открыв редактором просмотреть и ввести необходимые изменения. На стадии компиляции файлы COF, ROM, HEX, EEP не создаются.

Выполняем окончательную сборку проекта значок - сборка проекта в CodeVisionAVR, при этом создаются готовые к употреблению файлы COF, ROM, HEX, EEP.

Если создается проект с помощью мастера кода (CodeWizardAVR), после необходимых установок на вкладках (USART, ADC, работа с термодатчиком и т.д.), то в меню file мастера выбираем Generate, Save and Exit, и выполняем необходимые сохранения! Посмотреть предварительно какой код создаст мастер, можно выбрав в меню file командную строчку Program Preview!

CodeWizardAVR - generate, save end exit

Си программа CodeVisionAVR начинается с директивы #include - включает в текст программы содержимое указанного файла (заголовочный файл), содержащий прототипы библиотечных функций:

#include <mega8.h>

Заголовочный файл header на atmega8, содержащий символьные мнемоники всей архитектуры микроконтроллера – (адреса портов, счетчиков, аналого-цифрового преобразователя, приемопередатчика и т.д.):

sfrb UBRRL=9;

sfrb UCSRB=0xa;

sfrb UCSRA=0xb;

sfrb UDR=0xc;

sfrb SPCR=0xd;

sfrb SPSR=0xe;

sfrb SPDR=0xf;

sfrb PIND=0x10;

sfrb DDRD=0x11;

sfrb PORTD=0x12;

. . . . .

Векторы прерываний:

#define EXT_INT0 2

#define EXT_INT1 3

#define TIM2_COMP 4

#define TIM2_OVF 5

#define TIM1_CAPT 6

#define TIM1_COMPA 7

#define TIM1_COMPB 8

#define TIM1_OVF 9

#define TIM0_OVF 10

. . . . .

 

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

#include <mega8.h>

#include <LCD.h>

#include <ds18b20.h>

#include <delay.h>

#include <stdio.h>

#include <1wire.h>

 

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

#define time 50

#define uart_RxD 2

#define lightcontrol_off PORTB.2=0

#define lightcontrol_on PORTB.2=1

#define protection PORTD=0x2f;PORTC=0x20;\ символ переноса

PORTB=0xed;

 

Список некоторых заголовочных файлов, использующихся в среде CodeVisionAVR:

assert.h - диагностика программ

ctype.h - преобразование и проверка символов

float.h - работа с вещественными данными

limits.h - предельные значения целочисленных данных

math.h - математические вычисления

setjump.h - возможности нелокальных переходов

stdarg.h - поддержка переменного числа параметров

stddef.h - дополнительные определения

stdio.h - средства ввода-вывода

stdlib.h - функции общего назначения (работа с памятью)

string.h - работа со строками символов

 

Программа начинается с функции main – основная функция, с которой начинается выполнение всей программой процедуры, состоящей из множества функций.

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

void main(void)

{

/* тело функции. Последовательность операторов */

}

 

Из основной функции main можно вызывать другие функции. Данные функции не принимают аргументы и не возвращают результат:

void structs(void)

{

/* список операторов */

/* вызов других функций */

}

void main(void)

{

/* список операторов */

structs(); /* функция не принимает аргументы и не возвращает результат */

/* список операторов */

}

 

Функция, которая имеет список аргументов и возвращает результат:

Int structs(int a,int b)

{

int c;

c=a/(100*2)-b*10; /* математическое вычисление */

return c; /* значение результата присваивается функции */

}

int main()

{

int a=100, b=50;

int result;

result=structs(a,b);

. . . . .

}

 

Небольшой код «светодиодной моргалки» как пример записи программы в среде CodeVisionAVR C Compiler:

 

#include <mega8.h>

#include <delay.h>

#define dl 300 /* директива заменит dl на значение 300 */

 

void main(void)

{

DDRD=0x01; /* разряд PD0 на вывод */

while(1) /* бесконечный цикл */

{

PORTD.0=1; /* разряд PD0 в лог.1 */

Delay_ms(dl); /* задерживаем на значение dl, мс */

PORTD.0=0; /* разряд PD0 в лог.0 */

Delay_ms(dl);

};

}

мигалка - симуляция в Proteus

Автор: skiff, Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра.

 

Добавить комментарий


Защитный код
Обновить