85974

Разработка и программирование устройств построенных на базе 8-битных микроконтроллеров Atmega

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

Информатика, кибернетика и программирование

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

Русский

2015-04-01

756.5 KB

4 чел.

PAGE  2

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ

ДОНЕЦКИЙ НАЦИОНАЛЬНЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

Методические указания

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

по курсу “Микропроцессорная техника”

Разработка и программирование устройств построенных на базе 8-битных микроконтроллеров Atmega

 

Для студентов специальности 7.090601

“Электрические станции”

Донецк, ДонНТУ-2012


УДК  537.3.31

Методические указания к выполнению лабораторных работ по курсу “Микропроцессорная техника”: Разработка и программирование устройств, построенных на базе 8-битных микроконтроллеров Atmega.

Для студентов специальности 7.090601 “Электрические станции”

Составитель:  Антоненко Г.В. - Донецк: ДонНТУ, 2012. – 43с .

Содержатся рекомендации по проведению лабораторных работ по  курсу ”Микропроцессорная техника”. Рассматриваются вопросы по проектированию, изготовлению, программированию и тестированию устройств релейной защиты и автоматики, построенных с использованием  8-битных микроконтроллеров Atmega фирмы Atmel.

Составитель                 асс. Антоненко Г.В.

Рецензент                     доц. Заболотный И.П.

Ответственный за выпуск    д.т.н., проф. Сивокобыленко В.Ф.

розглянуто

Протокол засідання

кафедри Електричні станції”

№___від ___________ 2012р.

Завідувач кафедри

д.т.н., професор

В.Ф.Сивокобиленко

«____» «___________» 2012р.

УЗГОДЖЕНО

Голова навчально-методичної комісії з підготовки фахівців кваліфікаційного рівня спеціаліста і магістра

спеціальності «Електричні станції», «Нетрадиційні та відновлені джерела енергії»

В.Ф.Сивокобиленко ____________

укладач

ст. викл., Г.В.Антоненко _____________



Содержание


Введение

В дисциплине "Микропроцессорная техника" прежде всего студенты получают подготовку, необходимую для понимания принципов устройства и работы микропроцессоров. Для этого, после изучения структуры микропроцессора и организации его памяти, изучается программирование его на самом низком уровне – на языке Ассемблера, с получением машинных кодов вручную. Пошаговое выполнение полученной программы в отладчике, позволяет в деталях проследить работу элементов микропроцессора. Такой подход является наиболее эффективным для понимания всего пути от написания программы на языке высокого уровня, до исполнения программы и получения результата.

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

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

Любое микропроцессорное устройство, реализующее алгоритмы работы релейных защит и автоматики, должно иметь возможность управления его работой при помощи иерархического меню и модуля редактирования параметров уставок. Вот почему в данном курсе очень большое внимание уделяется программированию, что потребовало отдельной лабораторной работы по разработке небольшой программной системы, реализующей меню и обеспечивающей редактирование 3-4 параметров.

Поднимаясь на одну ступень в иерархии управляющих систем, необходимо решить задачу объединения микроконтроллеров в управляющую сеть и обеспечить ее связь с персональными компьютерами и глобальной сетью Internet. По этой причине, последнюю лабораторную работу, посвященную вопросу связи микроконтроллера с ПК типа IBM PC, можно считать самой интересной.

Правила работы за компьютером

Студентам запрещается изменять расположение значков на рабочем столе, фон рабочего стола и другие параметры настройки компьютера. Запрещается инсталлировать и запускать на компьютере принесенные программы, выходить в Internet, изменять содержимое файлов и папок, кроме своей рабочей папки. В случае нарушения студент удаляется с занятия. При повторном нарушении – отстраняется от занятий. В этом случае продолжить работу в компьютерных аудиториях студент может только при наличии письменного разрешения деканата.

В аудиториях 4-го корпуса студенты работают на диске С:, в папке Students/Название_группы/Фамилия_студента. В аудитории 8.305 работа разрешена на диске Е:, в папке Название_группы/Фамилия_студента.

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

Правила выполнения лабораторных работ

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

Справа вверху пишется фамилия и группа студента. На следующей строке, посередине листа - Лабораторная работа №   по курсу “МП техника”. Ниже – название лабораторной работы.

Отчет должен содержать:

  •  цель работы;
  •  задание;
  •  выбор структур данных;
  •  текст алгоритма и блок-схему;
  •  текст программы;
  •  план отладки с результатами, ожидаемыми в контрольных точках;
  •  после выполнения работы на компьютере к отчету желательно приложить распечатку программы, результатов или копию экрана;
  •  записать выводы.

Без подготовки студент к выполнению лабораторной работы не допускается.

Работу программы студент демонстрирует преподавателю.

Отдельно оцениваются:

  •  схемы структур данных и алгоритм;
  •  текст программы;
  •  результаты пошагового выполнения вручную и план отладки;
  •  модификация программы по требованию преподавателя и демонстрация ее работы;
  •  защита отчета (написание небольшого фрагмента или ответ на вопрос с примером).

По работе выставляется усредненная оценка.

Работа, своевременно выполненная на занятии, при полностью оформленном отчете зачитывается без защиты.

При трех и более незащищенных работах студент не допускается к выполнению лабораторных работ. Защита отчетов производится на лабораторных работах и на консультациях.


Расчетная работа №1 – Системы счисления. Работа с целыми числами, как двоичными

Как известно, вся информация в ЭВМ представляется в виде чисел.

Хранение и выполнение операций с числами производится в двоичном виде.

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

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

Десятичная система счисления

В числе 2468 каждая цифра имеет свой вес. Умножив значение цифры на ее вес, мы получим значение числа:

2*1000 + 4*100 + 6*10 + 8*1 = 246810

Или используя степени числа 10:

2*103 + 4*102 + 6*101 + 8*100 = 246810

Число десять является основанием системы счисления, отсюда и название - десятичная. Вес каждого следующего разряда можно получить, умножив вес предыдущего на основание системы счисления.

Двоичная система счисления

Двоичное представление чисел основано на степенях числа 2:

100110112 = 1*27 + 0*26 + 0*25 + 1*24 + 1*23 + 0*22 + 1*21 + 1*20 = 15510 

Или достаточно сложить веса ненулевых цифр:

128 + 0 + 0 + 16 + 8 + 0 + 2 + 1 = 15510

Удобно под каждой цифрой записывать ее вес следующим образом:

1  0  0  1  1  0  1  1    =  15510

128 64 32 16    8   4    2   1

Первый способ перевода десятичного значения в двоичное:

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

Второй способ. Заполняем таблицу:

Операция

Результат

Остаток

155/2

77

1

77/2

38

1

38/2

19

0

19/2

9

1

9/2

4

1

4/2

2

0

2/2

1

0

1/2

0

1

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

Шестнадцатеричная система счисления

Для более компактной записи двоичных чисел применяется шестнадцатеричная система счисления. В шестнадцатеричной системе цифр должно быть 16. Недостающие цифры представлены буквами. Поэтому счет ведется следующим образом: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11, … , 19, 1A, 1B, 1C, 1D, 1E, 1F, 20, 21 и т.д.

Перевод в десятичную систему осуществляется аналогично:

FD4 = 15*162 + 13*161 + 4*160 =  405210

Или с помощью весов цифр:

15*256 + 13*16 + 4*1  =  405210

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

Значение цифры

Десятичное

Шестнадцатеричное

Двоичное

0

0

0000

1

1

0001

2

2

0010

3

3

0011

4

4

0100

5

5

0101

6

6

0110

7

7

0111

8

8

1000

9

9

1001

10

A

1010

11

B

1011

12

C

1100

13

D

1101

14

E

1110

15

F

1111

Например:

D4CF = 1101 0100 1100 1111

Преобразование десятичных чисел в шестнадцатеричные:

В качестве примера выполним обратное преобразование числа 691 в шестнадцатеричное представление.

Первый способ:

  1.  Под позициями будущих шестнадцатеричных цифр числа записываем их веса: 1, 16, 256, 4096, 65536, и т.д. Вес каждого следующего разряда получается путем умножения предыдущего веса на 16 (основание системы). Вес разряда, который превышает значение числа, уже не записываем.

         =  405210

256  16   1

  1.  Делим значение числа на вес цифры (слева на право):

4052 / 256 = 15     (это F)

  1.  Целую часть результата записываем как значение разряда (0 – F) над его весом           F     

256  16   1

  1.  Вычитаем из числа то значение, которое мы уже учли:

4052 – 256 * 15 = 212

  1.  Повторяем действия, начиная с пункта 2, пока не закончатся разряды:

212 / 16 = 13         (это D)

 F  D     

256  16   1

212 – 16 * 13 = 4  (4 есть 4…)

Получаем:                       F  D  4    =  405210

256  16   1

Второй способ. Заполняем таблицу:

Операция

Результат

Остаток

4052 / 256

15

212

212 / 16

13

4

4 / 1

4

0

Что из таблицы следует выписывать и в каком порядке, определите сами.

Выполнение операции сложения в различных системах счисления

В десятичной системе:

1  1  - Перенос

4 7 9     9 + 4 = 3 + 10  (Перенос 1 в старший разряд)

3 8 4         1 + 7 + 8 = 6 + 10  (Перенос 1)

8 6 3        1 + 4 + 3 = 8

В двоичной системе:

    Переполнение!

1  1  1  1      1  1  1       - Перенос

  1 0 1 1  0 1 0 1  =  18110       1 + 1 = 0 + 2  (Перенос 1 в старший разряд)

  0 1 1 1  0 0 1 1  =  11510       1 + 0 + 1 = 0 + 2  (Перенос 1)

  0 0 1 0  1 0 0 0  =    4010              и так далее…

Задумайтесь над тем, почему получилось  181 + 115 = 296 – 256(?) = 40

Числа со знаком

Существует два способа представления чисел со знаком: путем выделения знакового разряда и в дополнительном коде.

При работе с восьмиразрядными целыми числами выделим старший (седьмой) разряд для хранения знака числа. Тогда, если 0000 0001 = 1, то 1000 0001 = -1. Такой подход не применяется по двум причинам:

  1.  Два представления 0. Если 0000 0000 = +0, тогда 1000 0000 = -0.
  2.  Усложнение логики процессора, так при сложении 1 и –1 должен быть получен ноль:

  0 0 0 0  0 0 0 1  =   1

  1 0 0 0  0 0 0 1  =  -1

  1 0 0 0  0 0 1 0  =  -2

  •  при обычной логике построения сумматора получается (-2).

Чтобы исключить эти недостатки, было разработано представление чисел в дополнительном коде.

Представление чисел в дополнительном коде основано на следующих правилах:

  1.  Первое правило: Для изменения знака числа необходимо проинвертировать значения разрядов числа и прибавить 1.

