Однажды, появилась необходимость использования в нашем устройстве мультиплексного канала обмена информацией (МКИО), он же ГОСТ Р 52070-2003, он же MIL-STD-1553В. Первоначальный результат поисков несколько удивил: типовые решения выдаваемые поисковой системой, как правило, основывались на использовании ПЛИС. Поскольку решать проблему нужно было быстро, появилась мысль сделать конвертер протокола из MIL-STD-1553 в MODBUS RTU. При этом постараться использовать достаточно недорогие технические решения и микроконтроллер из семейства STM32.
На фото из Википедии: F16, на котором впервые был использована шина MIL-STD-1553В. Наши устройства не летают :), поэтому каких либо ограничений по применению элементной базы нет. Просто у Заказчика приборная сеть построена на основе этой шины. Первая часть статьи описывает прием и передачу по шине МКИО, вторая часть будет про конвертер в MODBUS.
Первый этап любой разработки: поиск информации и чтение документации. После этого этапа в голове сложилось следующее:
— протокол достаточно прост 🙂
— максимальный кадр 32 байта 🙂
— имеет довольно жесткий тайминг 🙁
— довольно дорогие микросхемы и модули 🙁
После некоторых размышлений остановился на использовании кодера — декодера HI-15530, фирмы HOLT, однако аналогов у это микросхемы достаточно много. Правда не все могут быть доступны в России за разумные деньги и сроки. 🙂
Вот примерная схема включения этой микросхемы. Правда взята из даташита аналога. 🙂
Дальше все просто 🙂 Подключаем к портам микропроцессора 16 разрядные шины данных: PARALLEL IN и PARALLEL OUT и управляющие сигналы:
— VALID WORD (Принято корректное слово)
— ENCODER ENABLE (Начало передачи слова)
— COMMAND SYNC (Выбор команда/данные)
Вместо регистра 74LS164 пришлось использовать аналог ЭКФ1533ИР8. Кроме этого используются повторители SN74ALS1035 (ЭКФ1533ЛП17) с открытым коллектором для согласования сигналов 3.3В (STM32) до 5В (HI-15530).
После некоторой переписки с производителями и поставщиками был выбран приемо-передачик EL-15N фирмы ЕЛКУС.
Добавился еще один сигнал управления ST (Включение передатчика)
Получилась вот такая плата.
Началась отладка программного обеспечения.
Для имитации обмена данных с каналом был приобретен USB модуль у компании «Модуль»,:) который может быть, как оконечным устройством (ОУ), так и контроллером шины (КШ).
К модулю прилагается программа управления PURUMK.
Программа приема и передачи получилась достаточно простой.
Прием 16 разрядного слова происходит по прерыванию от сигнала VALID WORD:
void EXTI9_5_IRQHandler (void) //Valid Word { Ctrl_LED3_ON EXTI->PR|=0x0040; //Очищаем флаг STD1553_RX_buffer[recieve_count] = GPIOE->IDR; recieve_count++; frame_from_channel = 1; //флаг принятого слова Ctrl_LED3_OFF }
Обработка флага принятого слова.
if (frame_from_channel) { frame_from_channel = 0; switch (Channel_state) { case 0: //обработка командного слова Device_address_recieved = STD1553_RX_buffer[0]; Device_address_recieved = Device_address_recieved >> 11; if (Device_address_recieved == Device_address) //запрос по адресу { Command_recieved = STD1553_RX_buffer[0]; //сохранение команды в буфере Command_recieved = Command_recieved & 0x001F; //выделение команды/количества слов Transmitt_direction = STD1553_RX_buffer[0]; Transmitt_direction = Transmitt_direction & 0x0400; if (Transmitt_direction == 0x0400) //запрос информации в канал { TRANSMITTER_ENABLE_HIGH; //запуск таймера передачи данных TIM5->CR1 |= TIM_CR1_CEN; //Bit 0 CEN: Counter enable TIM5->CNT = Transmitt_word_period; // Answer_word_flag = 1; } else //прием данных из канала { Channel_state = 1; } } else { recieve_count = 0; } break; case 1: //прием данных if (recieve_count == Command_recieved + 1) { //передача ответного слова TRANSMITTER_ENABLE_HIGH; Answer_word_flag = 1; Command_recieved = 0; //запуск передачи TIM5->CR1 |= TIM_CR1_CEN; //Bit 0 CEN: Counter enable TIM5->CNT = Transmitt_word_period; // } break; } //end of switch } //end of if
И собственно передача данных в канал.
Передача каждого слова в канал происходит по прерыванию таймера.
//передача данных по МКИО void TIM5_IRQHandler (void) // { EXTI->IMR &= ~EXTI_IMR_MR6; //DISABLE Interrupt Mask on line 1 if (Answer_word_flag) { SYNC_SELECT_COMMAND; Answer_word_flag = 0; } else { SYNC_SELECT_DATA; } GPIOD->ODR = STD1553_TX_buffer[transmitt_count]; delay(5); ENCODER_ENABLE_HIGH; //запись данных в регистр delay(112); transmitt_count ++; ENCODER_ENABLE_LOW; //начало передачи данных в канал if (transmitt_count > Command_recieved) { delay(700); TIM5->CR1 &= ~TIM_CR1_CEN; //Bit 0 CEN: Counter enable transmitt_count = 0; EXTI->IMR |= EXTI_IMR_MR6; //ENABLE Interrupt Mask on line 1 Channel_state = 0; recieve_count = 0; TRANSMITTER_ENABLE_LOW; } TIM5->SR = 0; TIM5->CNT = 0; }
И вот результат.
Аббревиатуры ОУКШ и КШОУ означают, соответственно: оконечное устройство — контроллеру шины, контроллер шины — оконечному устройству. То есть в первом случае запрос на передачу данных от ОУ, а во втором передача данных оконечному устройству. И в том, и другом случае передается по 31 слову. Более 10000 слов принято и передано и ни одной ошибки. 🙂
ссылка на оригинал статьи https://habrahabr.ru/post/316430/
Добавить комментарий