Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Регистры часов реального времени↑ ⇐ ПредыдущаяСтр 9 из 9 Содержание книги
Похожие статьи вашей тематики
Поиск на нашем сайте
Использование регистров памяти CMOS часами реального времени приведено ниже.
Регистры счетчиков В регистрах 0, 2, 4, 6 и 8 хранится текущее значение времени и дата. Регистры с номерами 1, 3, 5, 7 и 9 – это регистры будильника. То есть можно установить будильник, и когда он сработает, произойдет прерывание.
Регистр состояния A Адрес первого регистра состояния – 0Ah. Формат битовых полей представлен ниже:
Регистр состояния B Адрес второго регистра состояния – 0Bh:
Регистр состояния C Адрес третьего регистра состояния – 0Сh. Этот регистр доступен только для чтения и содержит биты состояния прерывания.
Регистр состояния D Адрес четвертого регистра состояния – 0Dh. Если бит 7 этого регистра сброшен, это означает, что разрядился аккумулятор, питающий память CMOS.
Прерывание от часов реального времени Часы реального времени вырабатывают аппаратное прерывание IRQ8, которому соответствует прерывание с номером 70h. Это прерывание может вырабатываться по трем причинам:
При срабатывании будильника BIOS вырабатывает прерывание INT 4Ah. Программа может подготовить собственный обработчик для этого прерывания.
(слайд №70) Функции прерывания INT 1Ah Для работы с часами реального времени можно обращаться непосредственно к перечисленным выше ячейкам памяти CMOS, используя порты 70h и 71h. Но лучше всего воспользоваться функциями 2 - 7 прерывания INT 1Ah, описанными ниже.
Прочитать показания часов реального времени
Установить часы реального времени
Прочитать дату из часов реального времени
(слайд №71) Установить дату в часах реального времени
Установить будильник
Эта функция позволяет установить будильник на заданное время. Когда будильник “зазвенит”, будет вызвано прерывание INT 4Ah (его вызывает BIOS после прихода аппаратного прерывания от часов реального времени IRQ8, то есть прерывания с номером 70h). Программа, использующая функцию будильника, должна подготовить обработчик прерывания INT 4Ah, завершающий свою работу выполнением команды IRET. При этом можно установить только один будильник.
Сброс будильника
Эта функция позволяет сбросить будильник, например, для того чтобы установить его на другое время.
Пример:
// =================================== // Работа с часами реального времени // =================================== #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <dos.h> typedef struct _SYSTIMER_ { char hour; // часы char min; // минуты char sec; // секунды unsigned year; // год char month; // месяц char day; // число char daylight_savings; // флаг летнего // времени } SYSTIMER; #define RTC_GET_TIME 2 // прочитать // показания часов; #define RTC_SET_TIME 3 // установить // часы; #define RTC_GET_DATE 4 // прочитать // дату; #define RTC_SET_DATE 5 // установить // дату; #define RTC_SET_ALARM 6 // установить // будильник; #define RTC_CLEAR_ALARM 7 // сбросить // будильник. int bcd1bin(char *bcd); int bcd2bin(char *bcd); void bin1bcd(int bin, char *bcd); void _interrupt _far alarm(void); int timer(char fn, SYSTIMER *tm); // Выключаем проверку стека и указателей #pragma check_stack(off) #pragma check_pointer(off) // Макро для выдачи звукового сигнала #define BEEP() _asm { \ _asm mov bx,0 \ _asm mov ax, 0E07h \ _asm int 10h \ } // Прототип программы-обработчика // прерывания будильника void _interrupt _far alarm(void); // Переменная для хранения старого // вектора будильника void (_interrupt _far *old_4a)(void); union REGS reg; int main(void) { char *month_to_text[] = { "январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь" }; SYSTIMER tmr; // Определяем текущие дату и время timer(RTC_GET_DATE, &tmr); timer(RTC_GET_TIME, &tmr); // Выводим дату и время на экран printf("\nСейчас %d год, %s, %d число." "\n", bcd2bin((char*)&(tmr.year)), month_to_text[bcd1bin(&(tmr.month)) - 1], bcd1bin(&(tmr.day))); printf("\nВремя - %02.2d:%02.2d:%02.2d" "\n", bcd1bin(&(tmr.hour)), bcd1bin(&(tmr.min)), bcd1bin(&(tmr.sec))); // Для установки будильника увеличиваем // счетчик минут на единицу. // Для упрощения программы мы // не проверяем счетчик на переполнение, // поэтому если текущее значение счетчика // минут равно 59, будильник не сработает. // Вы можете сами немного // усовершенствовать программу для // проверки переполнения bin1bcd(bcd1bin(&(tmr.min)) + 1, &(tmr.min)); // Выводим на экран время, когда сработает // будильник. printf("\nВремя срабатывания будильника" "- %02.2d:%02.2d:%02.2d" "\n", bcd1bin(&(tmr.hour)), bcd1bin(&(tmr.min)), bcd1bin(&(tmr.sec))); // Подключаем свой обработчик прерывания // будильника, старое значение вектора // 0x4a сохраняем old_4a = _dos_getvect(0x4a); _dos_setvect(0x4a, alarm); // Устанавливаем будильник timer(RTC_SET_ALARM, &tmr); printf("\nБудильник установлен. Для отмены " "и завершения программы нажмите" "\nлюбую клавишу..."); getch(); // Сбрасываем будильник и восстанавливаем // вектор прерывания будильника timer(RTC_CLEAR_ALARM, &tmr); _dos_setvect(0x4a, old_4a); return 0; } // ---------------------------------- // Преобразование однобайтового // числа из формата BCD в двоичный // формат // ---------------------------------- int bcd1bin(char *bcd) { return(((*bcd) & 0x0f) + 10 * (((*bcd) & 0xf0) >> 4)); } // ---------------------------------- // Преобразование двухбайтового // числа из формата BCD в двоичный // формат // ---------------------------------- int bcd2bin(char *bcd) { return(bcd1bin(bcd) + 100 * bcd1bin(bcd + 1)); } // ---------------------------------- // Преобразование однобайтового // числа из двоичного формата // формат BCD // ---------------------------------- void bin1bcd(int bin, char *bcd) { int i; i = bin / 10; *bcd = (i << 4) + (bin - (i * 10)); } // ---------------------------------- // Программа получает управление // при срабатывании будильника. // Ее назначение - выдать звуковой сигнал // ---------------------------------- void _interrupt _far alarm(void) { BEEP(); BEEP(); BEEP(); BEEP(); BEEP(); BEEP(); BEEP(); }
/** *.Name timer *.Title Работа с часами реального времени * *.Descr Эта фун-я предназ-на для * обслуживания системных часов реального * времени через прерывание INT 1Ah * *.Proto int timer(char fn, SYSTIMER *tm) * *.Params char fn - выполняемая функция: * * RTC_GET_TIME - прочитать показания * часов; * RTC_SET_TIME - установить часы; * RTC_GET_DATE - прочитать дату; * RTC_SET_DATE - установить дату; * RTC_SET_ALARM - установить будильник; * RTC_CLEAR_ALARM – сбросить * будильник. * * SYSTIMER tm - структура, содержащая * данные для установки часов или * показания часов: * *.Return 0 - успешное выполнение функции; * -1 - часы реального времени отсутствуют * в компьютере; **/ int timer(char fn, SYSTIMER *tm) { reg.h.ah = fn; switch (fn) { case RTC_SET_TIME: { reg.h.ch = tm->hour; reg.h.cl = tm->min; reg.h.dh = tm->sec; reg.h.dl = tm->daylight_savings; break; } case RTC_SET_DATE: { reg.x.cx = tm->year; reg.h.dh = tm->month; reg.h.dl = tm->day; break; } case RTC_SET_ALARM: { reg.h.ch = tm->hour; reg.h.cl = tm->min; reg.h.dh = tm->sec; break; } } int86(0x1a,®,®); if(reg.x.cflag == 1) return(-1); switch (fn) { case RTC_GET_TIME: { tm->hour = reg.h.ch; tm->min = reg.h.cl; tm->sec = reg.h.dh; break; } case RTC_GET_DATE: { tm->year = reg.x.cx; tm->month = reg.h.dh; tm->day = reg.h.dl; break; } } return 0; }
Программа чтения времени и даты: (слайд №72)
#include <stdio.h> #include <conio.h> #include <stdlib.h> #include <dos.h>
typedef struct _SYSTIMER_ { char hour; // часы char min; // минуты char sec; // секунды unsigned year; // год char month; // месяц char day; // число char daylight_savings; // флаг летнего времени } SYSTIMER;
#define GET_TIME 2 // прочитать показания часов; #define GET_DATE 4 // прочитать дату;
int bcd1bin(char *bcd); int bcd2bin(char *bcd); int timer(char fn, SYSTIMER *treal);
// Выключаем проверку стека и указателей #pragma check_stack(off) #pragma check_pointer(off)
union REGS reg;
int main(void) { char *month_to_text[] = { "январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь" }; SYSTIMER timereal;
// Определяем текущие дату и время timer(GET_DATE, &timereal); timer(GET_TIME, &timereal); // Выводим дату и время на экран printf("\nСейчас %d год, %s, %d число." "\n", bcd2bin((char*)&(timereal.year)), month_to_text[bcd1bin(&(timereal.month)) - 1], bcd1bin(&(timereal.day))); printf("\nВремя - %02.2d:%02.2d:%02.2d" "\n", bcd1bin(&(timereal.hour)), bcd1bin(&(timereal.min)), bcd1bin(&(timereal.sec))); getch(); return 0; }
// Преобразование однобайтового числа из формата BCD в двоичный формат int bcd1bin(char *bcd) { return(((*bcd) & 0x0f) +10 * (((*bcd) & 0xf0) >> 4)); }
// Преобразование двухбайтового числа из формата BCD в двоичный формат int bcd2bin(char *bcd) { return(bcd1bin(bcd) +100 * bcd1bin(bcd + 1)); }
int timer(char fn, SYSTIMER *treal) { reg.h.ah = fn; int86(0x1a,®,®); if(reg.x.cflag == 1) return(-1); switch (fn) { case GET_TIME: { treal->hour = reg.h.ch; treal->min = reg.h.cl; treal->sec = reg.h.dh; break; } case GET_DATE: { treal->year = reg.x.cx; treal->month = reg.h.dh; treal->day = reg.h.dl; break; } } return 0; }
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2016-04-26; просмотров: 439; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.17.181.122 (0.007 с.) |