Например:  0000 0101  =  5

Изменим знак:

Инвертируем:    1111 1010

Прибавляем 1:      1

   1111 1011  = -5

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

Свойства чисел в дополнительном коде:

  1.  Единственное представление 0:

Например:  0000 0000  =  0

Изменим знак:

Инвертируем:    1111 1111

Прибавляем 1:      1

   0000 0000  =  0     -  Выполняется! (Перенос игнорируем)

  1.  Обратимость:

Например:  1111 1011  = -5

Инвертируем:    0000 0100

Прибавляем 1:      1

   0000 0101  =  5      -  Выполняется!

  1.  Правильный результат операции сложения:

Необходимо, чтобы при сложении 5 и (-5) получался 0. Проверка:

0000 0101  =  5

1111 1011  = -5

0000 0000  =  0

Выполняется, однако, необходимо игнорировать возникающий перенос в несуществующий 8-й разряд и не считать такую ситуацию переполнением!

Еще примеры:

1111 1011  = -5  1111 1011  = -5  1111 1011  = -5

0000 0100  =  4  0000 0011  =  3  0000 0110  =  6

1111 1111  = -1  1111 1110  = -2  0000 0001  =  1

Если признаком того, что число отрицательное, является установленный старший разряд, тогда  0111 1111 =  12710 = (2(8-1)-1) является наибольшим положительным значением числа со знаком, а 1000 0000 = -128 = 2(8-1) – наименьшим значением при 8-разрядном представлении чисел в дополнительном коде.

Циклическое свойство представления целых чисел

Что же произойдет, если к наибольшему допустимому значению мы прибавим еще 1. Для изучения этого вопроса напишем программу:

char c=127;

c=c+1;

cout<<(int)c<<endl;

Тип char - это сокращение от character (читается ”кэрикте”) – буква. Этот тип представляет в языке С++ знаковые числа в дополнительном коде и как раз нам подходит. В последнем операторе перед выводом выполняется преобразование к типу (int), иначе переменная с, имеющая символьный тип, будет выведена как символ (буква).

После исполнения программы мы получим значение (–128), т.е. наименьшее возможное значение. Вместо увеличения значения мы неожиданно получили значительное уменьшение (на 256). При обычных вычислениях такая ситуация считается аварийной и называется “переполнение”. Знание природы двоичных чисел позволяет нам легко объяснить такое поведение:

0111 1111  =  +127

              1  

1000 0000   =  -128

В свою очередь при вычитании: char c=-128; c=c-1;  //c=127  происходит аналогичное явление, только наоборот.

Такое свойство чисел назовем циклическим и представим его в виде круговой диаграммы:

Рисунок 1.1 – Круговая диаграмма представления значений целых чисел

а - для чисел со знаком в доп. коде; б - для чисел без знака

В связи с тем, что данное свойство отражает природу реального мира, например отсчет углов поворота по компасу, и оно с пользой может быть использовано грамотными программистами, ситуация переполнения не выявляется как ошибочная. Расчет будет продолжен с новым значением. Это как раз тот случай, когда задача обеспечения правильности вычислений целиком ложится на плечи программиста.

Для обеспечения беззнакового представление чисел при объявлении переменной необходимо применить модификатор unsigned. Преимуществом использования такой переменной будет удвоение диапазона положительных значений. Допустимыми значениями станут числа от 0 до 255 (28-1).

unsigned char c=127;

c=c+1;

cout<<(int)c<<endl; //c=128

c=255;

c=c+1;

cout<<(int)c<<endl; //c=0

c=0;

c=c-1;

cout<<(int)c<<endl; //c=255

Характеристики целочисленных типов данных

И знаковые и беззнаковые данные типа char могут принимать только 256 значений и определяется это тем, что данные этого типа занимают 1 байт и представляются 8 разрядами.

Тип данных short int или сокращенно short, занимает 2 байта и, соответственно, может принимать 216 = 65 536 значений. Данные long int или сокращенно long, занимают 4 байта и могут принимать 232 = 4 294 967 295 значений.

Особое место занимают данные типа int. Их длина выбирается компилятором 2 или 4 байта в зависимости от конструкции компьютера. Так 8-битные микроконтроллеры Atmel наиболее быстро могли работать с данными размером 2 байта, поскольку имеют 8-разрядные регистры. Современные процессоры для персональных компьютеров имеют как минимум 32-битные регистры. Исходя из этого все компиляторы, работающие под Windows, выбирают для типа int размер 4 байта.

В таблице 4.1 приведены характеристики целочисленных типов данных при программировании на С++:

Таблица 4.1 - Характеристики целочисленных типов данных

Тип данных

Длина, байт

Min значение

Max значение

byte

1

-128

127

unsigned byte

1

0

255

short

2

-32 768

32 767

unsigned short

2

0

65535

int

4 (2 под DOS)

-2 147 483 648

2 147 483 647

unsigned int

4 (2 под DOS)

0

4 294 967 295

long

4

-2 147 483 648

2 147 483 647

unsigned long

4

0

4 294 967 295

Правила выбора размера целочисленных данных

  1.  Если нужно экономить память, выбирайте тип char (1 байт) или short (2 байта).
  2.  Если значения будут превышать 32767 и важна переносимость программы (возможна компиляция ее под DOS), то выбирайте тип long (4 байта).
  3.  Если важна скорость вычислений, то применяйте тип int и компилятор выберет размер данных (2 или 4 байта), над которыми операции выполняются быстрее.
  4.  Если на то нет особых причин, программисты используют тип int.

Поразрядные операции И, ИЛИ, НЕ, ИСКЛЮЧАЮЩЕЕ ИЛИ (&, | ,~,^)

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

При поразрядной операции И (AND), которая обозначается &, бит результата принимает значение 1 когда и у первого и второго операнда он равен 1. Копирует в результат только те биты первого операнда, где во втором операнде находятся единицы, остальные – обнуляет. Операнд, указывающий биты, над которыми производится действие, называется маской. Таким образом, эта операция позволяет очищать или выделять заданные биты первого операнда.

Выделение значений двух разрядов и очистка значений двух разрядов (2-го и 3-го):

1100 1010      1100 1010     

0000 1100 - маска   1111 0011 - маска

0000 1000      1100 0010   

            Выделены          Очищены

В качестве примера выполним эти же вычисления в программе:

char c=0xCA;   //1-й операнд = 202

cout<<(c&12)  <<endl; //=8

cout<<(c&0xF3)<<endl; //=194

Чтобы записать шестнадцатеричное число (константу) CA, впереди ставят ноль и букву  “икс” (х или Х): 0xCA или  0xca.

При поразрядной операции ИЛИ (OR), которая обозначается |, бит результата принимает значение 1 когда или у первого, или у второго операнда 1, или оба бита 1-цы. Применяется для установки в 1 заданных бит:

1100 1010  

0000 1100 - маска

1100 1110   

        Установлены в 1

Пример:

char c=0xCA;   //1-й операнд = 202

cout<<(c|12)<<endl;  //= -50

При поразрядной операции ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR), которая обозначается ^, бит результата принимает значение 1, когда биты первого и второго операнда имеют различные значения. Команда используется, когда нужно найти бит или биты, значение которых изменилось или когда нужно изменить значение определенных разрядов:

1100 1010 - старое значение  1100 1010     

1100 0110 - новое значение   0000 1100 - маска

0000 1100       1100 0110   

         Изменились          Изменены (инвертированы)

Пример:

char c1=0xCA,c2=0xC6;

cout<<(c1^c2)<<endl;  //= 12

cout<<(c1^12)<<endl;  //=-58

При поразрядной операции отрицания - НЕ (NOT), которая обозначается ~ и является однооперандной, все биты инвертируются. Имеет очень высокий приоритет, который выше, чем у операций AND, OR, XOR. Применяется совместно с предыдущими двухоперандными операциями для изменения значений одного из операндов (маски) на противоположное:

Рассмотрим еще раз пример для операции AND:

1100 1010         1100 1010     

0000 1100 – маска – инвертируем    1111 0011

0000 1000         1100 0010   

           Выделены           Очищены

Пример:

char c=0xCA;   //1-й операнд = 202

cout<<(c& 12)<<endl;  //=  8

cout<<(c&~12)<<endl;  //= -62

Операции сдвига (<<, >>)

Сдвигают двоичное представление первого операнда влево или вправо на количество разрядов, задаваемое вторым операндом. Пример:  5<<2; // = 20.

Сдвиг на каждый разряд влево удваивает значение числа. Вправо – уменьшает его в 2 раза.

При сдвиге влево, справа на освободившееся место вдвигаются нули. При сдвиге вправо вдвигаются нули, если операнд беззнакового типа. Если операнд знакового типа, то повторяется старший (знаковый) разряд. Возьмем известное нам значение (–5) = 1111 1011. При сдвиге вправо с расширением знакового бита получим 1111 1101 = -3. Если бы вдвигался ноль, то знак числа изменился бы и результат стал бы равен 0111 1101 = 125, что правильно, если бы 1111 1011 было беззнаковым числом 251.

Проверка:

char c1=-5;   

unsigned char c2=c1; //Разряды с1 копируются в с2

cout<<(c1/2) <<endl; //=-2

cout<<(c1>>1)<<endl; //=-3

cout<<(c2/2) <<endl; //=125

cout<<(c2>>1)<<endl; //=125

cout<<(c1<<2)<<endl; //=-20 (умножение на 4)

Задание по расчетной работе № 1

Расчетная работа №1 выполняется в рамках самостоятельной работы студентов по курсу "Микропроцессорная техника". На нее предусмотрено 3 часа из 54, отведенных на самостоятельную работу.

  1.  Взять номер варианта N, например N=23. Если  номер варианта меньше 10, то перед цифрой варианта добавляется 0, например: N=05 для 5-го варианта.
  2.  Получить его двоичное представление  ( 23= 10111 ), из которого выделить 4 младших разряда ( В = 0111 ). Если получилось В = 0000, то принять В = 1001.
  3.  Получить шестнадцатеричное представление  N = 2310 = 1716 и вычесть его из FF:               H  =  FF – 17  =  E8.
  4.  Преобразовать в двоичные числа 2N, 9N, 27NN, 45NN, например, для 23-го варианта: 223 =, 923 =, 272323 =, 452323 = . Для 5-го варианта: 205=, 905=, 270505=, 450505=.
  5.  Преобразовать в шестнадцатеричную и затем в двоичную  5N, 7N, 35NN, 5N9N, например, 523 =, 723 =, 352323 =, 523923 =.. Для 5-го варианта: 505=, 705=, 350505=, 505905=.
  6.  Преобразовать в десятичную из двоичной  11В =,  1В1 =, 1ВВВ =, 1В1В1В =, например: 11 0111 =, 10 1111 =, 1 0111 =, 1 0111 0111 0111 =, 101111011110111=.
  7.  Преобразовать в десятичную из шестнадцатеричной 1Н, 9Н, 8НН, 2Н3Н, например, 1Е8 =, 9Е8 =, 8Е8Е8 =, 2Е83Е8 =.
  8.  Преобразовать числа [H], FF[H], [H] [H] в десятичную систему как числа со знаком. Например: знЕ8 = -24, знFFE8 =, знE8E8 =.
  9.  Преобразовать в шестнадцатеричные двухбайтные числа со знаком: -1 =, -3 =, -1N =, -3NN =.
  10.   Сложить         5 СВ [ H ]        Например:         5 СВ Е8

                     9 [ H ] EF                                     9 E8 EF

  1.   Вычесть         9 [ H ] 00         Например:          9 E8 00

                    5  FE [ H ]                                    5 FE E8

