Разработка блока коррекции часов 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Разработка блока коррекции часов



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

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

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

Пример временной диаграммы сигнала на контактах кнопки приведен на рис. 25.5. На этой временной диаграмме четко просматривается зона дребезга контактов. Для иллюстрации эффекта подавления дребезга контактов за счет ввода информации в строго определенные моменты времени, на временной диаграмме, приведенной на рисунке 40, выбран наихудший случай момента взятия отсчета. Этот момент совпадает с зоной дребезга контактов. При этом на выводе порта микроконтроллера может быть считан сигнал, как логического нуля, так и логической единицы. Но даже в этом случае дополнительного импульса не возникает! Дребезг контактов приводит только к неопределенности определения времени нажатия кнопки, который не превышает времени реакции системы, равной 50 мс.

 

Рис. 25.5. Временные диаграммы напряжения на контактах кнопки и сигнала, введенного в микроконтроллер

Новый вариант программы с включенной в цикл подпрограммой опроса кнопок блока коррекции времени приведен в листинге 25.14.

 

Листинг 25.14. Исходный текст основной программы с подпрограммой опроса кнопок коррекции времени.

 

/********************************************************************

ВЫПОЛНЕНИЕ ПРОГРАММЫ НАЧИНАЕТСЯ ОТСЮДА

********************************************************************/

char Delit=20; //8-ми разрядная ячейка памяти для делителя частоты (1с)

void main(void)

{//-------------ИНИЦИАЛИЗАЦИЯ МИКРОКОНТРОЛЛЕРА-------------------------

Timer0_Init(); //Настроить таймер T0 на прерывания с периодом 50мс

//-------------ОСНОВНАЯ ПРОГРАММА МИКРОКОНТРОЛЛЕРА--------------------

while(1) //Бесконечный цикл

{

OprosKnop(); //Опросить кнопки

 

Indic(); //Произвести индикацию состояния часов на светодиодных

//индикаторах

 

if(--Delit==0) //Если прошла одна секунда, то

{Delit=20; //настроить делитель на коэффициент деления 20

Clock(); //и вызвать подпрограмму счётчика секунд.

}

PCON=1; //Перевести микроконтроллер в пониженный режим

} //потребления тока и подождать переполнения таймера

}

 

Теперь можно заняться реализацией подпрограммы опроса кнопок. Для хранения состояния кнопок в этой программе пришлось ввести новую переменную. Её задача состоит в копировании логических уровней с выводов порта во внутреннюю переменную микроконтроллера SostKn. Так как это будет происходить быстро и с постоянной задержкой по времени, то время взятия отсчетов (а также время вывода на индикаторы) будет строго постоянным. Исходный текст подпрограммы опроса кнопок приведён в листинге 25.15.

 

Листинг 25.15. Исходный текст подпрограммы опроса кнопок.

 

sbit P1_7 = 0x97;

sbit P2_7 = 0xa7;

sbit P3_7 = 0xb7;

 

unsigned char SostKn=0;

 

/********************************************************************

Подпрограмма опроса кнопок

********************************************************************/

void OprosKnop(void)

{if(P1_7)

SostKn|=1;

else

SostKn&=~1;

if(P2_7)

SostKn|=2;

else

SostKn&=~2;

if(P3_7)

SostKn|=4;

else

SostKn&=~4;

}

 

В этой подпрограмме кнопки, разнесённые по трем различным портам, сводятся в одну переменную SostKn. Для опроса состояния кнопок установки времени используется условный оператор if. При помощи этого оператора опрашивается состояние логического уровня на входах седьмого вывода портов P1, P2 и P3. Объединение сигналов производится при помощи команд логического ‘И’ и ‘ИЛИ’.

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

При обнаружении на выводе порта логического нуля, в соответствующий бит переменной SostKn записывается логический ноль. Запись производится при помощи оператора логического умножения с константой, содержащей логический ноль в заданном бите. Константа вычисляется на этапе трансляции программы при помощи одноместной операции побитовой инверсии ‘~’.

Исполнение команд, вводимых при помощи кнопок, можно осуществить в любом месте основного цикла программы. Это обеспечит время исполнения команды в пределах 50мс. Точно так же, как и в предыдущих случаях, выделим это действие в отдельную подпрограмму. Пусть эта подпрограмма называется CorrClock.

Первое действие, которое мы выполним в подпрограмме CorrClock — это обработаем команду, вводимую кнопкой установка секунд. По этой команде нужно просто обнулить счётчик секунд. Команду будем получать через глобальную переменную состояния кнопок SostKn. Исходный текст подпрограммы, выполняющей данное действие, приведен в листинге 25.16.

 

