Разработка генератора секундных импульсов 
";


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



ЗНАЕТЕ ЛИ ВЫ?

Разработка генератора секундных импульсов



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

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

Выберем в качестве таймера, задающего 50-мс интервал, таймер T0. Настройка таймера T0 нам потребуется только один раз (при включении часов). Поэтому настройку таймера поместим в блок инициализации микроконтроллера (часть программы не входящая в бесконечный цикл).

Программа в основном режиме может ожидать переполнения таймера, опрашивая его флаг TF0, но при использовании прерываний от таймера можно значительно снизить потребление микроконтроллера. Экономия тока потребления реализуется при переведении микроконтроллера в спящий режим записью в нулевой разряд регистра PCON логической единицы. После выполнения этой команды микроконтроллер может проснуться только после сброса микроконтроллера или возникновения прерывания.

Для реализации прохождения микроконтроллером по основному циклу один раз в 50 мс, поместим команду PCON=1 в конце тела бесконечного цикла, образованного оператором while(1). В качестве источника прерываний будет служить таймер T0. Переход на начало бесконечного цикла будет осуществляться сразу после возврата из подпрограммы обслуживания прерывания.

Так как прерывания нам потребуются каждые 50 мс, то разрешение прерываний от таймера разместим в подпрограмме инициализации таймера. Разрешение прерываний от таймера производится записью единиц в биты регистра специального назначения IE. Разрешение прерываний от таймера производится битом ET0, а общее разрешение всех прерываний битом EA. Можно записать в эти биты единицу двумя командами присваивания EA=1 и ET0=1, но вспомним, что эти биты находятся в одном регистре. Это означает, что мы можем обойтись одной командой.

Установим биты EA и ET0 в единичное состояние командой логического сложения IE = IE | 0x82, ведь шестнадцатеричное число 0x82 соответствует двоичному числу 10000010. Старший бит этого числа соответствует биту EA, а второй бит этого числа соответствует биту ET0. Использование команды логического сложения вместо команды присваивания позволяет не изменять оставшиеся биты выбранного регистра вне зависимости от состояния этих бит. Язык программирования C позволяет записать эту команду короче: IE |= 0x82.

Теперь специально для начинающих. Я думаю, что перевод чисел из одной системы счисления в другую достаточно затруднителен для человека, впервые столкнувшегося с программированием. Эту работу можно возложить на компилятор. Программа при этом получится длиннее, но зато можно описать комментариями каждый бит многоразрядного числа. Дело в том, что все операции над константами компилятор выполняет в процессе трансляции исходного текста программы, а в загрузочный модуль размещает результирующее число. Поэтому команда IE |= 0x82 может выглядеть в следующем виде: IE |= (1<<7)|(1<<1). Здесь мы просто указываем нужные нам номера битов. Выражение в первых скобках просто означает выделение седьмого бита (единица, сдвинутая на семь позиций влево), а выражение во вторых скобках означает выделение первого бита (единица, сдвинутая на одну позицию влево). Именно такую форму команды мы и выберем.

Теперь микроконтроллер каждые 50 мс будет не только просыпаться, но и передавать управление на вектор прерывания таймера T0. Этот вектор находится по адресу 0Bh. Подпрограмму повторной записи числа 50мс в таймер нужно поместить точно на этот адрес. Размещение подпрограммы на векторе прерывания мы осуществим зарезервированным словом interrupt. Вектор прерывания конкретно таймера T0 выбирается числом 1.

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

 

Листинг 25.3. Исходный текст программы, обеспечивающей проход по циклу один раз за 50 мс.

 

#include<reg51.h>

 

void Timer0(void) interrupt 1 //ВЕКТОР ПРЕРЫВАНИЯ ТАЙМЕРА T0

{TH0=-50000/256; //Загрузить старший байт таймера

TL0=-50000; //Загрузить младший байт таймера

}

 

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

Подпрограмма настройки таймера T0 на 50мс режим работы

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

void Timer0_Init(void)

{TMOD=(0<<7)| //Запретить управление таймером T1 от ножки INT1

(0<<6)| //Синхронизировать таймер T1 от внутреннего генератора

(0<<4)| //Перевести таймер T1 в тринадцатиразрядный режим работы

(0<<3)| //Запретить управление таймером T0 от ножки INT0

(0<<2)| //Синхронизировать таймер T0 от внутреннего генератора

1; //перевести таймер T0 в первый режим работы

 

//Настройка таймера на генерацию 50-ти миллисекундного интервала времени

TH0=-50000/256; //Загрузить старший байт таймера

TL0=-50000; //Загрузить младший байт таймера

 

IE |=(1<<7)| //Разрешить прерывания в микроконтроллере

(1<<1); //Разрешить прерывания конкретно от таймера T0

TR0=1; //включить таймер T0

} //и вернуться в основную программу

 

void main(void)

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

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

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

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

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

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

}

 

Программа, приведенная в листинге 25.3, реализует генератор эталонных интервалов времени с периодом 50 мс. Нам же требуется генератор импульсов с периодом 1 с. То есть, требуется ещё один делитель частоты с коэффициентом деления 20. Его можно реализовать на одиночной ячейке внутренней памяти микроконтроллера.

Для этого выделим 8-ми разрядную ячейку. Это мы делаем при помощи оператора объявления переменной char Delit=20;. Где конкретно будет находиться эта ячейка при программировании на языке C‑51 не важно, однако важно, чтобы в первоначальный момент времени нем содержалось число 20. Если интересно где же конкретно компилятор разместил эту переменную, то можно воспользоваться окном дизассемблера в отладчике программ. Новый вариант программы приведен в листинге 25.4.

 

Листинг 25.4. Исходный текст программы, обеспечивающей вызов подпрограммы часов один раз в секунду.

 

#include<reg51.h>

#include "clock.h"

 

...

 

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

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

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

void Clock(void)

{

}

 

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

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

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

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

void main(void)

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

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

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

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

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

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

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

}

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

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

}

 

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

Подпрограмма реализации часов Clock вызывается точно один раз в секунду. Это обеспечивается тем, что мы организовали счётчик на 20. При вычитании из числа 20 единицы потребуется ровно двадцать вычитаний, а так как проход по циклу мы обеспечили с периодом 50 мс, то 20 вычитаний мы выполним ровно за одну секунду. Через секунду переменная Delit обнулится и мы попадём в составной оператор условного оператора if, расположенный в начале основного цикла программы.

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

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



Поделиться:


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

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