Все промежуточные вычисления должны быть подробно расписаны. Работа сначала сдается на проверку. Для зачета работы необходимо  продемонстрировать умение выполнять указанные вычисления без использования таблиц, калькулятора и компьютера.


Лабораторная работа №1 – Программирование на языке Ассемблера, компиляция в машинные коды, исполнение

Архитектура ЭВМ, разработанная Джоном фон Нейманом

  1.  Машина имеет память, которая хранит программу, данные и результаты промежуточных вычислений.
  2.  Программа вводится в машину, так же, как и данные (а не коммутируется проводами).
  3.  Адресный принцип. В команде указываются не сами числа, над которыми выполняются арифметические действия, а адреса – номера ячеек памяти, где эти числа находятся.
  4.  Автоматизм. После ввода программа работает автоматически. Каждая команда содержит явное или неявное указание об адресе команды, которая будет выполняться следующей.
  5.  Переадресация. Адреса ячеек памяти, указанные в команде, можно вычислять и преобразовывать как числа. ЭВМ может сама готовить команды, которые выполняет. ЭВМ напоминает движение танка, который прокладывает перед собой рельсы (на внутренней стороне гусениц) и едет по ним.

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

Задание:

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

Таблица 1.1 – Варианты заданий к л.р. №1

№ вар.

1

2

3

4

5

6

7

8

9

10

Нач. регистр

R1

R2

R3

R4

R5

R6

R7

R8

R9

R10

Числа

3

1

8

9

2

4

7

6

2

11

№ вар.

11

12

13

14

15

16

17

18

19

20

Нач. регистр

R11

R12

R13

R14

R15

R16

R17

R18

R19

R20

Числа

5

1

3

8

14

13

2

7

4

3

№ вар.

21

22

23

24

25

26

27

28

29

30

Нач. регистр

R1

R2

R3

R4

R5

R6

R7

R8

R9

R10

Числа

9

12

8

16

5

1

3

7

14

4

Допускается только одна команда занесения числа в регистр (команда с непосредственным операндом типа  ldi регистр, константа). Остальные команды могут быть:    mov регистр, регистр;    inc регистр;   add регистр, регистр;   sub регистр, регистр.


Таблица 1.1 – Команды и их кодирование

Мнемоника

Description

Код 

Описание

ADD Rd, Rr

Add

0000 11rd dddd rrrr

Сложение:   Rd = Rd + Rr

SUB Rd, Rr

Subtract

0001 10rd dddd rrrr

Вычитание:  Rd = RdRr

INC Rd

Increment

1001 010d dddd 0011

Rd ++

MOV Rd, Rr

Move

0010 11rd dddd rrrr

Содержимое Rr копируется в Rd

LDI Rd, K

Load Immediate

1110 KKKK dddd KKKK

Загрузка непосредственной константы в регистр R(d+16)

LDS Rd, k

Load direct

from SRAM

1001 000d dddd 0000

kkkk kkkk kkkk kkkk

Загрузка регистра из ячейки памяти с адресом k

STS  k, Rd

Store direct

to SRAM

1001 001d dddd 0000

kkkk kkkk kkkk kkkk

Сохранение регистра в ячейку памяти с адресом k

LD Rd, Z

Load indirect

1000 000d dddd 0000

Загрузка регистра из ячейки памяти с адресом, хранящимся в регистре Z

BRLT k

Branch if Less Than zero

1111 00kk kkkk k100

Переход, если при вычитании первый операнд был меньше второго: PC = PC + k + 1, где k – в доп. коде

Пример:

Пусть необходимо в регистрах, начиная с R3 сформировать такие числа:  8, 1, 4, 12, 6, 3.

Напишем программу:

ldi r16,1 ;r16=1

mov r4,r16 ;r4=1

mov r3,r4 ;r3=1

inc r3 ;r3=2

inc r3 ;r3=3

mov r8,r3 ;r8=3

inc r3 ;r3=4

mov r5,r3 ;r5=4

add r3,r3 ;r3=8

mov r6,r3 ;r6=8

add r6,r5 ;r6=C

mov r7,r8 ;r7=3

add r7,r7 ;r7=6

sub r0,r0 ;r0=0 – Очистка суммы

sub r1,r1 ;r0=0 – Очистка счетчика итераций

ldi r17,6 ;r17=6 – Количество итераций

ldi z31,0 ;Загрузка адреса начальной

ldi z30,3 ;ячейки памяти в регистр Z

loop:

ld  r10,z ;Загрузка элемента массива из ячейки с адресом z во ;временный регистр

add r0,r10 ; s = s + m[i] – накопление суммы

inc zl ;Увеличение Z на 1

inc r1 ; i++

mov r16,r1 ;

sub r16,r17; r1<r3 ?

brlt loop ; переход, если меньше на метку loop

Для удобства программирования следует представить программу в виде таблицы:

 

Таблица 1.2 – Команды программы и их коды

Команды

Комментарий

Двоичный код команд

Шестн. код

ldi r16,1

mov r4,R16

mov r3,r4

inc r3

inc r3

mov r8,r3

inc r3

mov r5,r3

add r3,r3

mov r6,r3

add r6,r5

mov r7,r8

add r7,r7

sub r0,r0

sub r1,r1

ldi r17,6

ldi r31,0

ldi r30,3

loop:

ld  r10,z

add r0,r10

inc r30

inc r1

mov r16,r1

sub r16,r17

brlt loop

;r16=1

;r4=1

;r3=1

;r3=2

;r3=3

;r8=3

;r3=4

;r5=4

;r3=8

;r6=8

;r6=C

;r7=3

;r7=6

;s=0

;ii=0

;n=6

;z=0x0000

;i=z=0x0003

;r10= m[i]

;s=s+m[i]

;z++

;ii++

;r16=ii

;ii<n ?

;переход,если ;меньше на loop

1110 0000 0000 0001

0010 1110 0100 0000 0010 1100 0011 0100

1001 0100 0011 0011

1001 0100 0011 0011

0010 1100 1000 0011

1001 0100 0011 0011

0010 1100 0101 0011

0000 1100 0011 0011

0010 1100 0110 0011

0000 1100 0110 0101

0010 1100 0111 1000

0000 1100 0111 0111

 

0001 1000 0000 0000

0001 1000 0001 0001

1110 0000 0001 0110

1110 0000 1111 0000

1110 0000 1110 0011

 

1000 0000 1010 0000

0000 1100 0000 1010

1001 0101 1110 0011

1001 0100 0001 0011

0010 1101 0000 0001 0001 1011 0000 0001

1111 0011 1100 1100

(на 7 команд назад)

E0 01

2E 40

2C 34

94 33

94 33

2C 83

94 33

2C 53

0C 33

2C 63

0C 65

2C 78

0C 77

18 00

18 11

E0 16

E0 F0

E0 E3

80 A0

0C 0A

95 E3

94 13

2D 01

1B 01

F3 CC

Для загрузки и исполнения программы откройте программу VMLAB. Если программа не установлена, то установите ее на диск D: в папку VMLAB. Инсталляция находится на “D:\Комплект_по_МП-технике\К лаб работе №1”. Кроме того, в вашу личную папку сбросьте папку проекта с именем My_z3.

После запуска программы VMLAB откройте проект с которым будем работать:       ProjectOpen ProjectE:\ES07a\Петров\My_z3\vmlab.

Закройте в программе все окна кроме Registers и Program Memory.

Если эти окна тоже оказались закрыты, то откройте их через меню View.

Затем выполните операцию Project – Re-build all. В окне Program Memory появятся коды и текст загруженной программы на языке ассемблера.

Чтобы выполнить первую команду этой программы, нажмите F6. При этом вы увидите, как в окне Program Memory выделенная строка переместилась на следующую команду, а в окне Registers изменилось содержимое регистров в соответствии с выполненным действием. Прошагайте несколько команд, отслеживая их воздействие на регистры, чтобы научиться работать в VMLAB. Закройте проект ProjectClose Project.

Для загрузки в программу проекта полученных вами кодов команд, откройте файл E:\ES07a\Петров\My_z3\main..hex   в блокноте. Вы увидите следующий текст:

:0800000013C0FECFFDCFFCCFC1

:10000800FBCFFACFF9CFF8CFF7CFF6CFF5CFF4CFB4

:10001800F3CFF2CFF1CFF0CFEFCFEECFEDCF00009F

:1000280001e0402E342c33943394832C3394532CCE

:10003800330C632c650c782c770c0018111816E01C

:10004800f0E0E3E0A0800A0CE3951394012D011BBE

:10005800CCF30000000061F0A591B59105901590BE

где после кода 0000 (отмечен голубым цветом), находится код первой команды программы e001, только байты e0 и 01 переставлены местами. Это выполнено по причине существования правила: “Число в памяти расположено так, что младший байт хранится по младшему адресу”. В конце каждой строки находится два служебных символа, которые к программе не относятся (отмечены желтым цветом). Найдите в этом тексте коды остальных команд из программы табл.1.2. Разобравшись с размещением кодов программы приведенного выше примера, впишите на эти места коды вашей программы. При вставке кодов замещайте ими существующие символы так, чтобы служебные байты, отмеченные желтым цветом, не изменяли своего положения. Закройте файл с сохранением и заново откройте проект в VMLAB. Выполните вашу программу и проконтролируйте правильность результатов на каждом шаге, в том числе правильность найденной в цикле суммы регистров.

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

Контрольные вопросы:

  1.  Где хранится программа на ПК и на МК Atmega?
  2.  В каком виде хранится программа?
  3.  Где хранятся данные на ПК и на МК Atmega?
  4.  В каком виде хранятся данные?
  5.  Какие этапы обработки проходит программа от рукописного текста до выполнения?
  6.  Как обычно получают коды команд программы?
  7.  В чем состоит адресный принцип построения архитектуры компьютера?
  8.  В чем состоит принцип автоматизма?
  9.  Приведите примеры применения переадресации.
  10.  Написать программу из 3-7 операторов языка Ассемблера по заданию преподавателя.
  11.  Закодировать команду из таблицы 1.1 по заданию преподавателя.