Листинг 25.16. Исходный текст первого варианта подпрограммы коррекции внутреннего состояния часов.

 

/********************************************************************

Подпрограмма блока коррекции часов

********************************************************************/

void CorrClock(void)

{if((SostKn&1)==0) //Если нажата кнопка "уст сек",

SEC=60; //то обнулить счетчик секунд

}

 

Обработка нажатия на кнопки “уст мин” и “уст часов” производится несколько иначе. Дело в том, что по общепринятому алгоритму коррекции показаний часов при нажатии на эти кнопки необходимо непрерывно увеличивать показания счётчика часов или минут. Предварительный делитель начинает счет от числа 20, которое в двоичном представлении выглядит как 101002. То, что в младших разрядах записаны нулевые значения означает, что эти разряды будут меняться по двоичному закону, и единица в этих разрядах будет появляться через одинаковые промежутки времени.

Например, в младшем разряде единица будет появляться один раз за 100 мс, то есть десять раз в секунду. В следующем разряде единица будет появляться один раз за 200 мс, то есть пять раз в секунду. В третьем же разряде появление единицы будет неравномерным. Два раза единица в этом разряде появится через 400 мс, а один раз через 200 мс. Если использовать сигнал с этого бита для коррекции времени, то эта непериодичность коррекции показаний часов будет раздражать пользователя, поэтому такой вариант неприемлем.

Пусть изменение показаний часов происходит пять раз в секунду. Эта скорость изменения показаний часов ещё может восприниматься человеком. Подпрограмма коррекции показания часов будет выглядеть так, как это приведено в листинге 25.17.

 

Листинг 25.17. Исходный текст окончательного варианта подпрограммы коррекции внутреннего состояния часов.

 

/********************************************************************

Подпрограмма блока коррекции часов

********************************************************************/

void CorrClock(void)

{if((SostKn&1)==0) //Если нажата кнопка "уст сек",

SEC=60; //то обнулить счетчик секунд

if((Delit&3)==2) //Если в предделителе число не кратно 2,

return; //то выйти из подпрограммы коррекции времени

if((SostKn&2)==0) //Если нажата кнопка "уст мин",

IncMin(); //то увеличить содержимое счётчика минут

if((SostKn&4)==0) //Если нажата кнопка "уст час",

IncChas(); //то увеличить содержимое счётчика минут

}

 

В приведенном варианте программы проверяется два младших бита делителя. Для выделения двух младших бит используется логическое умножение содержимого переменной Delit с маской 00011b. Это число соответствует десятичному эквиваленту 310. Так как эти биты принимают значение 102 пять раз в секунду, то соответствующее количество раз в секунду будет вызываться подпрограмма увеличения значения содержимого счётчика минут (или часов).

Если скорость коррекции показаний часов пять раз в секунду покажется слишком высокой, то можно изменить соотношение коэффициентов деления таймера и делителя, например: 32´31250. Тогда можно будет выбрать скорость коррекции показания часов из набора вариантов два, четыре или восемь раз в секунду. Это обеспечивается двоичным характером коэффициента деления предварительного делителя, равного числу 32. В этом случае, так как изменился коэффициент деления таймера, один проход по основному циклу программы будет осуществляться за 31,25 мс. То есть время реакции часов увеличится. Правда, уменьшится и потребление тока от источника питания.

На этом можно завершить разработку часов. В заключение я хотел бы отметить, что ток потребления микроконтроллера на частоте 12 МГц в режиме пониженного энергопотребления составляет 6,5 мА. Это означает, что даже если отключить светодиодную индикацию, то батарейки с емкостью 300 мА/ч хватит на 46 часов работы. Отличные часы! Не правда ли?

Ток потребления можно снизить, применив вместо стандартного кварцевого резонатора часовой резонатор с частотой 32,768 кГц. При этом ток потребления микроконтроллера снизится в 366 раз и составит 18 мкА. При таком токе потребления той же самой батарейки хватит на 16666 часов или на 694 суток (почти два года работы). Есть разница? Однако при этом программа предварительного делителя будет немного сложнее.

Придется строить делитель с дробным коэффициентом деления. Такие делители обычно строят, переключая два коэффициента деления с определенным периодом, но я думаю, в данном случае это имеет смысл. Основная цель приведенного примера была не в разработке рабочего устройства, а в обучении создания и развития программного проекта на языке программирования C‑51, а также иллюстрация его возможностей.

 



Поделиться:


Последнее изменение этой страницы: 2017-02-07; просмотров: 215; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.191.211.66 (0.02 с.)