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

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

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



§ 55. Управление COM портом внешним устройством

Иванов Дмитрий, Декабрь 2006
Статья обновлена 28 Мая 2014

Продолжаем работать с COM портом. В этой статье мы поговорим о том, как можно снаружи управлять этим портом, т.е. записывать в него данные снаружи (через внешнее устройство) и анализировать состояние порта в программе. Обращаю внимание, что пока мы работаем без USART`а (см. ранее) и будем управлять только линиями взаимодействия.


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


  • CTS - Готовность к передаче. Линия взаимодействия, с помощью которой внешнее устройство сообщает компьютеру, что оно готово к передаче данных.
  • DSR - Готовность внешнего устройства. Линия взаимодействия, с помощью которой внешнее устройство сообщает компьютеру, что оно включено и готово к связи.

А вот ее практичекая реализация. Как видно, у меня ключ выполнен в виде простой перемычки. Когда перемычка соединена с землей, на соответствующей линии устанавливается низкий уровень напряжения, когда разъеденена - высокий.


Теперь напишем программу, которая будет считывать соостояние этих линий и отображать какой уровень напряжения сейчас на них установлен. Для этого создаем новый проект MFC и указываем ему имя, например, TestCOM. Далее выбираем вариант построения на основе диалога.

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

Теперь надо создать переменные для Edit-окошек. Для этого выбирайте в главном меню пункт View - > ClassWizard. В открывшемся окне перейдите на вкладку Member Variables. Если в списке Class Name установлен не CTestCOMDlg то выбирите его. В списке просмотра Control IDs выделите идентификатор первого Edit-окна IDC_EDIT (если Вы не изменяли это имя). Нажимайте книпку Add Variable. В открывшемся окне в поле Member Variable Name введите m_CTS (например, такое имя для окна, показывающее состояние линии CTS), в списке Category - Value, а в списке Variable Type тип int. Нажмите Ok.

Аналогично проделываем ту же операцию для окошка, связанного с линией DSR, только назовите переменную как m_DSR.

Далее, в файле TestCOMDlg.h в описание класса диалога добавьте строчку: HANDLE hFile;.

class CTestCOMDlg : public CDialog
{
// Construction
public:
	CTestCOMDlg(CWnd* pParent = NULL);	// standard constructor	
	HANDLE hFile;

Абсолютно аналогично с предыдущей статьей этого раздела, добавляем код который открывает порт при загрузке программы. В итоге, функция OnInitDialog(), расположенная в файле TestCOMDlg.cpp, класса нашего диалога должна принять вид:

BOOL CTestCOMDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	..................
	
	// TODO: Add extra initialization here

	hFile = CreateFile("COM2", GENERIC_READ|GENERIC_WRITE, 0, NULL,
	    OPEN_EXISTING, 0,NULL);

	if(hFile==INVALID_HANDLE_VALUE)
	{
		MessageBox("Не удалось открыть порт!", "Ошибка", MB_ICONERROR);
	}
	else
	{
		MessageBox("Порт успешно открыт", "Ok", MB_OK);
	}
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

Еще раз обращаю внимание на номер открываемого порта. Побробнее об этом написано в предыдущей статье.

А теперь займемся самым интересным - функцией, которая анализирует состояния линий. Для этого создайте функцию-обработчик на кнопку Read (так ее обозвал я) двойным щелчком на нее, и назовите ее, например, OnRead. Добавьте в нее следующий код:

void CTestCOMDlg::OnRead() 
{
	// TODO: Add your control notification handler code here

	ULONG ul=0;

	if(GetCommModemStatus(hFile, &ul)!=0)
	{		
		if(ul == 0x10)
		{
			m_CTS = 1;
			m_DSR = 0;
		}

		if(ul == 0x20)
		{
			m_CTS = 0;
			m_DSR = 1;
		}

		if(ul == 0x30)
		{
			m_CTS = 1;
			m_DSR = 1;
		}

		if(ul == 0x00)
		{
			m_CTS = 0;
			m_DSR = 0;
		}		

		UpdateData(false);
	}		
}

С помощью стандартной Win API функции GetCommModemStatus() проводится считывание состояний линий управления COM порта. Ей передается два параметра - первый, это HANDLE на открытый порт, второй - адрес на переменную, в которую будет помещено числовое значение, характерезующее состояние линий. Далее, если вызов функции был удачным, проводится анализ этой переменной с назначением в переменные Edit-окошек нуля или еденицы в соответствие с тем, какой уровень напряжения был на линии. В конце с помощью функции UpdateData() проводится обновление информации в Edit-окнах.

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



© Иванов Дмитрий
Декабрь 2006
http://www.kernelchip.ru



© KERNELCHIP 2006 - 2017