Лабораторная работа №2 – Работа в CodeVision AVR. Разработка и выполнение простейшей программы

Автоматическая генерация проекта

Запустите интегрированную среду разработки программ CodeVisionAVR. Из меню выберите File – New – Project – OK.

На вопрос Do you want to use CodeWizardAVR ответьте Yes. (Wizard – мудрец, чародей).

В появившемся диалоге

во вкладке Chip выберите тип контроллера (Atmega8 или Atmega16) и установите частоту впаянного на плату кварца (для МК2 это 12 MHz). Program TypeApplication (Тип программы – приложение).

Во вкладке Ports должны быть запрограммированы порты на ввод информации (In) или на вывод (Out) в зависимости от подключенных к портам устройств. В соответствии со схемой контроллера MK2 к порту В подключены катоды светодиодных индикаторов, а к порту D – управление их сегментами, следовательно эти порты программируем на вывод. Начальное состояние Output Value (выводимая величина) устанавливаем нулевым.

К выводам порта А  PA7 и PA6 подключены реле, а к PA1 – динамик, поэтому их программируем на вывод, Output Value = 0 иначе реле сразу сработают. Остальные выводы порта А будут использоваться как входы АЦП, поэтому их программируем на вход, подтяжку (Pullup) – внутреннее подключение к источнику питания через резистор 20К во избежание неопределенного состояния порта – не производим.

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

Во вкладке External IRQ (Interrupt Request – внешние прерывания) можно указать внешние источники прерываний. Так если выбрать INT2 Enabled (дана возможность) то при установке Falling Edge (по спадающему фронту) при переходе (INT2/AIN0)PB2 входа порта В из высокого в низкое состояние будет вызвана функция с именем ext_int2_isr(), которая должна быть оформлена в тексте программы. Такое действие можно вызвать, например, нажатием кнопки, заземляющей при нажатии данный вывод.

Найдите на корпусе процессора выводы, через которые можно вызывать внешние прерывания INT0 и INT1. В нашем контроллере внешние прерывания не используются, поэтому ничего во вкладке не меняйте.

Timer 0 – это 8-битнй таймер, имеющий низкую точность. Будет использоваться для переключения разрядов светодиодного индикатора. В качестве источников импульсов (Clock Source) выбираем System Clock, тогда таймер будет работать с частотой кварцевого генератора, уменьшенной в 1, 8, 64, 256 или 1024 раз, в зависимости от значения делителя, что при частоте кварца 12 МГц дает нам частоты 12000 КГц, 1500 КГц, 187.5 КГц, 64.875 КГц или 11.718 КГц. Выберем Clock Value = 187.5 КГц. При поступлении импульсов на вход таймера с такой частотой, его счетчик будет увеличиваться на 1 при получении каждого импульса.

Выбираем Mode: Normal Top, что означает нормальный режим работы – счет от 0 до FF. Для вызова прерывания при переполнении выбрать Overflow Interrupt. Вызываемая функция будет иметь имя interrupt [TIM0_OVF] void timer0_ovf_isr(void) и будет вызываться с частотой 187500 Гц / 256 = 732 раза в секунду. При 6 цифрах в индикаторе будет происходить 732 / 6 = 122 зажигания каждой цифры в секунду. Так как частота выше 60, то мерцания индикатора заметно не будет.

Timer1 – 16-битный таймер. Максимальное значение счетчика FFFF = 216 - 1 = 65535. Соответственно имеет большУю точность. В УМК используется для организации часов. На вход таймера подадим системные тактовые импульсы, в нашем случае 12 МГц. Прерывание будем вызывать не при переполнении, а при достижении счетчиком значения 12000.  12 000 000 / 12 000 = 1000 вызовов в секунду. Поместив в функцию прерывания счетчик, получим значение времени в миллисекундах, прошедшего с момента включения МК – переменная  itime.

Установки таймера 1:

Clock Source: System Clock

Clock Value: 12000 kHz  – установить частоту кварца

Mode: Normal Top = FFFFh  – но мы будем останавливать счет раньше – при достижении 12000

Interrupt on: Compare A Match  – совпадение при сравнении

Comp. A:    2ee0  – число, равное 2*4096+14*256+14*16 = = 12000, заносится в специальный регистр таймера, при совпадении с которым вызывается прерывание

Вызываемая функция будет иметь имя interrupt [TIM1_COMPA] void timer1_compa_isr(void).

Вкладка Project Information – занести свою фамилию и группу.

Вкладка ADC  (Analog to Digital Converter) – установка режима работы аналого-цифрового преобразователя.

 ADC Enabled – Выбрать работу АЦП

 Interrupt – Вызывать прерывание по окончании счета

 Nose Canceller – Подавлять шумы при работе АЦП

Volt Ref AREF pin – Референсное напряжение будет взято с вывода AREF

    Можно выбрать AVCC pin – сравнение будет производится с напряжением питания или Int.cap.on AREF – использовать внутренний источник референсного напряжения 2.54 В.

Clock 187.500 kHz  – Частота тактового генератора для АЦП

Данные во вкладках LCD (Liquid Crystal Display), I2C, 1Wire, USART, Analog Comparator, SPI оставляем без изменений, так как их не используем.

Запускаем генерацию проекта: Диалог со вкладками не закрываем(!) а из его меню выбираем  FileGenerate Save and Exit – будут вызваны три диалога:

  1.  Save C Compiler Source File –
  2.  Save C Compiler Project File – во всех случаях укажите одно и тоже имя файла,
  3.  Save Workspace – например, TimerTest

Предлагаемые типы файлов не изменяйте!

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

Установка драйвера программатора

Для работы программатора необходимо один раз установить его драйверы. Для этого вставьте программатор в порт USB. Будет найдено новое устройство AVR910 USB и запрошены его драйверы. Укажите путь к папке Драйвер для AVR910 USB программатора., которая находится не диске D: в папке Комплект по МП-технике.

Открываем Мой компьютер – Свойства – Оборудование – Диспетчер устройств – Порты COM и LPT  и проверяем, на какой из COM-портов подключился программатор AVR910 USB. Если это COM9 или любой другой, кроме третьего, то назначаем порт COM3 принудительно.

При последующих подключениях программатора он будет автоматически опознаваться и появляться в списке устройств, как подключенное к порту COM3 устройство AVR910 USB.

Установка режимов работы программатора

Из меню интегрированной среды разработки выбрать ProjectConfigureC compiler   и установить:

File Output Format OBJ  ROM  HEX  EEP

Нажать ОК.

After Make Program Chip.

OBJ – объектный файл, ROM – Read Only Memory, HEX hexadecimal (шестнадцатеричный), EEP – Energy EEPROM – вид памяти МК, куда записывается программа.

Из меню интегрированной среды выбрать SettingsProgrammer  выбрать  Atmel AVRProg (AVR910) и установить порт COM3 (или другой, к которому подключен программатор).

Запуск программы на компиляцию

Производится нажатием кнопки . Если в появившемся окне отчета есть строки

No errors

No warnings

то программа откомпилирована без ошибок и может быть записана в микроконтроллер.

Программирование микроконтроллера

Запись программы в память микроконтроллера производится нажатием кнопки . В отчете будет указан процент использования памяти  Program size: 160 words (2.0% of FLASH). Собственно сам процесс записи начнется при нажатии кнопки .

Лабораторная работа №3 – Программирование 7-сегментного светодиодного индикатора

Устройство и принцип работы 7-сегментного индикатора

Семисегментный индикатор состоит из 8 светодиодов, включенных как показано на рисунке 3.1, которые подсвечивают сегменты.

       

Рисунок 3.1 – Устройство 7-сегментного индикатора а) одноразрядного; б) трехразрядного

Чтобы зажечь на индикаторе цифру 2, необходимо на выводы A, B, F, E и D через резисторы 330 Ом подать напряжение +5В, а общий катод подключить к земле. Резисторы устанавливаются для ограничения тока каждого светодиода до величины I = 5В/330 Ом = 15 мА. При подаче большего тока светодиод перегревается и выходит из строя. Чтобы снизить яркость свечения сопротивление можно увеличить (до 1 кОм).

Выпускаются от одно- до девятиразрядных индикаторов. Такие индикаторы имеют объединенные аноды (рис 3.1б) и отдельно выведенные катоды для каждого разряда. Очевидно, что такое подключение не позволяет зажигать различные значения разрядов числа. В этом случае индикацию делают динамической. При этом первую цифру зажигают на долю секунды, затем подают положительное напряжение на другую комбинацию сегментов и подключают катод второй цифры, зажигая ее, и так далее. Если каждая цифра будет зажигаться менее 50 раз в секунду, мерцание будет заметно, и будет неприятно воздействовать на зрение. Максимально допустимую продолжительность горения одной цифры можно рассчитать tд = 1/(50∙n), где n – общее количество цифр на индикаторе. При увеличении количества разрядов индикатора частота переключения с цифры на цифру должна быть пропорционально увеличена. Так при двух цифрах требуется не менее 100, а при 9 цифрах – не менее 450-ти переключений в секунду.

Подключение индикаторов к контроллеру

На рисунке 3.2 изображено подключение двух 3-разрядных индикаторов, как это выполнено в микроконтроллере МК-2.


Рисунок 3.2 – Подключение двух трехразрядных семисегментных индикаторов и светодиода HL1 для индикации знака “–”

Выводы управления сегментами индикаторов объединены и подключены к порту D контроллера через токоограничивающие резисторы R10-R17 с величиной сопротивления 330 Ом. При выводе логической 1 в младший разряд порта D на 14-м выводе контроллера появится напряжение 5 В, которое через резистор R10 попадет на сегменты H всех 6 цифр обеих индикаторов. Программно это выполняется так:

PORTD = 1;

Для выбора цифры, на какой будет подсвечен сегмент H, катоды цифр подключены через транзисторные ключи VT1-3, VT5-7. Через транзистор VT4 подключен отдельный плоский светодиод индикации знака “–”, который установлен перед вторым индикатором. При подаче положительного напряжения на базу одного из транзисторов ключей, транзистор открывается, его сопротивление перехода коллектор-эмиттер становится небольшим (около 3 Ом) и катод этой цифры соединяется с землей. При этом зажигаются сегменты только одной выбранной цифры.

Управление открытием транзисторов осуществляется через разряды 5 – 0 порта B. Для снижения управляющего тока транзисторов до 1.5 мА применены резисторы R1-R7 с величиной сопротивления 2.2 кОм. При таком токе базы переход коллектор-эмиттер будет иметь сопротивление всего 2.7 Ом.

