Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Создание проекта в AVR Studio

Содержание

Задание

Описание работы порта А

Описание работы порта B

Создание проекта в AVR Studio

Список использованной литературы

Приложение


Задание

 

К общей шине (ОШ) подключены несколько абонентов, каждый из которых функционирует автономно в соответствии с управляющей информацией, полученной от специального устройства - арбитра общей шины. Эта шина включает 3 линии связи: одну информационную и две синхронизирующие. Передача информации ведется в последовательном коде. При этом синхроимпульсы С1 отмечают начало каждого байта, а С2 синхронизируют передачу отдельных битов. Основная тактовая частота 1 МГЦ. Длительность синхроимпульсов 0,25 мкс.

При необходимости связи арбитр вырабатывает общий для всех абонентов сигнал ВНИМАНИЕ и затем - АДРЕС нужного абонента. Этот абонент после идентификации своего адреса выдает в шину сигнал ГОТОВ либо ЗАНЯТ в зависимости от своего состояния. Получив сигнал готовности, арбитр сразу же формирует непрерывную многобайтную посылку - информационное сообщение (ИС), которое замыкается сигналом КОНЕЦ ПЕРЕДАЧИ. Приняв эту посылку, абонент отвечает сигналом КОНЕЦ ПРИЕМА при отсутствии ошибок передачи, либо сигналом ПОВТОРИТЬ ПЕРЕДАЧУ, если обнаружена ошибка. В последнем случае арбитр повторяет весь цикл связи заново. Информационное сообщение имеет символьный характер. Каждый символ занимает 1 байт (8 разрядов). Алфавит сообщений содержит всего 200 символов. Остающиеся 56 символов могут быть использованы в качестве сигналов связи: ГОТОВ, ВНИМАНИЕ и др.

Для реализации связи каждому абоненту придается интерфейсный модуль-контроллер связи. Сигналы ГОТОВ и ПОВТОРИТЬ-ПЕРЕДАЧУ вырабатываются контроллером по получении от своего абонента сигналов конца работы (КР) и ошибки передачи (ОП) соответственно.

 

ВНИМАНИЕ 217 11011001
АДРЕС 57 00111001
ГОТОВ 237 11101101
ЗАНЯТ 253 11111101
КОНЕЦ_ПЕРЕДАЧИ 114 01110000
КОНЕЦ_ПРИЕМА 174 10101110
ПОВТОРИТЬ_ПЕРЕДАЧУ 154 10100100

 

Схема микроконтроллера.

Для программирования необходимой логики работы мы будем использовать 3 из 8 выводов порта А и все 8 выводов порта B

Описание работы порта А

 

На вывод 0 поступает сигнал синхронизации С1

На вывод 1 поступает сигнал синхронизации С2

Вывод 2 используется для посылки и приёма Арбитру управляющих сигналов ("Внимание", "Готов" ит.д.), а также для приёма информационного сообщения.

Выводы 3-7 не используются и поэтому не показаны на схеме

Описание работы порта B

 

8 выводов порта B используются для параллельной передачи и приёма Абоненту управляющих сигналов ("Ошибка передачи", "Конец работы" ит.д.), а также для пересылки информационного сообщения, которое идёт от Арбитра

 

порт линия связь схема

 

В качестве программируемого микроконтроллера возьмём ATmega 169. Выбор обусловлен тем, что данное устройство поддерживает необходимые для выполнения курсового проекта характеристики, хотя и является избыточным.

Работу программы будем проверять в эмуляторе AVR Studio 4.13.528

Компилировать программу будем в WinAVR 20071221

AVR Studio - интегрированная среда проектирования программ для микроконтроллеров, которую можно свободно скачать с сайта производителя www.atmel.com <http://www.atmel.com>

WinAVR - программный пакет, содержащий в себе интересующий нас компилятор GNU GCC для C. WinAVR можно свободно скачать с сайта разработчиков <http://sourceforge.net/projects/winavr/>

