Итак,
for Frame use
record
Transaction_Id at 0 range 0 .. 15;
Protocol_Id at 2 range 0 .. 15;
Frame_Length at 4 range 0 .. 15;
Unit_id at 6 range 0 .. 7;
Function_Code at 7 range 0 .. 6;
Is_Exception at 7 range 7 .. 7;
end record;
Кажется, вы хотите, чтобы Is_Exception был младшим битом последнего байта?При for Frame'Bit_Order use System.High_Order_First;
младший бит будет равен 7,
(также 16#32#
никогда не будет -- Big endian version of 16#4#
, битовая комбинация просто не совпадает)
Может быть более интуитивно понятными ясно, чтобы указать все ваши поля относительно слова, в котором они находятся, а не байта:
Unit_ID at 6 range 0..7;
Function_Code at 6 range 8 .. 14;
Is_Exception at 6 range 15 .. 15;
Учитывая приведенное выше определение Command
, допустимыми значениями для последнего байта будут:
- 2 -> READ_COILS FALSE
- 3 -> READ_COILS TRUE
- 8 -> READ_DISCRETE_INPUTS FALSE
- 9 -> READ_DISCRETE_INPUTS*
Кстати, применив ваше обновление к исходной программе и добавив / изменив следующее, ваша программа работает для меня
add
with Interfaces;
add
type Byte_Array is array(1..8) of Byte with Pack;
изменить, поскольку мы не знаем определение
Transaction_ID : Interfaces.Unsigned_16;
Protocol_ID : Interfaces.Unsigned_16;
Frame_Length : Interfaces.Unsigned_16;
Unit_ID : Interfaces.Unsigned_8;
изменить
function To_Frame is new Ada.Unchecked_Conversion (Byte_Array, Frame);
изменить
my_frame := To_Frame (Byte_Array'(00, 01, 00, 00, 00, 09, 16#11#, 16#9#));