Необходимость применения транзисторов вызвана тем, что при токе 15 мА одного сегмента суммарный ток всех все 8 зажженных сегментов достигнет величины 120 мА. Если бы мы подключили катоды к порту B напрямую, протекание такого тока через один вывод порта привело бы к выходу его из строя, так как максимально допустимый ток одного вывода – 20 мА  и  не более 80 мА на весь порт.

При подключении индикаторов, как изображено на рис.3.2, для вывода цифры 2 на третьем разряде 1-го индикатора достаточно выполнить следующие операторы:

PORTD = 0b11011010; или PORTD = 0xDA – зажигание сегментов AB_DE_G_

PORTB = 0b00001000; или PORTD = 1<<3; – выбор третьей цифры

Последний оператор означает сдвиг 1 на 3 двоичных разряда влево.

Для вывода уже двух цифр потребуется применение динамической индикации:

m1:

PORTD=0x60; //Коды сегментов цифры 1

PORTB=1<<5; //Выбор 1-й цифры

delay_ms(10);  //Задержка на 10 миллисекунд

PORTD=0xDA;  //Коды сегментов цифры 2

PORTB=1<<4;  //Выбор 2-й цифры

delay_ms(10);  //Задержка на 10 миллисекунд

goto m1; //Бесконечный цикл

Попробуйте увеличить задержку до 500 миллисекунд. Что наблюдаете?

Удобно разместить коды сегментов, которые должны быть выведены, в массиве segm из 6 элементов, соответственно количеству цифр на индикаторах. Тогда программа динамической индикации значительно упростится. Выведем цифры 123 456 на двух индикаторах.

int segm[6]={0x60,0xDA,0xF2,0x66,0xB6,0xBE}; //Коды сегментов цифр

int scanpos=0;

m1:

PORTD=segm[scanpos]; //Вывод кодов сегментов цифр в порт D

PORTB=1<<(5-scanpos); //Выбор цифры, на которую указывает scanpos

delay_ms(3);  //Задержка на 3 миллисекунды

scanpos++; //Переход к следующей цифре

if(scanpos>5) scanpos=0;//Возврат к первой цифре

goto m1; //Бесконечный цикл

Замечание: Необходимость подключения отдельного светодиода HL1 через транзистор VT4 связана с тем, что этот вход контроллера используется для подключения программатора. В этом случае нагрузка составляет 2.2 кОм, а без транзистора нагрузка была бы 330 Ом.

Таблица 3.1 – Задание к лабораторной работе №3

вари-анта

Задание

1

Названия трех пунктов меню                                          переключаются  на втором индикаторе при нажатии кнопок  ↑↓.

2

Названия трех пунктов меню                                                       переключаются  на индикаторах при нажатии кнопок  ← →.

3

Первая цифра в числе                 , выведенном на первом индикаторе увеличивается / уменьшается циклически при нажатии кнопок  ↑↓.

4

Вторая цифра в числе                 , выведенном на втором индикаторе увеличивается / уменьшается циклически при нажатии кнопок  ↑↓.

5

Позиция точки в числе                               переключаются  циклически при нажатии кнопок  ← →.

6

Выведенное на двух индикаторах число                             перемещается  циклически при нажатии кнопок  ← →.

7

Число                            перемещается  влево / вправо при нажатии кнопок  ← → не выходя за пределы индикатора.

8

Первая цифра в числа                         ,   мигает. Позиция мигания перемещается  циклически при нажатии кнопок  ← →. 

9

Первая цифра в числа                    погашена. Погашенная позиция перемещается в пределах числа при нажатии кнопок  ← →. Точка отображается всегда.

10

Первая позиция числа                 на втором индикаторе мигает. Позиция мигания перемещается  в пределах числа при нажатии кнопок  ← →. 

11

Первая позиция числа                                 выделена повышенной яркостью за счет свечения в два раза дольше, чем остальные цифры. Выделенная яркостью позиция перемещается  в пределах числа при нажатии кнопок  ← →. 

12

Вывести на индикаторе текст                                (“Отсечка”, “Перегрузка”) с помощью динамической индикации. Задержку при зажигании следующей цифры установить в 0,5 секунды. При нажатии кнопок  ↑↓ задержку увеличивать/уменьшать в 1.189 раза.

13

В шестнадцатеричном числе           , выведенном на втором индикаторе, последняя цифра увеличивается/уменьшается при нажатии кнопок  ↑↓ в пределах от 0 до F. Зацикливание не применять (после 0 не должно появляться F и наоборот).

14

Реализовать часы. На первом индикаторе отображать минуты, на втором – секунды с точностью до десятых. Счет начать с 0 минут 0.0 секунд. Для вывода чисел использовать функцию Fout.

15

Реализовать секундомер. На первом индикаторе отображать секунды, на втором – тысячные доли секунды. Счет начать с 0.0 при нажатии “Enter” и останавливать при нажатии “Esc”. При нажатии  показания обнуляются. Для вывода чисел использовать функцию Fout.

Контрольные вопросы:

  1.  Нарисовать схему подключения светодиодов сегментов в двухразрядном индикаторе.
  2.  Изобразите схему подключения одно/двух/ … /семиразрядного 7-сегментного индикатора к портам Х1 и Х2 контроллера Atmega8/Atmega16.
  3.  Нарисуйте схему подключения к МК двух одноразрядных индикаторов для работы без применения динамической индикации.
  4.  Какое ограничение существует на величину тока одного вывода порта/на весь порт?
  5.  Напишите программу вывода заданного текста или цифр на индикаторах.
  6.  Напишите программу увеличения заданного разряда числа, выведенного на индикаторе при нажатии кнопки ↑ / уменьшения при нажатии ↓.
  7.  Напишите программу мигания всего числа, выведенного на индикаторе.


Лабораторная работа №4 – Программирование таймеров

Перед выполнением данной работы изучите регистры таймеров и режимы их работы по лекциям 7 и 8, прерывания по лекции 9 и тему “Получение заданных напряжений с помощью ШИМиз лекции 11.

Пример настройки Таймера0 на генерацию 10-битного ШИМ

В качестве примера запрограммируем Таймер1 на вывод двухканального 10-битного ШИМ с максимально возможной частотой. Двухканальный – означает, что у нас будет два отдельных сигнала, каждый со своей величиной ШИМ.

Программный код для конфигурации таймера 1 создадим с помощью мастера CVAVR:

  1.  Запустите компилятор CodeVisionAVR и кликните по серой шестеренке в панели инструментов - запустится  мастер начального кода.
  2.  Выберите тип МК и частоту кварца (рис.4.1а):

 

а) б)

Рисунок 4.1 – Настройки проекта при задании режимов Таймера 1

  1.  Щелкните по ярлыку - Таймеры и затем по Таймер 1
  2.  Сделайте следующие установки: 

- оставить источник тактирования таймера без изменения - "System Clock";

- выбрать тактирующую частоту равной частоте кварца;

- режим ШИМ  mode 7 - по Лекции, табл. 7.1;

- выходы Out A: и B:  установите "Не инвертирующими". 

  1.  Во вкладке Ports установите для битов 4 и 5 режим Out, таким образом, сконфигурировав контакты PD4 и PD5 для работы выходами. Почему именно эти выводы? Потому что, как следует из Лекции, рис.3.1, именно эти выводы имеют имена OC1B и OC1A что означает Output Compare выводы каналов В и А Таймера 1. Вот и все установки для 2-х каналов 10-битного (top = 3FFh)  ШИМ на ножках PD4 и PD5. 
  2.  Посмотрим код, полученный мастером, выбрав в меню над вкладками File - Program Preview.

Нас интересуют вот эти строки:

 

DDRD=0x30; // PD4 PD5 теперь выходы 

// .......... 

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 12000,000 kHz
// Mode: Fast PWM top=03FFh
// OC1A output: Non-Inv.
// OC1B output: Non-Inv.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0xA3;
TCCR1B=0x09;

TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;

OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

 

Проанализируем этот код.

Настройка PD4, PD5 для работы на выход должна быть очевидной!

Далее идут комментарии настройки Таймера1 и строка кода:

TCCR1A=0xA3; // 1010 0011

описание этого регистра Лекции, стр. 46.

Биты_7_6 выбирают форму сигнала на выводе PD5 (канал А Таймера 1), биты_5_4  –  на выводе PD4 (канал B).

Биты_1_0  совместно  с  битами_5_4  регистра  TCCR1B  определяют режим работы ШИМ по по Лекции, табл. 7.1. В нашем случае:

TCCR1B=0x09; // 0000 1001

Значит комбинация 4-х битов определяющая режим ШИМ   0111.  По Лекции, табл. 7.1 определяем, что это режим 7, как и было указано мастеру!

Биты_2_0  регистра  TCCR1B  определяют коэф. деления источника тактового сигнала прежде чем он попадет в Таймер_1. У нас это 001  по таблице 48  коэф. деления  1   - т.е. таймер_1 считает с частотой кварца.

Скорость счета совместно с разрядностью ШИМ определяют частоту ШИМ сигнала ! 

Значит, частота ШИМ задается коэффициентом деления тактирующего МК сигнала и разрядностью ШИМ. 

Самостоятельно определите назначение следующих 4 регистров. 

Рассмотрим еще 4 регистра, в которые нужно записывать желаемую величину ШИМ в виде числа от 0 до 1023:

OCR1AH=0x00;
OCR1AL=0x00;

OCR1BH=0x00;
OCR1BL=0x00;

 

Помните в мастере опцию – “Не инвертирующий”?

Выбрав inverted, вы замените величину  ШИМ на скважность !

"1" и "0" на выходах OC1x просто поменяются местами и задав (записью соответствующего числа в регистры OCR1xx) величину ШИМ  например 25 %  на выходе вы получите сигнал со скважностью 25%  - соответственно величина такого ШИМ сигнала будет 75% .

 

Зададим величину ШИМ на выводе PD4, добавив в программу перед строкой      while(1){   такие операторы:

// вывести ШИМ около 25% на PD4
OCR1BH = 0x00; 
OCR1BL = 0xFF;
// PWM(PD4) 255/1023 = 24.9(%) 

Чтобы увидеть второй ШИМ сигнал на виртуальном осциллографе SCOPE симулятора  VMLAB, нужно в файле проекта  vmlab.prj  внести добавку:

.plot V(PD1) V(PD4) V(PD5) V(DAC)

Таблица 4.1 – Варианты заданий к лабораторной работе № 4

вар

Таймер

Частота,

с

Скважность,

%

Вывод на

Управление

Величина

Кнопки

1

0

46.8 кГц

10

Индик.

Период

↑ ↓

2

1

0.179 Гц

20

Зел. св.

Период

←  →

3

2

5.8 к

30

Кр. св.

Скважность

↑ ↓

4

0

732 Гц

40

Динамик

Скважность

←  →

5

1

0.715 Гц

50

Индик.

Период

↑ ↓

6

2

732 Гц

60

Зел. св.

Период

←  →

7

0

138 Гц

70

Кр. св.

Скважность

↑ ↓

8

1

2.86 Гц

80

Динамик

Скважность

←  →

9

2

138 Гц

90

Индик.

Период

↑ ↓

10

0

45 Гц

10

Зел. св.

Период

←  →

11

1

22.9 Гц

20

Кр. св.

Скважность

↑ ↓

12

2

138 Гц

30

Динамик

Скважность

←  →

13

0

732 Гц

40

Индик.

Период

↑ ↓

14

1

183 Гц

50

Зел. св.

Период

←  →

15

2

5.8 кГц

60

Кр. св.

Скважность

↑ ↓

16

0

46.8 кГц

70

Динамик

Скважность

←  →

Лабораторная работа №5 – Измерение напряжений и токов с помощью АЦП

Подготовка файлов для VMLAB

  1.  Создайте текстовый файл, например z5_start.txt, который будет файлом проекта для VMLAB.
  2.   Измеряемое напряжение мы будем подавать на вход PA0 (ADC0 - вывод 40) МК с движка переменного резистора. Выводы переменного резистора подсоединим к нулю и к питанию МК. Таким образом, во время эмуляции мы сможем менять напряжение на входе ADC0 АЦП от 0 до 5 вольт.
  3.  Результат измерения будем выводить в порт B на 5 светодиодов эмулятора - горит "1" не горит "0" - точнее мы будем видеть только 5 младших битов результата.

 

; Заголовок:

; ********* www.avr123.nm.ru *********
;
; задача 5.  АЦП МК AVR AT90S8535
;
; компиляция на - CodeVision C compiler demo
;
; Эмулятору VMLAB нужны файлы .hex .cof __.c
; полученые в результате компиляции.
;
; *********************************


; Для использования АЦП МК нужно подать 
; опорное напряжение на вывод AREF - мы
; подадим 5 вольт питания МК.
Но! в VMLAB 
; нельзя соединить два узла напрямую 
; используем резистор на 1 Ом:


R1 VDD AREF 1
; резистор R1 подключен к 
; узлам VDD и AREF. Сопротивление 1 Ом


; опорное напряжение Vref у нас 5 вольт - 
; значит при подаче 5 вольт на вход АЦП
; мы получим результат: 11111 11111 (АЦП в 
; AT90S8535 10-ти разрядный)
; а шаг преобразования составит 
; Vref/1024=4.883 милиВольта


; Вход0 АЦП (это вывод PA0 МК) мы подключим к 
; подвижному контакту переменного
; резистора (Slider 1 в окне "Control Panel") - 
; чтобы при эмуляции менять измеряемое
; напряжение на входе АЦП.


V1 PA0 VSS SLIDER_1(0 5)
; на концах переменника 
; 0 и 5 вольт


; 5 светодиодов
; подключаем их к выводам порта B


D1 VDD PB0
D2 VDD PB1
D3 VDD PB2
D4 VDD PB3
D5 VDD PB4
 


.PLOT V(PA0)
; На экран Осцилографа (окно 
; "SCOPE") выведем напряжение
; на движке потенциометра


;   Все, файл проекта для VMLAB готов.

 Обратите внимание, VMLAB допускает прямое подключение светодиодов к  + питания и выводам МК. В действительности необходим  токоограничивающий резистор 430 - 910 Ом, включенный последовательно с каждым светодиодом!

Создание программы для МК:

  1.  В папке D:\CVAVR (где у вас должен находится компилятор CodeVisionAVR) создайте папку Atmega16 для файлов проекта.
  2.  Запустите компилятор.
  3.  Для создания файла проекта выберите  Файл -> новый -> проект -> ОК -> No 
  4.  Перейдите в созданную для проекта папку Atmega16 и введите в поле "имя файла": Atmega16.
  5.  Нажмите "сохранить" - откроется окно конфигурации проекта.
  6.  Откройте закладку "C Compiler" и установите все вот так:

Обратите внимание на форматы выходных файлов: 

Нам понадобится как обычно .HEX, но теперь еще и .COF файл - в нем содержится привязка прошивки для МК к тексту программы на Си для симуляторов !

  1.  Нажмите ОК.
  2.  Для создания файла исходного текста на Си нажимайте Файл -> Source -> ОК   появился файл untitled.c.
  3.  Теперь нажимайте Файл -> Сохранить как, введите в поле "имя файла": A8535.c  и нажмите Сохранить.

Теперь все готово к созданию текста программы на языке Си. Текст программы выделен черным цветом, а комментарии зеленым:

/*  заголовок программы

ADC пример для МК AT90S8535
 

Курс AVR "с нуля" на языке Си - задача 5 

avr123.nm.ru 

CodeVisionAVR C Compiler

Напряжение на выводе AREF = 5.0V
Частота кварца 3.69 МГц
Измеряемое напряжение подается на вывод PA0
Результат (младший байт!) выводится в PORTB
К битам 0_4  PORTB подключены светодиоды.
*/

#include <90s8535.h>   /* файл с описанием "железа" МК AT90S8535. Текст этого файла просто будет вставлен вместо этой строки препроцессором компилятора перед компиляцией */

#include <delay.h> // готовые функции задержек

#define ADC_VREF_TYPE 0x00 /* теперь препроцессор везде в тексте программы заменит "ADC_VREF_TYPE" на "0x00"  


Директива #define  -  очень мощная и удобная Изучите и применяйте ее! 

*/

/* Мы будем прерываться по завершении АЦ преобразования и выводить результат.

Нужно написать функцию обработчик этого 
прерывания - пишем: */

interrupt [ADC_INT] void adc_isr(void) {
/* ОЧЕНЬ ВАЖНО! Открывающую фигурную скобку тела функции нужно писать в одну строчку с ней - если будем отлаживать программу с просмотром движения по тексту на языке Си */

PORTB=(unsigned char) ~ADCW;
/* выводим в PORTB результат АЦП. 

Проанализируем эту строку программы ... 


Регистра ADCW вы не найдете в DataSheet
но в компиляторе CVAVR вы можете использовать его - это виртуальный 16 битный регистр, он содержит все 10 бит результата - удобно, но можно использовать и регистры из DataSheet, а именно: ADCL и ADCH  

Далее идет операция: 

~   - это инверсия: ЕДИНИЦЫ становятся НУЛЯМИ и наоборот, нам нужно это сделать, чтобы "1" соответствовал горящий светодиод - ведь по схеме по
дключения он загорается когда на ножке МК "0" 

Еще важный момент: (unsigned char)  - приведение типа данных - двухбайтную величину (ADCW - виртуальный!!! 16 битный регистр существующий только в "голове" компилятора КодВижн!) мы привели к типу беззнаковый символьный - это 8 бит - такой тип данных "полезет" в порт МК */

delay_ms(20);  /* задержка 20 милисекунд

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

Подробнее о прерываниях в Лекции № 9.

*/ 

ADCSR|=0x40; // запустили следующее 
// АЦ преобразование.
//
почитайте DataSheet о регистре ADCSR ! 

}
// закрывающая скобка функции- 
// обработчика прерывания



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


void main(void) { 
/* Главная функция main - она должна быть в любой программе на Си */

PORTB=0xFF;
/* Записали в "защелки" порта "B" МК единички - но на выводах МК они появятся только когда мы сделаем эти ножки ВЫХОДАМИ ! */

DDRB=0xFF;
/* Регистр направления работы выводов  порта "B" МК - мы записали восемь "1" - значит теперь все ножки стали ВЫХОДАМИ и на них появились сигналы находящиеся в защелках PORTB, а предыдущей строкой программы мы туда закинули единички - теперь они на ножках PB0_PB7 МК. */ 

 

 

 

 

Высокие уровни это почти напряжение питания МК - значит ток через светодиоды не протекает и они погашены. 

Светодиоды другими своими выводами подключены через резист
оры именно к питанию! 

Значит пропала разность потенциалов на светодиоде и нет тока - он не горит. 

Вот так просто... 

 

 

 

 

 



ADCSR=0x8E; /* мы записали в ADCSR число 0x8E или 1000 1110  

Bit 7 - ADEN: записали ‘1’ - включили АЦП (догадались? да, да... '0' - выключить АЦП) 

Bit 6 - ADSC: ‘1’ - запускает АЦ преобразование, а у нас '0' значит преобразование пока не начнется. 

Bit 5 - ADFR: ‘1’ - переводит АЦП в автоматическую непрерывную работу - в "автономку". У нас Bit 5 = '0' - значит АЦП будет делать каждое, отдельное  преобразование по нашей команде.  

Bit 4 -ADIF: Флаг прерывания - по окончании АЦП становится ‘1’ и сбрасывается либо выполнением обработки прерывания, либо записью в этот бит единицы! 

Bit 3 - ADIE: ‘1’ - разрешили прерывание по окончании АЦП.
 

Bits 2..0 - ADPS2..ADPS0: Установка частоты работы АЦП - у нас 110 - значит коэф. деления 64 - частота работы АЦП 57,65625 кГц. */

#asm("sei")
// разрешили глобальные прерывания

ADMUX=0;
// Выбрали вход АЦП, напряжение на котором будет оцифровываться. 
// почитайте DataSheet о регистре ADMUX 
// Вы должны понимать как выбрать канал АЦП

ADCSR |=0x40;  
/* Запустили первое преобразование сделав '1' бит_6 в регистре ADCSR  

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

Маска это число, в котором все биты нули, а значение "1" имеют только устанавливаемые биты.   

*/
while (1);
/* бесконечный цикл - будем сидеть в нем пока есть питание МК, а по завершении АЦП будем выскаиквать в функцию обработки прерывания и возвращаться сюда */

}
// скобка закрывающая для main

Вот текст программы на Си без комментариев:

#include <90s8535.h> 
#include <delay.h> 
#define ADC_VREF_TYPE 0x00 
interrupt [ADC_INT] void adc_isr(void)

{
   PORTB=(unsigned char) ~ADCW;
   delay_ms(20); 
   ADCSR|=0x40; 

void main(void)

{
   PORTB=0xFF; 
   DDRB=0xFF; 
   ADCSR=0x8E; 
   #asm("sei") 
   ADMUX=0; 
   ADCSR|=0x40; 
 

   while (1); 




Сохраните файл с исходным тестом программы - нажмите на "дискетку".

Также его нужно включить в состав проекта: нажмите на "молоток-ключ-отвертка" - в открывшемся окне конфигурации проекта нажмите - Add - выбирете Atmega16.c - и "Открыть" – теперь файл A8535.c в составе проекта, нажмем "ОК". Сделайте: Файл - сохранить все. 

Симулируем:

Нам понадобятся всего 3 файла из полученных в процессе компиляции: 
A8535__.c  
A8535.hex  
A8535.cof 
 

Запустите  VMLAB.

Нужно создать новый проект 

нажимаем: Project - New project  

появилось окно "Create new project" посмотрите внимательно - оно с
одержит несколько шагов конфигурирования проекта - нужно просто заполнить их аккуратно.

step 1 - дадим имя нашему проекту ad_test.prj убедитесь что он расположен в созда
нной нами папке!

step 2 - выбор МК: AT90S8535

step 3 - отмечаем третий пункт - файл A8535.cof

step 4 - пишем в верхнем поле название файла исходного текста на Си A8535__.c cи нажимаем кнопку справа: "добавить этот".   
Теперь в поле "Target file [HEX]" впишем: A8535.hex

Жмем "ОК"

Разверните окно файла проекта ad_test.prj - скелет проекта готов! Теперь нужно открыть текстовый файл z5_start.txt  который мы создавали в начале задачи. 

Мы описали в нем на языке Эмулятора схему устройства на МК - теперь нужно доб
авить в него несколько строчек из сгенерированного эмулятором файла проекта: 

Вставьте перед строчкой "; Для исполь..." следующее:

.MICRO "AT90S8535"

.TOOLCHAIN "GENERIC"

.TARGET "a8535.hex"
; эмулируемая прошивка МК

.COFF "a8535.cof"
; файл содержит привязку 
; содержимого [.hex] к коду в [__.c]


.SOURCE "a8535__.c"
; исходник на Си на который 
; сорентирован файл [.cof].

; это CodeVision добавил '__' при компиляции


.TRACE
; выводить отладочную инфо в окне 
; SCOPE - розовым (см. HELP эмулятора)


.CLOCK 3.69meg
; частота используемого кварца

;---------------------------------------------
; Обозначения электрических "контактов" - 
; узлов МК к которым можно "подключиться"
; эмулятору: RESET, AREF, ACO, TIM1OVF
; PA0-PA7, PB0-PB7, PC0-PC7, PD0-PD7, 

; __
эта информация справочная - для 
; каждого МК своя!
 


Теперь в тестовом файле z5_start.txt  у нас полное описание проекта сохраните его. Выделите весь текст, скопируйте и замените вставкой содержание развернутого файла проекта эмулятора ad_test.prj 

Теперь: Файл - сохранить все.

Можно от'Билдить проект - нажмите F9

Вот такая надпись должна вас порадовать:


Все готово к прогону программы в эмуляторе.

Но перед запуском нужно еще сконфигурировать окна на экране ПК чтобы удобно было наблюдать процесс эмуляции. Нам понадобятся окна:

  •  Control panel -  на этой панели переменник для изменения напряжения на входе АЦП и светодиоды
    Peripherals - нажмите "+" A/D converter - будем смотреть что в регистрах АЦП происходить будет.
  •  Messages - всякие месаги кидает по ходу эмуляции - разместите его внизу и сделайте низким и широким.
    Scope - виртуалный осцилограф - в нем можно увидеть напряжение на входе АЦП - установите вертикальную шкалу 1 вольт на деление.
  •  Code - в этом окне мы увидим наш исходник на Си и движение программы по нему в процессе работы.

В меню View можно посмотреть какие еще окна доступны - а для чего они почитать в Help.

 

3) Эмуляция: 

Нажимаем светофор. Эмулятор умничает и ругается: мол Сторожевой Таймер (собака в просторечии) батенька должна быть сброшена! до включения!


Любит он поругаться - но у нас ЦВЕ не используется - посмотрите файл с ассемблерным листингом программы (он в папке проекта в компиляторе) - там вот такой пунктик есть:

;DISABLE WATCHDOG

LDI R31,0x18
OUT WDTCR,R31
LDI R31,0x10
OUT WDTCR,R31

Эмулятор заругался на строчку 3 не учитывая, что написано в строках 4 и 5! 

иронично: ...и эта фича эмулятора называется проверка пр
авильности кода! во как...

Пожалуйста откройте DataSheet стр. 44 раздел: "Watchdog Timer" - это очень полезное устройство и нужное! 

Давайте разберемся с нашим ASM кодом:

LDI R31,0x18 ; загрузили в регистр R31 число 00011000

OUT WDTCR,R31 ; это число записали в регистр WDTCR 

LDI R31,0x10 ; загрузили число 00010000

OUT WDTCR,R31
 ; записали в регистр WDTCR

если вы прочитали стр. 44 и хотя бы начало стр.45 - вам стало ясно, что смутило эмулятор в 3 строчке: это запись в бит_3  значения "1".  

НО! механизм отключения Собаки имеет защиту от случайного отключения! Отключ
ается Собака переводом бит_3 из "1" в "0" - но при условии что бит_4 у нас "1" !!! 

Так что компилятор сделал все правильно! 

 

 

 

 

Включенный WDT (или Собака) сбрасывает - "ресетит" МК если его самого (Собаку) не сбросить программой то его переполнения. 

Если программа в МК "завистнет" то Собака  не будет сброшена и перезагрузит МК - значит перезапустит программу МК сначала!

Собака - сторожевой таймер - тикает от своего внутреннего RC генер
атора - период срабатывания устанавливается программно.

 

 

 

 

Эмулируем дальше:

Пойдем по программе шагая по инструкциям - для этого есть 2-я кнопка  (правее светофора) "Step into". Нажимаем ее. В окне "код" - видим подсветилась первая строка в функции main { } - все верно, программа на Си и должна выполнятся отсюда. 

Откройте View -> Watch  - в этом окне появляются названия функций, в которых мы находимся в данный момент.

Нажимаем опять "Step into" - перешли на следующую строчку кода Си - хотя МК выполнил две ASM инструкции! Еще два раза нажимаем и видим что в регистр АЦП ADCSR записано число 10001110 - это есть 0x8E в двоичном виде! Продолжая в это духе мы могли бы увидеть попадание в функцию обработчик прерывания - но слишком много кликать мышкой придется. Есть решение этой проблемы - называется "Точка останова" или "Breakpoints". 

Щелчком мыши сделаем вот так:

Мы поставили значок "СТОП" левей той строки на которой хотим остановится.

Нажимаем "светофор" и мгновенно останавливаемся на интересующей нас строчке! так просто.

В окне Watch видим: Мы находимся в обработке прерывания 0x0E - это прерывание от АЦП.

Теперь поднимите движок переменника S1 в окне "Control Panel" примерно на второе деление снизу и снова нажмите "светофор"

Видим в окне "Peripherals" что напряжение на входе АЦП 1.19 вольт а двоичный код преобразования в регистре ADCL  '11110011'

Но почему же мы не видим этого результата на светодиодах??? 

Дело в том что мы остановились по прерыванию АЦП - т.е. преобразование уже выполнено, а вот строчка на которой мы остановились еще не выполнялась - т.е. результат не отправлен в PORTB - и светодиоды отображают предыдущий результат или начальное состояние - а они у нас погашены в начале программы!

Нажмите кнопку вторую справа от светофора - светодиоды загорелись в соответствии с результатом! Значит результат отправлен в PORTB и мы его видим.

Давайте выключим точку останова (щелкните мышкой по значку stop) и запустив программу "светофором" в режим непрерывной работы понаблюдаем как отображается в Осциллографе наши манипуляции потенциометром - одновременно в окне "Peripherals" можно увидеть десятичное и двоичное значения входного напряжения АЦП.

Теперь вы можете самостоятельно попробовать различные изменения в процессе эмуляции.

Задача завершена - программа работает в соответствии с поставленной задачей.
Задание для самостоятельной работы: 

Измените текст программы на Си так чтобы АЦП проводил преобразования со всех входов последовательно. 

А схему устройств измените так: Между всеми входми АЦП включите резисторы по 10 кОм, кроме того поставьте резистор 10 кОм от входа PA0 на землю и такой же резистор от входа PA7 к +5 вольт питания МК.  

Теперь напряжения на всех входах АЦП различны - вы можете посчитать их а затем результат проверить в VMLAB ! 

 

Лабораторная работа №6 – Изучение структуры типовой программы микроконтроллера, реализация меню

Функция вывода текста на заданном индикаторе

Запустите интегрированную среду разработки программ CodeVisionAVR. Из меню выберите FileNewProjectOK.

Функция вывода целого числа

Запустите интегрированную среду разработки программ CodeVisionAVR. Из меню выберите FileNewProjectOK.

Функция вывода числа с плавающей точкой с заданным числом цифр после точки

Запустите интегрированную среду разработки программ CodeVisionAVR. Из меню выберите FileNewProjectOK.

Лабораторная работа №7 – Связь с ПК через порт RS232. Работа микроконтроллеров в сети RS485

Лабораторная работа №8 – Моделирование работы схемы контроллера в среде VMLAB

VMLAB – Visual Micro Lab – симулятор микроконтроллеров семейства AVR и подключенной к ним электронных устройств.

Инсталляция  VMLAB:

1. Загрузите файлы  к лабораторной работе №8 (лр8.zip) в созданную  папку - D:\VMLAB\лр8   и распакуйте файлы архива в эту же папку.

2. Запустите VMLAB  и через меню Project -> open project откройте проект  D:\vmlab\z8\лр8.prj

3. Сверните мешающее окно vmlab.prj и подправьте "мышкой" остальные окна  чтобы получить такую картинку экрана:

Вы видите :
- 8 светодиодов;
- 3 переменных резистора;
- клавиатуру на 16 кнопок которые можно использовать и раздельно,
- виртуальный ЗАПОМИНАЮЩИЙ осциллограф;
- виртуальный терминал с записью данных;
- просмотр портов МК;
- слежение за содержанием переменных;
- отладка по коду программы на Си;
- диаграмма PD1 - передача по USART .

4. Теперь в меню "Project" кликните "Re-build all" - проект нужно перекомпилировать при открытии и внесении каких либо изменений. В окне "Messages" появится сообщение "Success! All ready to run".  Это значит ошибок нет и все готово к моделированию микроконтроллера ATmega16. Вверху загорелся зеленым светом светофор. 

Если появилось сообщение об ошибке и светофор не загорелся - вы допустили ошибку на каком то этапе. Проделайте Шаг 2 сначала и более внимательно.

Симуляция работы МК

1. Нажмите мышкой светофор - это аналогично включению устройства, подаче питания на МК - программа зашитая в него начинает выполняться...

И тут же остановка! Дело в том что VMLAB контролирует правильность работы МК и содержимое программы. Если ему что-то не нравится то симуляция прерывается и в окне Messages появляется сообщений о причине. Подробнее это будет обсуждаться позже.

2. Нажмите светофор еще столько раз, сколько потребуется  до начала  непрерывной симуляции. Понаблюдайте внимательно что происходит на экране.

В окне SCOPE (это виртуальный осциллограф) вы видите как меняются напряжения на ножках МК указанных в файле проекта - vmlab.prj  Верхняя осциллограмма - это  сигнал на ножке TXD (PD1) по которой МК передает данные на COM порт ПК - что передает МК мы видим в виртуальном терминале TTY в панели Control Panel.

Там выводится значение ШИМ (PWM) сигнала создаваемого на контакте PD5 - а сам сигнал виден в окне SCOPE  - посмотрите как он меняется в соответствии с сообщаемыми числовыми значениями.

В файле проекта - vmlab.prj  к выводу PD5 подключен простейший фильтр нижних частот (ФНЧ) из резистора и конденсатора - он преобразует ШИМ в постоянное напряжение которое можно увидеть в окне SCOPE сигнал DAC (АЦП).

3. Остановите программу красной кнопкой STOP. В окне Messages появится
сообщение о том что программа остановлена пользователем - User break.

4. Разверните окно Code - в нем отображается исходный код программы которая "прошита" в МК и выполняется при симуляции. Вы увидите что некоторые строки программы подсвечиваются желтым цветом - длина подсветки пропорциональна времени которое программа тратит на выполнение этой строки.

5. Найдите строку в программе:  

pwm_val = ((1023 * (u32)pwm)/100);
Щелкните по квадратику с зеленой вставочкой перед этой строкой - он превратится в красный знак STOP вы поставили "точку останова" (Break point) - теперь программа а
втоматически остановится перед выполнением этой строки.

6. Сверните окно Code и нажмите светофор для продолжения симуляции.
Дождитесь остановки программы на этой строке (на этой точке останова) - при ост
ановке строка программы подсветится голубым цветом. Посмотрите на панели внизу справа текущее "чистое" время (без учета остановок) прошедшее с запуска программы - запомните.

7. Теперь продолжите симуляцию (нажмите зеленый светофор). Через некоторое время программа опять остановится на этой строке, но время уже будет другим. Вычтите из него время прошлой остановки и вы получите время выполнения этого участка программы. О более точном измерении интервалов времени будет рассказано позже.

 

Информация об остановках программы отображается и в окне Messages. 

Как изменить программу    

Вам предстоит многократно менять создаваемые программы - в процессе отладки, пока они не начнут работать так как вы хотите.

1. Запустите компилятор CodevisionAVR (CVAVR) и через меню File -> Open откройте файл проекта CVAVR   -  c:\vmlab\z8\cv.prj 

2. Разверните окно с текстом программы. Вы видите что программа начинается с оформленного в виде комментария краткого описания того что она делает и некоторых технических параметров. Программа написана на языке Си - который является пожалуй самым популярным и удобным при программировании для МК.


3. Найдите в тексте программы в компиляторе CVAVR строки: 

putchar('P'); // вывод в USART символа P
putchar('W');
putchar('M');


Давайте заменим выводимое этими строками слово  PWM  на слово  WOW  вот так:

putchar('W'); // вывод в USART символа W
putchar('O');
putchar('W');


4. После внесения изменений в исходный текст программы ее нужно cкомпили-
ровать. Компилятор должен превратить вашу программу в файл "прошивку"  .hex кот
орый можно прошить (загрузить) в реальный МК или использовать в симуляторах.

5. Для выполнения компиляции нажмите кнопку "Make the project":

После компиляции появится информационное окно в котором сообщается что наша программа содержит целых 5 ошибок ! В чем же дело? Где найдены ошибки и каковы они написано красным цветом в левой части экрана в окне Navigator  - навигации по проекту CVAVR:


При наведении курсора можно увидеть описание ошибок.
6. Первая ошибка - "не могу открыть файл m8_128.h"

Этот файл включен в исходный текст программы строкой:

#include <m8_128.h>

Этот файл был создан для возможности прямой вставки примеров на Си из документации в текст программы в CVAVR. В инсталляции компилятора его нет. Но в тексте программы написано где можно скачать файл – скачайте m8_128.h.
Скачав, поместите его в папку INC компилятора CVAVR.

7. Снова откомпилируйте программу кнопкой "Make the project" - теперь получаем сообщение об отсутствии ошибок и о размере программы и о том сколько это %% от максимального размера программы для данного МК.

Посмотрите внимательно - хотя ошибок нет, но есть “Warning” - это замечание от компилятора. Замечания не критичны, но можно посмотреть в навигаторе о чем они. Закройте информационное окно кнопкой "ОК".

Вы выполнили всего 4 несложных шага, но уже знаете что моделировать работу МК можно на компьютере не имея самого МК и электронной схемы вокруг него. При этом видеть не только то что происходит на ножках МК но и то что происходит внутри МК с помощью нижних частей меню View и Window симулятора VMLAB.  

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

 

Симуляция после правки   

1. Разверните окно симулятора VMLAB - выскочит сообщение о том что файл с текстом симулируемой программы изменен. Мы же его меняли в компиляторе. Закройте его кликнув "ОК".

2. Сделайте "глубокий рестарт" симуляции кнопкой с круговой темно-синей стрелкой и перекомпилируйте весь проект как в Шаге 2 пункт 4 или нажав комбинацию: Shift+F9

Все готово к повторной симуляции.

3. Нажмите светофор 3 раза - начнется непрерывная симуляция и вы увидите результат правки программы в компиляторе CVAVR в окне виртуального терминала симулятора VMLAB - вот он:

Обратите внимание на то что симулятор показывает примерный расчетный ток потребления МК. Скорость симуляции можно снизить регулятором Speed. А частоту кварца можно поменять кнопками Clock.

Кроме того указаны текущие параметры настройки терминала которые можно изменить нажав кнопку "Set parameters". Кнопки "Clear" очищают окна. Вы можете набирать текст в окне TX и он будет передаваться в МК (см. пример к симулятору C:\VMLAB\AVR_demo\UART.PRJ) а можно передать в МК текстовый файл кнопкой  "TX File". Если отметить чек-бокс "RX to file" то данные поступившие от МК будут записываться в файл на ПК. Вы не покупали МК ATmega16 - у вас его нет.

Вы ни чего не паяли и не подключали.

Увидели, как работает МК и программы.

Получили осциллограммы работающего устройства.

Могли записать в файл то что передавал МК.

Выполните остальные  примеры  симулятора VMLAB. Это позволит вам лучше понять его возможности. Дополнительные важные примеры в папке C:\VMLAB\tutorial.

Расчетно-графическая работа №2 – Задания на разработку контроллеров

1. Устройство санкционированного доступа к терминалу управления ячейкой КРУ (кодовый замок)

2. Ключ дистанционного управления выключателем ячейки КРУ 6 кВ с микропроцессорным управлением

3. Терминал управления микроконтроллером по инфракрасному каналу

4. Разработка микропроцессорного устройства управления АВР двухтрансформаторной подстанции на базе МК Atmega16

5. Трехступенчатая микропроцессорная защита от перегрузки


1

0

64

192

128

255

0

64

-64

127

-128

-

+

б

а

&

&

OR

XOR

XOR

&

&

Общий катод

E

G

F

A

B

C

D

H

A B C D E F G H

б)

3

2

1

а)

