PDA

Просмотр полной версии : Помогите начинающему пользователю среды програмированния CoDeSys 2.3



Fudz
17.07.2012, 16:25
Здравствуйте. Возникли трудности с написанием программы. Задача в следующем. есть массив данных количество элементов 52 типа байт. Этот массив отправляется по UDP. Нужно сохранить 200 предыдущих состояний этого пакета данных и сделать так что бы самый старый пакет удалялся когда отправляется самый новый. С формированием массива и отправкой по UDP вроде как бы разобрался, а вот с листингом даже не знаю с какой стороны подойти.

capzap
17.07.2012, 18:46
ищите библиотеку oscat и в ней посмотрите реализация stack

Fudz
17.07.2012, 22:57
да прикольная идея но там максимальный стек в 32 ячейки в каждую ячейку можно записать данные типа DWORD => на 32 ячейки 128 байт у меня UDP пакет 52байта => я смогу записать всего лишь 2 пакета, а множить стек еще сто раз не хочется. Или можно увеличить количество ячеек???

Yegor
18.07.2012, 06:22
Нужен всего-навсего кольцевой буфер, состоящий из двухмерного массива (ARRAY [0..199] OF ARRAY [0..51] OF BYTE), индекса головы и переменной размера.

capzap
18.07.2012, 06:34
да прикольная идея но там максимальный стек в 32 ячейки в каждую ячейку можно записать данные типа DWORD => на 32 ячейки 128 байт у меня UDP пакет 52байта => я смогу записать всего лишь 2 пакета, а множить стек еще сто раз не хочется. Или можно увеличить количество ячеек???

Я предложил не готовый пример, а посмотреть сам принцип. Размер стека можно увеличить, вместо DWORD использовать структуру из 52 байт. Сложно конечно, но зато отработано. А с массивами, один неверный шаг и плк уйдет в стоп из-за "злой собаки"

Fudz
18.07.2012, 10:18
А не могли бы вы примерно показать как это сделать???

Yegor
18.07.2012, 12:06
Что, кольцевой буфер? Пфф...
VAR
crbuf, plainbuf: ARRAY[0..199] OF TIME;
count, i: DINT;
END_VAR

(* Запись *)
crbuf[count MOD 200] := TIME();
count := count + 1;

(* Чтение *)
FOR i := 0 TO 199 DO
plainbuf[i] := crbuf[(count + i) MOD 200];
END_FOR

Fudz
18.07.2012, 13:49
Спс за пример )) ноя не о кольцевом буфере, а о ..


Размер стека можно увеличить, вместо DWORD использовать структуру из 52 байт.

capzap
18.07.2012, 15:21
у меня на телефоне не установлена КДС, да если бы была то размер экраны "выбесил" бы :)
Пока попытайтесь воссоздать вариант с массивом, единственно надо поправить, чтоб сам DINT обнулился раньше чем закончиться его нумерация, примерно при 2147483599 чтоб следущее стало равно нулю. А то неувязочка выйдет с пропажей данных

capzap
18.07.2012, 15:44
http://www.kipshop.ru/CoDeSys/steps/codesys_v23_ru.pdf ищите пункт Пользовательские типы данных, там расписано как создается структура, в FIFO меняете константу на 200, а вместо переменной
fifo : ARRAY[0..n] OF DWORD;
пишите
fifo : ARRAY[0..n] OF STRUC;
где STRUC это созданная структура из 52 байт, причем каждому байту можно дать запоминающееся имя, а не безликий индекс массива :)

Fudz
19.07.2012, 11:26
О, ну да как я мог забыть. СПС буду пробовать.

Fudz
06.08.2012, 15:01
Появился новый вопрос. В данный момент осваиваю работу с датой и временем. Не могли бы вы подсказать как преобразовать например минуты в байт? Пользуюсь библиотекой SysLibTime.

S.A.D.
06.08.2012, 15:26
Если я правильно понял то вот:

SYST:SystemTimeDate; *Объявляем экземпляр ФБ системного времени*
X:BYTE;
_________________________________

X:=UINT_TO_BYTE(SYST.Minute);

Fudz
06.08.2012, 15:42
Да правильно но я так уже пробовал результат X=0;

Fudz
06.08.2012, 16:06
ПРИМЕР ПРОГРАММЫ

PROGRAM TIME_PLC
VAR
GetTime: CurTimeEx;
TimeAndDate: SystemTimeDate;
Sys_Time: SysTime64;
set_time: BOOL;
set_date: BOOL;
MM: UINT;
SS: UINT;
HH: UINT;
D: UINT;
M: UINT;
Y: UINT;

X:BYTE;
END_VAR

(*Текущее время*)
TimeAndDate.Day :=0;

TimeAndDate.DayOfWeek :=0;
TimeAndDate.dwHighMsec :=0;
TimeAndDate.dwLowMSecs :=0;
TimeAndDate.Milliseconds :=0;
TimeAndDate.Minute:=0;


X:=UINT_TO_BYTE(TimeAndDate.Minute);

TimeAndDate.Second :=0;

TimeAndDate.Hour :=0;

TimeAndDate.Year :=0;

TimeAndDate.Month :=0;

Sys_time.ulHigh :=0;

Sys_time.ulLow :=0;

GetTime (SystemTime:=Sys_Time , TimeDate:= TimeAndDate);

(*Если set_time - истина, то можно менять время*)

IF set_time THEN

TimeAndDate.Minute:=MM;
TimeAndDate.Second:=SS;
TimeAndDate.Hour:=HH;
GetTime (SystemTime:=Sys_Time , TimeDate:= TimeAndDate);

END_IF

(*Если set_date - истина, то можно менять дату*)

IF set_date THEN

TimeAndDate.Day:=D;
TimeAndDate.Month:=M;
TimeAndDate.Year:=Y;
GetTime (SystemTime:=Sys_Time , TimeDate:= TimeAndDate);

END_IF

Fudz
06.08.2012, 16:10
все проблему решил ........)))