Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 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; просмотров: 181; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.142.35.75 (0.017 с.) |