Общие катоды разрядов индикатора

14

15

16

17

18

19

20

1

2

3

4

5

6

7

PB0

PB1

PB2

PB3

PB4

PB5

PB6

PD0

PD1

PD2

PD3

PD4

PD5

PD6

A       B        C        D       E         F        G    H

“-”

1    2    3     4    5    6    7    8

9

8

7

6

5

4

3

2

1

VT1–VT7

BC547C

R1–R7

  2K

HL1

ATmega16-16

 330

 330

 330

 330

 330

 330

 330

 330

 R8

330

R10-R17

PD7

A       B        C        D       E         F        G    H

1    2    3     4    5    6    7    8

9

+5В

HG1

HG2

VT2

VT3

VT4

VT5

VT6

VT7

VT1

A

B

C

D

E

F

G

H


 

А также другие работы, которые могут Вас заинтересовать

69852. ПРАВООХРАНИТЕЛЬНЫЕ И СУДЕБНЫЕ ОРГАНЫ 978.5 KB
  Задачи изучения дисциплины: дать общее представление о правосудии его конституционных принципах; раскрыть систему правоохранительных органов место их в структуре государственных органов и их компетенция основные цели и задачи; дать общую информацию о правоохранительной деятельности...
69853. РУССКИЙ ЯЗЫК И КУЛЬТУРА РЕЧИ: УЧЕБНО-МЕТОДИЧЕСКИЙ КОМПЛЕКС 421.5 KB
  Язык как универсальная знаковая система. Язык и речь. Основные единицы языка и речи. Язык и общество, роль языка в развитии культуры и в становлении личности. Общение как одна из главных потребностей человека; особенности коммуникации в современном мире...
