Реализация протокола MIL-STD-1553 на STM32

Однажды, появилась необходимость использования в нашем устройстве мультиплексного канала обмена информацией (МКИО), он же ГОСТ Р 52070–2003, он же MIL-STD-1553В. Первоначальный результат поисков несколько удивил: типовые решения выдаваемые поисковой системой, как правило, основывались на использовании ПЛИС. Поскольку решать проблему нужно было быстро, появилась мысль сделать конвертер протокола из MIL-STD-1553 в MODBUS RTU. При этом постараться использовать достаточно недорогие технические решения и микроконтроллер из семейства STM32.

7b67469d91c44efa94a307ee42e82202.jpg

На фото из Википедии: F16, на котором впервые был использована шина MIL-STD-1553В. Наши устройства не летают :), поэтому каких либо ограничений по применению элементной базы нет. Просто у Заказчика приборная сеть построена на основе этой шины. Первая часть статьи описывает прием и передачу по шине МКИО, вторая часть будет про конвертер в MODBUS.

Первый этап любой разработки: поиск информации и чтение документации. После этого этапа в голове сложилось следующее:

— протокол достаточно прост :)
 — максимальный кадр 32 байта :)
 — имеет довольно жесткий тайминг :(
 — довольно дорогие микросхемы и модули :(

После некоторых размышлений остановился на использовании кодера — декодера HI-15530, фирмы HOLT, однако аналогов у это микросхемы достаточно много. Правда не все могут быть доступны в России за разумные деньги и сроки. :)

Вот примерная схема включения этой микросхемы. Правда взята из даташита аналога. :)

23ed4e5f76bd475180b00cca6691fc74.jpg

Дальше все просто :) Подключаем к портам микропроцессора 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 фирмы ЕЛКУС.

dc05e44d44a84994b4bc30beb8a7b9bc.jpg

Добавился еще один сигнал управления ST (Включение передатчика)

Получилась вот такая плата.

eda46d0b54474c2aa797b6309f8c0c02.jpg

Началась отладка программного обеспечения. Для имитации обмена данных с каналом был приобретен USB модуль у компании «Модуль», который может быть, как оконечным устройством (ОУ), так и контроллером шины (КШ).

f58b48e060ef42419fd7b9e5f6660d4f.jpg

К модулю прилагается программа управления 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;    
}

И вот результат.

1fb59361eeef43feb16c47bee26c0a8c.jpg

Аббревиатуры ОУКШ и КШОУ означают, соответственно: оконечное устройство — контроллеру шины, контроллер шины — оконечному устройству. То есть в первом случае запрос на передачу данных от ОУ, а во втором передача данных оконечному устройству. И в том, и другом случае передается по 31 слову. Более 10000 слов принято и передано и ни одной ошибки. :)

Комментарии (3)

  • 29 ноября 2016 в 16:06

    0

    Заметно, что вы старались использовать отечественную элементную базу. Но почему не стали использовать микроконтроллеры от Миландра, у них и поддержка MIL-STD-1553 есть?
    • 29 ноября 2016 в 16:16

      0

      Их продукцию тоже рассматривал. Вот такой чип нашел 1986ВЕ1Т, с поддержкой MIL-STD-1553. Но поиск по Efind выдал, что стоит он около 20 000=, отладочная плата от 80 000=. Как то не очень бюджетно получается. Они прежде всего ориентированы на то, что летает. Соответственно и корпуса и приемка очень не дешевые. А мне нужно было именно бюджетное решение.
  • 29 ноября 2016 в 16:32

    0

    Программа приема и передачи получилась достаточно простой.

    Протокол реализован частично, нет даже обработки ошибок.

© Habrahabr.ru