Работа с ведомым устройством при помощи билиотеки AXLIB


• О проекте
• Обратная связь
• Полезные ссылки
• Полезные программы
• Друзья сайта


Последние комментарии

Алексей: Виртуальный мастер для отладки протокола MHBUS
Хорошо....

Алексей: Виртуальный мастер для отладки протокола MHBUS
Исходник слейва. ...




           

Библиотека для AVR





AXLIB Генератор





Помощь сайту


   
				

Работа с ведомым устройством при помощи билиотеки AXLIB

	
	
	

Дата: 4 Ноября 2015. Автор: Алексей

	
	
Пример работы мастера и два слейва.
Программа виртуальный Мастер для отладки протокола MHBUS.

В данной статье я опишу принцип работы с ведущим устройством воспользовавшись библиотекой AXLIB
Ставлю задачу. Я буду от лица мастера (Терминал) формировать и передавать пакеты Слейву, а он в зависимости от запроса будет мне отвечать. Для визуализации происходящих процессов у ведущего, последний будет их выводить на ЖК дисплей 4х20. Я постараюсь продемонстрировать все возможные варианты запрос-ответов, а именно:

1) Присвоение адреса ведущему при широковещательной передаче по ID устройства.
2) Получение ответа от ведущего устройства с подтверждением присвоения ему адреса.
3) Изменение адреса ведущего устройства по текущему адресу.
4) Подтверждение ведущим изменения адреса на полученный от ведомого.
5) Передача пакета данных и ответ ведущему.
6) Имитация ошибок пакета и получение ведущим сообщения об ошибках от ведомого.

План ясен, действуем. Для тех кто не знаком с работой самого протокола MH-BUS, рекомендую почитать вот эту статью. Если Вы уже знакомы с основными принципами протокола, то начинаем программировать МК. Для теста протокола я решил использовать МК ATmega8A. К МК я подключил ЖК дисплей 4х20 следующим образом:

Ножка МК    Ножка ЖК
------------   -------------
PORTC 0      RS
PORTC 1      E
GND             RW
PORTD 4      PB4
PORTD 5      PB5
PORTD 6      PB6
PORTD 7      PB7

Для связи с терминалом необходимо соединить ПК-RX c МК-TX, а ПК-TX с МК-RX.
Все, со схематикой закончили, переходим к программе. Первым делом настраиваем, как всегда, файл main_init.h

//-------------------------------------------------------------------------
//  Протокол MH-BUS для передачи данных между устройствами
//	Для работы с шиной RS-485 необходимо выбрать порт и пин на данном порту
//	для управления передачей и скорость в БОД.
//
// Также необходимо задать уникальное ID на шине в диапазоне от 1 до 65535
//-------------------------------------------------------------------------

// Раскоментируйте данную строку, если требуется автоматическое
// управление потоком данных драйвера RS-485

//#define MH_BUS_RS485_ON				// Включить потдержку RS-485

// Раскоментируйта данною строку если необходимы функции режима Мастера

//#define MH_BUS_MASTER					// Включить в режиме Мастер

// Раскоментируйта данною строку если необходимы функции режима Слейва

#define MH_BUS_SLAVE					// Включить в режиме Слейв

// Текущие данные необходимы только в режиме Слейв
#if defined(MH_BUS_SLAVE)
	#define MH_BUS_SLAVE_ID	65530U	// Идентификационный номер устройства
#endif
	
#define MH_BUS_USART_BOD        38400		// Скорость обмена 
	
// Текущие данные необходимы только при использовании автоматическим 
// управлением потоком дпнных драйвера RS-485
#if defined(MH_BUS_RS485_ON)
	#define RS_485_DDR	DDRC	// Порт на котором будет выбран пин упраления
	#define RS_485_PORT	PORTC	// Порт на котором будет выбран пин упраления
	#define RS_485_PIN	0   	// Пин управления передачей данных
#endif