69854. ТРУДОВОЕ ПРАВО 1.17 MB
  В ходе преподавания и самостоятельного изучения студентами трудового права на основе сочетания аудиторных занятий и самостоятельных форм обучения достигаются следующие цели: образовательная усвоение теоретических положений принципов трудового права особенностей...
69856. Исполнительное производство 384.5 KB
  Государственные требования к минимуму содержания дисциплины 4 Введение 5 Объем дисциплины и виды учебных занятий 7 Тематический план 8 Программа учебной дисциплины 9 Тематический план семинарских практических занятий 20 Планы семинарских практических занятий...
69857. ЛАТИНСКИЙ ЯЗЫК: УЧЕБНО-МЕТОДИЧЕСКИЙ КОМПЛЕКС 237.5 KB
  Целью данного курса является осмысление и заучивание студентами латинских юридических терминов и выражений, встречающихся в юридической литературе и употребляемых юристами, наиболее известных крылатых выражений, а также выработка навыков чтения и перевода...
69858. ОСНОВЫ ФИЛОСОФИИ: УЧЕБНО-МЕТОДИЧЕСКИЙ КОМПЛЕКС 236 KB
  Изучение студентами юридического колледжа основ философии как универсальной формы общественного сознания должно побуждать их к духовной независимости и свободе, способствовать формированию высокой культуры мышления и чувств.
69859. Предпринимательское право: Учебно-методический комплекс 945.5 KB
  Цель изучения учебной дисциплины состоит в привитии обучаемым комплекса знаний, умений и навыков, необходимых для профессионального выполнения ими своих хозяйственно-производственных задач. Основными задачами дисциплины являются: привитие студентам глубоких знаний об основных принципах...
69860. СУДЕБНО-БУХГАЛТЕРСКАЯ ЭКСПЕРТИЗА 884.5 KB
  Цель курса состоит в формировании знаний умений и начальных практических навыков необходимых для профессиональной деятельности по установлению события преступления и изобличению лиц виновных в его совершении с использованием возможностей судебно-бухгалтерской экспертизы.