СОПРЯЖЕНИЕ КОМПЬЮТЕРОВ С ВНЕШНИМИ УСТРОЙСТВАМИ

Яндекс цитирования

Друзья ресурса:

www.roboforum.ru



Спряжение PIC16F877 с ПК через COM порт (Часть 2).

Файлы к статье (размер: 173 КБ)

Вот мы и добрались до второй части статьи по сопряжению ПК с контроллером через COM порт. Сейчас мы напишем приложение под Windows на языке C++ на основе MFC в среде разработки Microsoft Visual C++ 6.0 для обмена информацией с контроллером через COM порт. Для программирования порта будем использовать библиотеку SerialGate.dll.

сопряжение компьютера и микроконтроллера через COM порт

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

На рис. выше показан интерфейс этой программы. Он вполне очевиден. У нас есть два окошка ввода для указания параметров порта для открытия: его номер и скорость. Насколько Вы помните, в прошивке контроллера мы используем скорость 9600, соответственно, для работы с нашим контроллером мы должны указать именно эту скорость. Для открытия порта используется кнопка OpenPort >>. Далее мы можем отправить число в контроллер, которое он отобразит на своих светодиодах. Для этого предназначены соответствующее окошко ввода и кнопка Write.

Также, как Вы помните из прошлой статьи, мы решили тестировать и передачу данных от контроллера в ПК. Для этого мы договорились, что если в контроллер придет число 100, то он отправит в ПК состояние одного из своих портов. Для отображения этих данных предназначено последнее окошко ввода. Чтение данных из порта будет осуществлять по таймеру. Т.е. с определенным (но выбираемым произвольно) периодом будем пытаться прочесть данные из порта. Наверное лучше посмотреть код программы, тогда все статнет немного понятнее. Дававйте по порядку. Сначала рассмотрим код функции по нажатию на кнопку открытия порта.

void CCOM_PICDlg::OnOpenPort() 
{
	// TODO: Add your control notification handler code here

	UpdateData(true);	

	if(m_baud == 0 || m_com == 0 )
	{
		MessageBox("Bad params", "Error", MB_ICONERROR);
		return;;
	}

	bool b = sg.Open(m_com, m_baud);
	if(b == true)
	{
		MessageBox("Port open Ok!", "Info", MB_ICONINFORMATION);

		SetTimer(1, 500, NULL); // set timer for 0.5 sec
	}
	else
	{
		MessageBox("Port open ERROR", "Info", MB_ICONERROR);
	}	
}

Тут проводится уже стандартная последовательность действий. С помощью UpdateData() в переменные ассоциированные с окошками ввода перемещаем введенные данные. Далее проводим самую простенькую проверку на корректность введенных данных. Если все в порядке, пытаемся открыть доступ к порту с помощью экземпляра класса SerialGate sg (объявлен в описании класса диалога). В зависимости отрезультата выводим соответствующее сособщение. Также, если порт открыли успешно, запускаем таймер с идентификатором 1 и периодом срабатывания 500 мс.

Теперь посмотрим на участок кода, отрабатывающий по нажатию на кнопку Write. Он совсем уже прост. С помощью UpdateData() получаем данные из окошка ввода (с ним ассоциированна переменная m_write). В переменную data помещаем данные которые нужно отправить и делаем это с помощью метода Send(), передавая ему (методу) адрес на буфер в котором находятся данные и сколько байт данных из этого буфера нужно передать.

void CCOM_PICDlg::OnWrite() 
{
	// TODO: Add your control notification handler code here

	UpdateData(true);	

	char data = m_write;

	sg.Send(&data, 1); // 1 byte to send	
}

Тот кто знаком С/С++ получше, наверное зададут вопрос - а зачем вообще нужна эта переменная data, когда можно было просто в функцию Send() сразу передать m_write? Согласен, что только так и нужно делать, я просто не хотел загромождать код преобразованиями типов указателей, не совсем понятных для новичков в данном языке. Если сделать все как нужно, то последние две строчки тела этой функции должны выглядеть вот так:

sg.Send((char*)&m_write, 1); // 1 byte to send	

Дело в том, что Send() требует в качестве первого параметра указактель на char, в то время как m_write имеет тип int. Поэтому я и привожу принудительное преобразование типов указателей. Когда же я пишу data = m_write преобразование проводится автоматически. Вот такое вот маленькое отступление в теорию языка Cи.

Наконец, рассмотрим код обработчика таймера. При каждом срабатывании, пытаемся прочесть 1 байт из порта с помощью метода Recv(). Если нам действительно удалось что-то прочесть (число прочтенных байт данных > 0) то полученное число помещаем в нужное окошко ввода и обновляем его содержимое на экране с помощью функции UpdateData() с парамтром false.

void CCOM_PICDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default

	char buf;
	int readCount = sg.Recv(&buf, 1); // 1 byte for read

	if(readCount > 0)
	{
		m_read = (unsigned char)buf;
		UpdateData(false);
	}
	
	CDialog::OnTimer(nIDEvent);
}

Итак, давайте протестируем систему. Надеюсь, контроллер у Вас прошит еще с прошлой статьи и готов к работе. Подаем на него питание, подключаем к COM порту ПК. Запускаем, программу. Указываем нужный порт и скорость в 9600. Открываем порт. Надеюсь, Вы увидели положительное сообщение по поводу открытия. А далее вводим какое-либо число (ну конечно, не большее чем 255) и нажимаем кнопку Write. Это же число, мы должны увидельно на светодиодах, которыми управляет контроллер. Теперь попробуем отправить в контроллер наше магическое число 100. Тут же Вы должны увидеть что в последнем окошке ввода появилась информация по поводу входного порта контроллера (данных на нем). Попробуйте изменять данные на этом порте, замыкая / размыкая ключи подключенные к порту D контроллера. Посылая число 100, можно следить за состоянием порта.

сопряжение компьютера и микроконтроллера через COM порт

Если запустить две таких программы на разных компьютерах (или на одном, как в прошлых статьях), соединенных между собой через COM порты, можно пересылать данные между ними (по одному байту).


© Иванов Д. В.
6 сентября 2007 года
www.pcports.ru




Контакты | Гостевая книга

© 2005-2010 сопряжение компьютеров с внешними устройствами PCPORTS.RU © Иванов Д.В.