Для разбора задания установите сначала WinAVR, а потом AVR Studio. Порядок установки важен для того, чтобы AVR Studio установил в настройках проекта в качестве компилятора компилятор GNU GCC, входящий в состав WinAVR. Обе программы установите с параметрами по умолчанию.

Создание проекта в AVR Studio

 

Для создания проекта в AVR Studio необходимо зайти в меню Project - > Project Wizard - > New Project

В окне Project type выбираем AVR GCC потому что будем писать программу на языке C

В окне Project name вписываем произвольно название проекта, допустим mk

В окне Initial file вписываем main. c. Это будет главный файл проекта, где будет находиться функция main.

Жмём Next

В окне Debug platform выбираем AVR Simulator. В окне Device выбираем ATmega169

Жмём Finish

После создания проекта в AVR Studio необходимо зайти в меню Project - > Configuration Options - > General и выставить значение Optimization = - O0. Это отключит оптимизацию кода, которая нам не нужна при отладке программы.

Окно main. c содержит исходный текст программы (предварительно скопируйте код в это окно).

В окне I / O View можно наблюдать, а также изменять состояние портов А и B.

Например сигнал С1 эмулируется в данной работе установкой в единицу PINA bit 0., а сигнал С2 эмулируется установкой в единицу PINA bit 1.

Значение PINA bit 2 эмулирует значения, которые нам приходят по информационной линии

В окне Watch можно следить за значениями переменных.


Список использованной литературы

 

1.  Голубцов М.С., Кириченкова А.В. Микроконтроллеры AVR: от простого к сложному. - М.: "Солон-Пресс", 2004.

2. Шпак Ю.А. Программирование на языке C для AVR и PIC микроконтроллеров. - М.: "МК-Пресс", 2006.

.   Фрунзе А.В. Микроконтроллеры? Это же просто! - K.: "Додэка XXI", 2007.

.   Белов А.В. Самоучитель разработчика устройств на микроконтроллерах AVR. - М.: "Наука и техника", 2008.

.   Хартов В.Я. Микроконтроллеры AVR. Практикум для начинающих. - М.: МГТУ им. Н.Э. Баумана, 2007.

.   Джон Мортон Микроконтроллеры AVR. Вводный курс AVR: An Introductory Course. - К.: "Додэка XXI", 2006.

.   Евстифеев А.В. Микроконтроллеры AVR семейства Tiny. Руководство пользователя. - К.: Додэка XXI, 2007


Приложение

 

/*

Подключение заголовочного файла io. h, который в свою очередь подключит iom169. h. h - заголовочный файл, который ставит в соответствие константам PORTA и PORTB реальные адреса выводов конкретного контроллера (в нашем случае ATmega169)

Таким образом io. h позволяет работать с портами ввода-вывода

*/

#include <avr/io. h>

// Подключение заголовочного файла, который позволяет объявлять булевские переменные

#include <stdbool. h>

// Определение пользовательского типа данных byteunsigned char byte;

// Константы, определённые для обращения к выводам порта А

#define C1 (PINA & 0x01) /* 0-вой вывод порта А, на который приходит сигнал С1 */

#define C2 (PINA & 0x02) /* 1-вой вывод порта А, на который приходит сигнал С2 */

#define DATAIN ((PINA & 0x04) >> 2) /* 2-вой вывод порта А, на который приходит информация. Чтение информации из порта */

#define DATAOUT (x) PORTA = (PORTA & ~ (0x04)) | (x << 2) /* 2-вой вывод порта А, на который приходит информация. Ввод информации в порт */

// Символы сигналов связи варианта задания на курсовой проект #4

#define ATTENTION 217 // Внимание

#define ADDRESS 57 // Адрес

#define READY 237 // Готов

#define BUSY 253 // Занят

#define END_OF_TRANSFER_SEQUENCE 114 // Конец передачи

#define END_OF_RECEIVE 174 // Конец приёма

#define REPEAT_TRANSFER 154 // Повторить передачу

// Символы сигналов связи от Абонента

#define END_OF_WORK 1 // Конец работы

#define TRANSFER_ERROR 2 // Ошибка передачи

// Глобальные переменные

byte frameFromArbiter = 0;abonentStateReceived = false;frameCameFromArbiter = false;AddressCameFromArbiter = false;frameToAbonentWasSent = false;requestToAbonentWasSent = false;stateOfAbonentWasSentToArbiter = false;DataMessageRefered = false;

int abonentState = 0;

// Получаем побитово байт от Арбитра

void ReceiveFrameFromArbiter ()

{int C2Count = 0;bool C1Came = false;bool C2Out = true;

if (C1) // Если пришёл сигнал С1,{Came = true; // запоминаем что сигнал С1 приходил

}(C1Came) // Если сигнал С1 приходил

{(C2 && C2Out) // Если сигнал С2 пришёл,

{= (frameFromArbiter & ~ (1 << C2Count)) | (DATAIN << C2Count); // считываем очередной бит с информационной линии

/*

(1 << C2Count) даст нам байт с единицой, установленной на том бите, который мы должны установить

~ (1 << C2Count) инвертирование даст нам байт с нулём, установленным на том бите, который мы должны установить

(frameFromArbiter & ~ (1 << C2Count)) даст нам исходный frameFromArbiter с нулём, установленным на том бите, который мы должны установить<< C2Count) даст нам бит со значением пришедшим по информационной линии, который установлен в байте на том бите, который мы должны установить

Итоговое поразрядное ИЛИ даст нам исходный frameFromArbiter со значением пришедшим по информационной линии, которое установится в frameFromArbiter на номере бита, равном номеру сигнала С2

*/Count++; // Считаем номер пришёдшего сигнала С2Out = false; // Запоминаем, что С2 пришёл, но ещё не уходил

}(C2Count == 8) // Если пришло 8 сигналов С2, значит мы приняли целиком байт

{Count = 0; // Обнуляем количество сигналов С2Came = false; // Запоминаем что пришёдший после С1 байт уже обработан, ждём следующий С1

C2Out = true;= true; // Запоминаем что байт пришёл

}(! C2) { // Если сигнал С2 ушёлOut = true; // Запоминаем, что сигнал С2 ушёл

}

}

}

// Ждём поступления от Арбитра адреса микроконтроллераWaitAddressFromArbiter ()

{= 0x00; // Указываем микроконтроллеру настроить все выводы на приём информации

bool attentionCame = false;(); // Получить байт от Арбитра(frameCameFromArbiter) // Если байт от Арбитра пришёл

{(attentionCame) // Если сигнал Внимание уже приходил

{(frameFromArbiter == ADDRESS) // И пришедший байт равен адресу микроконтроллера

{= true; // Запоминаем, что адрес пришёл

}= false;

}(frameFromArbiter == ATTENTION) // Если пришёл байт равный сигналу Внимание

{= true; // Запоминаем, что приходил сигнал Внимание

}= false; // Записываем, что мы уже обработали пришедший байт

}

}

// Посылаем параллельно байт АбонентуSendFrameToAbonent (byte sendFrame)

{bool C1Came = false;(C1) // Если пришёл сигнал С1,{Came = true; // запоминаем что сигнал С1 приходил

}(C1Came) // Если сигнал С1 приходил

{= sendFrame; // Выдаём на выводы порта B байт

}(! C1 && C1Came) // Если сигнал С1 ушёл и приходил

{= true; // Запоминаем что байт был отосланCame = false;

}

}

// Посылаем Абоненту запрос о его состоянииSendToAbonentRequestAboutAbonentState ()

{= 0xFF; // Указываем микроконтроллеру настроить все выводы порта B на вывод информации(READY); // Посылаем байт ГОТОВ Абоненту(frameToAbonentWasSent) // Если байт был послан

{= true; // Запоминаем, что запрос Абоненту был послан

}

}

// Получаем от Абонента его состояниеReceiveFromAbonentAbonentState ()

