Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Разработка подпрограммы индикацииСодержание книги
Поиск на нашем сайте Теперь можно заняться следующим блоком часов – блоком индикации. При разработке часов мы получили устройство, в разных частях которого действуют различные частоты. Поэтому первоначально необходимо определить частоту, с которой необходимо производить обновление информации на светодиодных индикаторах. Учитывая, что изменение показаний часов при установке времени может происходить несколько раз в секунду, то выберем точку подключения блока индикации 50 мс, то есть подпрограмму индикации необходимо разместить внутри основного цикла программы. Индикацию внутреннего состояния часов легче всего произвести в составе отдельной подпрограммы. Это, как уже говорилось ранее, позволит разделить задачи и решать их независимо. На данный момент уже реализованы часы. Блок индикации может непосредственно обращаться к переменным часов для считывания хранящейся в них информации. Исходный текст основной программы с циклом, в котором производится вызов подпрограммы индикации, приведен в листинге 25.9.
Листинг 25.9. Исходный текст основной программы.
#include<reg51.h> #include "clock.h" #include "Indic.h"
...
/******************************************************************** ВЫПОЛНЕНИЕ ПРОГРАММЫ НАЧИНАЕТСЯ ОТСЮДА ********************************************************************/ char Delit=20; //8-ми разрядная ячейка памяти для делителя частоты (1с) void main(void) {//-------------ИНИЦИАЛИЗАЦИЯ МИКРОКОНТРОЛЛЕРА------------------------- Timer0_Init(); //Настроить таймер T0 на прерывания с периодом 50мс //-------------ОСНОВНАЯ ПРОГРАММА МИКРОКОНТРОЛЛЕРА-------------------- while(1) //Бесконечный цикл { Indic(); //Произвести индикацию состояния часов на светодиодных //индикаторах
if(--Delit==0) //Если прошла одна секунда, то {Delit=20; //настроить делитель на коэффициент деления 20 Clock(); //и вызвать подпрограмму счётчика секунд. } PCON=1; //Перевести микроконтроллер в пониженный режим } //потребления тока и подождать переполнения таймера }
В приведенном исходном тексте не отображены подпрограммы инициализации таймера и реализации часов. Естественно, что эти программы никуда не делись, они не показаны для уменьшения размера листинга. Теперь можно заняться подпрограммой блока индикации. На принципиальной схеме часов не указано, что и на каком индикаторе должно отображаться. Зададимся, что на индикаторе, подключенном к порту P0, будут отображаться единицы минут. На индикаторе, подключенном к порту P1, будут отображаться десятки минут. На индикаторе, подключенном к порту P2, будут отображаться десятки минут. На индикаторе, подключенном к порту P3, будут отображаться десятки минут. Какой индикатор что отображает, определяется конструкцией часов. При необходимости изменить порядок подключения индикаторов можно просто заменить в программе имена параллельных портов, к которым подключены индикаторы, и перетранслировать программу. Для декодирования двоично-десятичного кода предусмотрим подпрограмму-функцию decod. При этом декодируемое двоично-десятичное число будет передаваться в подпрограмму через ее параметр. Полученный в результате работы подпрограммы семисегментный код будет возвращаться самой функцией. Точно так же как и в случае с часами для индикации создадим отдельный файл (модуль). Исходный текст модуля индикации приведен в листинге 25.10.
Листинг 25.10. Исходный текст модуля индикации.
#include<reg51.h> #include "clock.h"
/***************************************************************************** Подпрограмма семисегментного дешифратора *****************************************************************************/ char Decod(char inp) { }
/***************************************************************************** Подпрограмма блока индикации *****************************************************************************/ void Indic(void) {char tmp; tmp=MIN%10; //Считать содержимое счётчика минут и выделить младшую тетраду P1=Decod(tmp); //Преобразовать её в семисегментный код и передать через //порт P1 на индикатор
tmp=MIN/10; //Считать содержимое счётчика минут и выделить старшую тетраду P2=Decod(tmp); //Преобразовать её в семисегментный код и передать через //порт P2 на индикатор
tmp=Chas%10; //Считать содержимое счётчика часов и выделить младшую тетраду P0=Decod(tmp); //Преобразовать её в семисегментный код и передать через //порт P0 на индикатор
tmp=Chas/10; //Считать содержимое счётчика минут и выделить старшую тетраду P3=Decod(tmp); //Преобразовать её в семисегментный код и передать через //порт P3 на индикатор }
Выделение единиц минут осуществляется при помощи операции взятия остатка от деления на константу 10. Эта операция выполняется при использовании символа ‘%’. При этом осуществляется целочисленное беззнаковое деление содержимого счетчика минут на число 10. В результате в остатке мы получим единицы минут. Это число не будет превышать числа 10, а значит для его представления достаточно четырех бит (тетрады). Десятки минут выделяется аналогичным образом. Отличие заключается в том, что вместо операции взятия остатка используется обычное целочисленное беззнаковое деление. Для того чтобы убедиться в правильности написания программы можно воспользоваться дизассемблированным текстом подпрограммы индикации, приведенным в листинге 25.11.
Листинг 25.11. Дизассемблированный текст подпрограммы индикации.
14: void Indic(void) 15: {char tmp; 16: tmp=MIN%10; //Считать содержимое счётчика минут и выделить младшую тетраду C:0x0099 E50A MOV A,MIN(0x0A) C:0x009B 75F00A MOV B(0xF0),#MIN(0x0A) C:0x009E 84 DIV AB C:0x009F AFF0 MOV R7,B(0xF0) 17: P1=Decod(tmp); //Преобразовать её в семисегментный код и передать через 18: //порт P1 на индикатор 19: C:0x00A1 110A ACALL Decod(C:000A) C:0x00A3 8F90 MOV P1(0x90),R7 20: tmp=MIN/10; //Считать содержимое счётчика минут и выделить старшую тетраду C:0x00A5 E50A MOV A,MIN(0x0A) C:0x00A7 75F00A MOV B(0xF0),#MIN(0x0A) C:0x00AA 84 DIV AB C:0x00AB FF MOV R7,A 21: P2=Decod(tmp); //Преобразовать её в семисегментный код и передать через 22: //порт P2 на индикатор 23: C:0x00AC 110A ACALL Decod(C:000A) C:0x00AE F5A0 MOV P2(0xA0),A
Как видно из этого листинга, деление осуществляется встроенной командой целочисленного деления DIV AB. В качестве примера неправильного использования данных операций воспользуемся листингом 25.12, где переменная MIN объявлена не как unsigned char, а как просто char.
Листинг 25.12. Дизассемблированный текст подпрограммы индикации с переменной MIN char типа.
14: void Indic(void) 15: {char tmp; 16: tmp=MIN%10; //Считать содержимое счётчика минут и выделить младшую тетраду C:0x0099 E50A MOV A,MIN(0x0A) C:0x009B 75F00A MOV B(0xF0),#MIN(0x0A) C:0x009E 11CA ACALL C?SCDIV(C:00CA) C:0x00A0 AFF0 MOV R7,B(0xF0) 17: P1=Decod(tmp); //Преобразовать её в семисегментный код и передать через 18: //порт P1 на индикатор 19: C:0x00A2 110A ACALL Decod(C:000A) C:0x00A4 8F90 MOV P1(0x90),R7 20: tmp=MIN/10; //Считать содержимое счётчика минут и выделить старшую тетраду C:0x00A6 E50A MOV A,MIN(0x0A) C:0x00A8 75F00A MOV B(0xF0),#MIN(0x0A) C:0x00AB 11CA ACALL C?SCDIV(C:00CA) C:0x00AD FF MOV R7,A 21: P2=Decod(tmp); //Преобразовать её в семисегментный код и передать через 22: //порт P2 на индикатор 23: C:0x00AE 110A ACALL Decod(C:000A) C:0x00B0 F5A0 MOV P2(0xA0),A
Как видно из приведенного листинга, в этой программе вместо машинной команды DIV AB используется подпрограмма знакового деления C?SCDIV, что вовсе не входило в наши планы, так как вряд ли эта подпрограмма состоит из одной машинной команды. Этот пример показывает насколько важен выбор типа переменной для каждого конкретного случая. Теперь вспомним, а где же индикация, ведь именно для этого мы и начали писать подпрограмму. Собственно говоря, индикация осуществляется при копировании полученного из подпрограммы декодирования семисегментного кода в параллельный порт. В рассмотренном листинге подпрограммы индикации мы осуществили индикацию всех четырех цифр времени: десятков часов, часов, десятков минут и минут. У нас осталась неразработанной подпрограмма семисегментного дешифратора, которая преобразует двоично-десятичное значение, содержащееся в локальной переменной tmp, в семисегментный код, пригодный для отображения на светодиодном индикаторе. Приступим к разработке этой подпрограммы.
|
||
|
Последнее изменение этой страницы: 2017-02-07; просмотров: 270; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.236 (0.007 с.) |