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

от автора

Однажды, появилась необходимость использования в нашем устройстве мультиплексного канала обмена информацией (МКИО), он же ГОСТ Р 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *