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

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

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



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

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

Файлы к статье скачать

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


Надеюсь, уважаемые читатели, Вы позволите мне не рассматривать пошагово весь процесс создания проекта, ведь техника создания проекта в 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	
}

Наконец, рассмотрим код обработчика таймера. При каждом срабатывании, пытаемся прочесть 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 порты, можно пересылать данные между ними (по одному байту).



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



© KERNELCHIP 2006 - 2017