{= 0x00; // Указываем микроконтроллеру настроить все выводы порта B на приём информации

static bool C1Came = false;(C1) // Если пришёл сигнал С1,{Came = true; // запоминаем что сигнал С1 приходил

}(C1Came) // Если сигнал С1 приходил

{= PINA; // Выдаём на выводы порта B байт

}(! C1 && C1Came) // Если сигнал С1 ушёл и приходил

{= true; // Запоминаем что получили состояние АбонентаCame = false;

}

}

// Посылаем Арбитру состояние Абонента

void SendToArbiterAbonentState (byte frame)

{= 0x04;int C2Count = 0;bool C1Came = false;bool C2Out = true;(C1) // Если пришёл сигнал С1,{Came = true; // запоминаем что сигнал С1 приходил

}(C1Came) // Если сигнал С1 приходил

{(C2 && C2Out) // Если сигнал С2 пришёл,

{((frame & (1 << C2Count)) >> C2Count); // Записываем очередной бит на информационную линиюCount++; // Считаем номер пришёдшего сигнала С2Out = false; // Запоминаем, что С2 пришёл, но ещё не уходил

}(C2Count == 8)

{Count = 0; // Обнуляем количество сигналов С2Came = false; // Запоминаем что пришёдший после С1 байт уже обработан, ждём следующий С1Out = true;= true; // Запоминаем, что состояние Абонента было отослано Арбитру

}(! C2) { // Если сигнал С2 ушёлOut = true; // Запоминаем, что сигнал С2 ушёл

}

}

}

// Получаем информационное сообщение от Арбитра и пересылаем АбонентуReceiveDataMessageFromArbiterAndReferToAbonent ()

{= 0x00; // Указываем микроконтроллеру настроить все выводы на приём информации(); // Получить байт от Арбитра(frameCameFromArbiter) // Если байт от АРбитра пришёл

{(frameFromArbiter); // Посылаем байт Абоненту= false; // Запоминаем, что мы обработали байт, пришедший от Арбитра(frameFromArbiter == END_OF_TRANSFER_SEQUENCE) // Если пришёдший байт совпадает с символом КОНЕЦ ПЕРЕДАЧИ

{= true; // Запоминаем что информационное сообщение переслали

}

}

}main (void)

{(1) // Запускаем бесконечный цикл

{(! AddressCameFromArbiter) // Если адрес МК ещё не пришёл от Арбитра,

{(); // ждём

}(AddressCameFromArbiter) // Если от Арбитра пришёл адрес МК

{(); // посылаем Абоненту запрос о его состоянии(requestToAbonentWasSent) // Если запрос о состоянии Абонента был послан

{(); // получаем ответ

}(abonentStateReceived) // Если получили состояние Абонента,

{(abonentState == END_OF_WORK) // и состояние равно КОНЕЦ РАБОТЫ,

{(READY); // посылаем Арбитру сигнал ГОТОВ(stateOfAbonentWasSentToArbiter) // Если состояние Абонента отослалось Арбитру

{(); // Начинаем принимать информационное сообщение от Арбитра и пересылать его Абоненту(DataMessageRefered) // Если информационное сообщение было отослано

{(); // Посылаем Абоненту запрос о его состоянии(requestToAbonentWasSent) // Если запрос о состоянии Абонента был послан,

{(); // ждём ответ

}(abonentStateReceived) // Если получили состояние Абонента,

{(abonentState == TRANSFER_ERROR) // Если состояние Абонента равно ОШИБКА ПЕРЕДАЧИ

{SendToArbiterAbonentState (REPEAT_TRANSFER); // Посылаем Арбитру сигнал ПОВТОРИТЬ ПЕРЕДАЧУ

}// Если ошибки не произошло

{

SendToArbiterAbonentState (END_OF_RECEIVE); // Посылаем Арбитру сигнал КОНЕЦ ПРИЁМА

}

}

}

}

}// Если состояние не равно КОНЕЦ РАБОТЫ

{(BUSY); // Посылаем Арбитру, что Абонент ЗАНЯТ

}

}

}

}

}

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...