Интернет-магазин

Просмотр корзины
В корзине:

товаров - 0 шт.



§ 8. Применение таймеров для работы с портами

Дмитрий Иванов, 15 Января 2007
Статья доработана и обновлена 22 Января 2012


Новерное, как только у Вас получилось "зажигать" и "тушить" светодиоды в LPT порту, сразу же появились мысли: "а нельзя ли записывать или считывать данные из порта с определенным временным интервалом, да к тому же желательно чтоб он был минимальным".


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

Итак, запускаем Microsoft Visual C++ 6.0 и создаем новый MFC проект с именем, например, LPTTimer.

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

Придайте окну диалога вид, показанный на рис. ниже. Уберите от туда созданные по умолчанию текстовую строчку "TODO: ..." и кнопку Cancel. Кнопку "Ok" переименуюйте, например, в "Exit". Добавьте еще две кнопки и дайте им названия Start Timer и Stop Timer.

Содадим обработчик на нажатие кнопки Start Timer. Для этого два раза щщелкните на нее. Появится окно с возможностью изменить имя функции. Задайте имя OnStartTimer. Проделайте аналогичную операцию и для второй кнопки. В качестве имени задайте OnStopTimer.

Далее добавьте к проекту все необходимые файлы для работы с библиотекой inpout32.dll. Если забыли как это сделать или первый раз про нее слышите, посмотрите предыдущие статьи этого раздела - там все хорошо расписано.

Теперь допишем тело функуии OnStartTimer(). Как видно из кода, сначала мы записываем в регистр DATA LPT порта число 0, т.е. тушим все светодиоды, подключенные к нему (предполагается, что у Вас к порту подключено какое-нибудь устройство для визуального наблюдения за его состоянием). А вот далее идет вызов не знакомой нам Windows функции SetTimer(). Что она делает? Происходит следующее: вызвав ее с такими параметрами как здесь мы говорим Windows - пожалуйста, каждые 500 мс (миллисекунд) передавай управление на спецализированный обработчик в нашей программе. Первый параметр - это идентификатор таймера (может потребоваться, если мы с своей программе создадим несколько таймеров). Представляет из себя просто целое положительное число, большее нуля. Воторой параметр - это период срабатывания таймера в миллисекундах. Третий - адрес на нашу собственную функцию обработчик, куда Windows передаст управление при срабатывании таймера. Мы здесь будем использовать стандартный Windows обработчик, поэтому передаем NULL.

void CLPTTimerDlg::OnStartTimer() 
{
	// TODO: Add your control notification handler code here
	Out32(0x378, 0);
	SetTimer(1, 500, NULL);	
}

Давайте определим этот самый обработчик таймера. Для этого заходим в пункт меню View->ClassWizard. Выбираем в разделе "Message Maps" в списке "Object IDs" пункт CLPTTimerDlg. В списке "Messages" выбираем пункт WM_TIMER и нажимаем кнопку Add Function затем Edit Code.

Нас перенесет к заготовке функции OnTimer(). Именно на нее будет переходить управление при каждом срабатывании таймера. В качестве параметра ей передается переменная nIDEvent, которая содержит идентификатор таймера. В нашем случае она будет равна 1 (т.к. других таймеров мы не создавали). Что мы будем делать при срабатывании таймера? Сначала прочтем содержимое регистра DATA а потом запишем его же, но проинвертировав. В результате, если в порту все биты были 0 то станут 1 и наоборот. В итоге, светодиоды начнут мигать с частотой 2 Гц.

void CLPTTimerDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	BYTE c=Inp32(0x378);
	Out32(0x378, ~c);	
	CDialog::OnTimer(nIDEvent);
}

Теперь немного допишем код функции OnStopTimer(). Единственное что мы сделаем, так это вызовем функциию KillTimer(). Я думаю, ее функциональное назначение вполне очевидно - она удалит таймер с идентификатором 1. При этом, соответственно, светодиоды мигать перестанут.

void CLPTTimerDlg::OnStopTimer() 
{
	// TODO: Add your control notification handler code here
	KillTimer(1);	
}


© Дмитрий Иванов
15 Января 2007
http://www.kernelchip.ru



© KERNELCHIP 2006 - 2024