Разработка логической схемы реализации линии связи

 

К общей шине (ОШ) подключены несколько абонентов, каждый из которых функционирует автономно в соответствии с управляющей информацией, полученной от специального устройства - арбитра общей шины. Эта шина включает 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

выбираем ATmega

169

 

Жмём 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

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

 

Приложение

/*

Подключение заголовочного файла 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); // Посылаем Арбитру, что Абонент ЗАНЯТ

}

}

}

}

}

Похожые стьтьи по экономике

Авиационные приборы
Акселерометр - это прибор для измерения ускорения(перегрузок), возникающего на летательных аппаратах, ракетах, самолетах и других движущихся объектах, при использовании машин, двигателей и т.д. Аксел ...

Анализ электромагнитного поля в прямоугольном волноводе
В полой трубе прямоугольного сечения (рис. 1) с идеально проводящими стенками создано монохроматическое электромагнитное поле. Труба заполнена однородной изотропной средой без потерь, а ...

USB осциллограф на микроконтроллере ATTINY45
На сегодняшний день огромное развитие получили электронные устройства. Человек использует их в своей деятельности почти во всех сферах(ПЕРЕЧИРСЛИТЬ). Большая часть таких устройств выполн ...

Разделы

© 2018 - www.frontinformatics.ru