#define MH_BUS_RS485_ON Эта строчка отвечает за автоматическое управление потоком данных при подключении микросхемы драйвера RS-485. Для того чтобы мне здесь не распинаться, что это за микросхема и куда нужно подключать выводы, просто отправляю не знающих вот сюда. Я здесь подробно описал как работает шина RS-485 и какое железо необходимо для реализации данной шины у МК.
#define MH_BUS_MASTER Раскомментировав данную строку, можно перевести устройство в режим Мастер. ВАЖНО! Нельзя одновременно использовать оба режима. Либо Мастер, либо Слейв.
#define MH_BUS_SLAVE Раскомментировав данную строку, можно перевести устройство в режим Слейв. ВАЖНО! Нельзя одновременно использовать оба режима. Либо Мастер, либо Слейв. С учетом того что наш МК будет слейвом, то нужно снять комментарий с данной строки.
#define MH_BUS_SLAVE_ID 65530U В этой строке задается ID устройства. Он нужен для поиска устройства при широковещательной передаче если обо всех устройствах мастер знать не знает. То есть если у мастера есть только ID устройств, а адресов нет. Такой принцип сделан для упрощения адресации ведущих устройств. Буковка U в конце ID должна стоять обязательно!
#define MH_BUS_USART_BOD 38400 Скорость в бодах. Должна быть одинаковая как у мастера, так и у слейва.
#define RS_485_DDR DDRC
#define RS_485_PORT PORTC
#define RS_485_PIN 0
Эти строки нужны только для работы с драйвером RS-485. Задают порт и пин который будет подключен к управляющим ножкам драйвера.
После настройки данного файла, переходим к написанию программы. Так... Давайте ка сначала пробежимся по алгоритму. Что за чем у нас будет идти.

1) Проверить на наличие пакета.
2) Если пакет пришел без ошибок, обработать его.
3) Если в пакете задан адрес широковещательной передачи, то проверить не требуется ли заменить адрес ведомого и если требуется, то заменить и ответить об этом ведомому. Если нет команды на замену, то выполнить требуемые действия.
4) Если в пакете указан чужой адрес, то игнорируем пакет.
5) Если адрес в пакете совпадает с нашим, то проверяем команду. Если требуется заменить адрес ведомого, то меняем его и отвечаем об этом ведомому. Если команда требует произвести какие-либо действия, то выполняем их и отвечаем об этом мастеру.

Начнем с простого. Проверка на наличие пакета.

temp = mhbus_read(); // Проверка на наличия полученного пакета

После вызова функции mhbus_read() в переменной temp будет лежать тип состояния. А уже по типу состояния можно определить что у нас на шине.

1) FALSE - ничего не пришло.
2) MH_BUS_OK - Пакет получен. Целостность пакета не нарушена. Команда в разрешенном диапазоне.
3) MH_BUS_START_FAIL - Получен пакет, но при проверке обнаружен битый СТАРТ-БАЙТ.
4) MH_BUS_STOP_FAIL - Получен пакет, но при проверке обнаружен битый СТОП-БАЙТ.
5) MH_BUS_CON_SUM_FAIL - Получен пакет, но при проверке обнаружено не совпадение контрольной суммы.
6) MH_BUS_COM_FAIL - Получен пакет, но при проверке обнаружено значение команды вне разрешенного диапазона.

Нас интересуют лишь первые два. Если приходят последние три состояния, то мы просто об этом говорим в ответном пакете мастеру. Первый ответ говорит о том что к нам никто ничего не прислал, а вот второй ответ говорит о том что пакет получен и проблем с ним не было. Далее проверяем адрес.

// Проверка не совпал ли адрес в пакете с адресом данного устройства
if(MH_BUS_ADD == mhbus_rd_add()) 
// Проверка на передачу пакета при широковещательной передаче
if(MH_BUS_ADD == MH_BUS_ALL_ADD) 

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

if(MH_BUS_COM == MH_BUS_RE_ADD) // Если необходимо изменить адрес

Этой строкой мы проверяем на получение команды по замене адреса и если данная команда пришла, то меняем адрес.

if(mhbus_id()) // Если ID устройства совпало с передаваемым в пакете

