Программирование контроллера
OCW и ICW
Описание работы основных элементов PIC. Схема управления чтением/записью
(Read/Write Control Logic). Основной функцией этого блока является прием команд от
микропроцессора и передача ему информации о состоянии PIC. Обмен с микропроцессором
осуществляется через специальный 8-разрядный буфер данных (Data Bus Buffer),
являющийся интерфейсом между PIC и шиной данных.
В состав блока входят регистры управляющих слов ICW и OCW. Схема управляется
входами CS, RD, WR и АО. Вход CS (Chip select) отвечает за выбор микросхемы. Низкий
уровень сигнала на входе CS разрешает выполнение обмена с PIC. Низкий уровень сигнала на
входе WR (Write) разрешает микропроцессору выводить управляющие слова ICW и OCW для
приема их PIC. Низкий уровень сигнала на входе RD (Read) разрешает PIC передать
микропроцессору информацию о состоянии специальных регистров IRR, ISR и IMR, которые
описаны ниже.
Все управляющие слова ICW и OCW принимаются контроллером в виде 9-разрядных
значений. Разряды 0-7 передаются через 8-разрядный буфер данных. Старший разряд
(восьмой, считая с нуля) носит название АО и устанавливается в 0 или 1 в зависимости от
того, через какой из двух возможных портов ввода-вывода (четный или нечетный) было
передано управляющее слово. Если для вывода значения использовался порт с четным
адресом, АО будет равен 0, если использовался порт с нечетным адресом на единицу
большим, чем предыдущий, тогда АО будет равен 1.
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <iostream.h>
} SYSTIMER;
// Массив длительностей
int del[] = { 4, 2, 3 };
int main(void)
{
int min;
clrscr();
SYSTIMER tmr;
char tempCh;
do
timer(RTC_GET_TIME, &tmr);
if (bcd1bin(&(tmr.hour)) == 8) {
min = bcd1bin(&(tmr.min));
min++;
min %= 60;
bin1bcd(8, &(tmr.hour));
bin1bcd(min, &(tmr.min));
bin1bcd(43, &(tmr.sec));
"- %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);
printf("\nPress any key...");
getch();
if(tempCh == '2')
break;
} while(1);
timer(RTC_CLEAR_ALARM, &tmr);
_dos_setvect(0x4a, old_4a);
return 0;
// Преобразование однобайтового
// Преобразование двухбайтового
return( bcd1bin(bcd) +
100 * bcd1bin(bcd + 1) );
}
// Преобразование однобайтового
int i;
i = bin / 10;
int i;
tm_sound(mary[i], del[i]);
int cnt;
outp(0x43, 0xb6);
// на вход громкоговорителя
delay(time*1000);
// Выключаем громкоговоритель.
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;