Реалізація протоколу 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 слів прийнято і передано і жодної помилки. :)
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.