В этой строке происходит вызов функции для проверки переданного ID. Данная функция ничего не принимает в качестве аргумента, так как все данные уже есть. Наш ID мы задали в main_init.h, а передаваемый пришел в пакете от ведущего. Далее после проверки на совпадение ID функция вернет либо TRUE, либо FALSE. Соответственно либо совпал, либо нет. Если совпал, то сначала меняем адрес вызвав функцию BYTE mhbus_wr_add(BYTE add), а та в свою очередь возвращает значение либо TRUE, либо MH_BUS_ADD_OVF. Ответ MH_BUS_ADD_OVF говорит о том что адрес на который хочет заменить Мастер вышел за пределы допустимого диапазона, а именно меньше единицы или больше пятидесяти одного.

temp = mhbus_wr_add(MH_BUS_REG);

Именно в переменную temp и заносится ответ этой функции. Далее собираем пакет и отсылаем его Мастеру.

data[0] = MH_BUS_BYTE_1;
data[1] = MH_BUS_BYTE_2;

mhbus_write(MH_BUS_COM, MH_BUS_REG, data);

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

if(MH_BUS_COM == MH_BUS_RE_ADD)

Опять же проверяем на команду смены адреса. Если таковая пришла, то меняем его и возвращаем ответ Мастеру.

mhbus_wr_add(MH_BUS_REG);
mhbus_write(MH_BUS_COM, MH_BUS_REG, data);

Здесь не мешало бы тоже проверить на переполнение, но)))) Так вышло))) Ну и последнее, наш адрес совпал, но команда не по замене адреса. Да просто выполняем ее и говорим об этом Мастеру.

data[0] = 0x2D; // Пример возвращаем запрошенную температуру.

mhbus_write(MH_BUS_COM, MH_BUS_REG, data);

Возврат температуры лишь пример. Вместо data[0] = 0x2D; можно вписать реальный замер температуры и данный код можно считать готовым ведущим датчиком температуры)))

Архив с проектом

Пример работы мастера и два слева.
Программа виртуальный Мастер для отладки протокола MHBUS.

А теперь самое интересное. Видео всего этого безобразия с подробным рассказом как что работает и что для чего нужно.

JW Player goes here



Олег    28.11.15 12:08

Прикольно.

Юрий    28.11.15 14:11

Спасибо! Протокол супер, все запустилось с первого раза. На скорости 9600 работает на ура. Теперь возник вопрос реализации мастера, чтобы опрашивать слейвы по очереди. Есть тема для новой статьи;-). Спасибо.

Алексей    28.11.15 20:35

Ну если это так актуально, то попробую завтра изобразить.

Олег    30.11.15 11:10

Возникла проблема с автоматическим управлением RS-485. При передаче, пакеты обрезаются. Не доходят последние два байта. Что может быть? Пробовал на 9600 и 38400. Всегда два последних байта теряются.

Алексей    30.11.15 17:01

Да, спасибо. Нашел багу и поправил. Теперь управление RS-485 работает как часы.

Олег    30.11.15 23:09

Спасибо, заработало. Присоединяюсь к Юрию и жду продолжения.

Юрий    21.12.15 01:44

Алексей! Ну где же наш мастер на аврке?

Алексей    21.12.15 09:04

Работаю над этим. Даже программатор под студию собрал для удобства. Мастер и один слейв работают как часы, но стоит подключить еще один слейв как один из них через какое-то время падает. Все просмотрел и осциллограф подключал и логический анализатор. Пакеты не пересекаются, а два слейва как-то мешают друг другу. Я просто не хочу выкладывать сырой код.

Евгений    14.10.16 17:41

Алексей, выложи плиз схемку подключения max485 к МК со всеми необходимыми подтяжками, делаю на макетке,, так сказать для проверки

Алексей    14.10.16 17:59

А пожалуйста. Ссылка.




Чтобы вставить ссылку используйте форму вида[url]http://www.адрес.ru[/url][text]текст ссылки[/text]
Чтобы вставить код используйте форму вида[code]код[/code]

Имя:   





  








Вверх


Рейтинг@Mail.ru Яндекс.Метрика