Лабораторная работа № 2

“Дискретные порты ввода-вывода”

Вариант № 2

Работу выполнил

Студент гр. 3100

Голубцов Евгений

2010

Задание

Разработать и реализовать драйверы светодиодного индикатора и DIP-переключателя контроллера SDK-1.1. Написать тестовую программу с использованием разработанных драйверов по алгоритму, соответствующему варианту задания.

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

Данная лабораторная работа посвящена изучению дискретных портов ввода-вывода встраиваемых микроконтроллеров. Дискретные (цифровые) порты используются для ввода-вывода дискретных значений логического «0» или «1». Исследование портов будет проводиться на примере светодиодного индикатора (линейки из 8 светодиодов) и DIP-переключателя, входящих в состав контроллера SDK-1.1.

Ниже на рисунке показано расположение линейки светодиодов и DIP-переключателя в стенде SDK-1.1.

Для удобства, двоичный (шестнадцатеричный) код, задаваемый DIP-переключателем, выставляется следующим образом: первый переключатель соответствует младшему (0-му) разряду двоичного кода; восьмой переключатель соответствует старшему (7-му) разряду. Переключатель, установленный в положение «ON», следует считать единичным разрядом, а в противоположное положение – нулевым.

Требования к выполнению работы

Все программы должны быть написаны на языке Си. Разрабатываемые драйверы устройств должны быть выполнены в виде отдельных функций (функции установки состояния светодиодов и функции чтения состояния DIP-переключателя). В тестовой программе для осуществления анимации запрещается использовать «покадровое» формирование картинки. Для реализации алгоритма анимации должны быть использованы логические, арифметические и бинарные операции, а также операции сдвигов.

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

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

Вариант № 2

В случае установки на DIP-переключателе кода 0x22 (шестнадцатеричное значение) на светодиодный индикатор должна выводиться первая анимация, в случае установки кода 0xDD (шестнадцатеричное значение) – вторая анимация. Во всех остальных случаях светодиодный индикатор отражает инвертированное значение, выставленное на DIP-переключателе.

Блок-схема программы.

Текст программы с комментариями.

#include "aduc812.h" // Подключаем заголовочные файлы

#include "led.h"

#define MAXBASE 8; // Создаем символическое имя

// Задержка на заданное количество мс

void delay ( unsigned long ms )

{

unsigned long i, j;

for( j = 0; j < ms; j++ )

{

for( i = 0; i < 50; i++ );

}

}

//readDIP

//Чтение из нужного регистра ПЛИС ALTERA MAX3064(3128)

//

//Вход: regnum - адрес (номер) регистра

//Выход: val – прочитанное значение

//Результат: прочитанное из регистра значение

//Описание: Чтение из порта ПЛИС ALTERA MAX3064(3128)

// путем переключения адресуемой страницы памяти на страницу, где

// расположены (куда отображаются) порты ввода-вывода ПЛИС.

unsigned char readDIP()

{

unsigned char oldDPP = DPP;

unsigned char val = 0;

unsigned char xdata *regnum = 0x080002; // 0x080002 - адрес регистра данных параллельного порта (разряды 0..7)

DPP = MAXBASE; // Переключение страничного регистра DPP

val = *regnum ; // regnum - адрес регистра ПЛИС

DPP = oldDPP;

return ~val;

}

///////////////////////////////////////////////////////////////////////////////////////////////////////

//Функция вывода анимации, если на DIP-переключателях стоит значение 0х22 или 0хDD //

//или вывод инвертированного значения, выставленного на DIP-переключателях //

////////////////////////////////////////////////////////////////////////////////////////////////////

void AnimationFunc()

{

unsigned char u; // Переменная для хранения значений регистра DPP

unsigned char r1=0x22; // Адрес для первой анимации

unsigned char r2=0xdd; // Адрес для второй анимации

int i=0;

unsigned char leftPart=0x00; // Левая часть светодиодов

unsigned char rightPart=0x00; // Правая часть светодиодов

unsigned char state = leftPart | rightPart; // Делим светодиоды на левую и правую часть

if( (u = readDIP()) == r1) // Получение значения в регистре dpp и сравниваем с 0x22

{

leftPart=0x80; // Адрес первого светодиода в левой части

rightPart=0x08; // Адрес первого светодиода в правой части

for ( i = 0; i<10; i++ )

{

if (i<3)

{

state = leftPart | rightPart;

leds( state ); delay(500); // Устанавливаем положения для светодиодов и задержку

leftPart = leftPart >> 1; // Сдвигаем светодиод в левой части вправо на 1 разряд

rightPart = rightPart >> 1; // Сдвигаем светодиод в правой части вправо на 1 разряд

}

else

if (i<6)

{

state = leftPart | rightPart;

leds( state ); delay(500); // Устанавливаем положения для светодиодов и задержку

leftPart = leftPart << 1; // Сдвигаем светодиод в левой части влево на 1 разряд

rightPart = rightPart << 1; // Сдвигаем светодиод в левой части влево на 1 разряд

}

else

{

state = leftPart | rightPart;

leds( state ); delay(500);

leftPart = leftPart >> 1;

rightPart = rightPart >> 1;

}

}

}

else

{

if ( ( u = readDIP()) == r2) // Получение значения в регистре dpp и сравниваем с 0xdd

{

state=(0x01); // Устанавливаем положение светодиода в 0х01

for ( i = 0; i<10; i++ )

{

if (i<7)

{

leds( state ); delay(500);

state = state << 1; // Сдвигаем светодиод влево на 1 разряд

}

else

{

leds( state ); delay(500);

state = state >> 1; // Сдвигаем светодиод вправо на 1 разряд

}

}

}

else

{

leds( ~u ); // Если на DIP-переключателях другой адрес, получаем его инверсию и

delay(500); // выводим

}

}

}

void main( void )

{

while( 1 )

{

AnimationFunc(); // Вызов процедуры вывода анимации

}

}

Соседние файлы в папке дискретные порта ввода-вывода