PDA

Просмотр полной версии : Работа с памятью в макросах



Aleksandr
25.06.2018, 19:48
Добрый день. Начинаю осваивать макросы, появилось несколько вопросов:

Будет ли работать конструкция
Write (HMI_LOCAL_MCH, 0, TYPE_PFW, 260, 0, TYPE_WORD, PSW[1059]);
Интересует именно регистр PSW запишется ли он напрямую в регистр PFW? компилятор при этом не ругается.Или лучше использовать промежуточную переменную?
С PFW уже ругается
Write (HMI_LOCAL_MCH, 0, TYPE_PFW, 260, 0, TYPE_WORD, PFW[1059]); , т.е. напрямую из PFW в PFW уже не получится?

В тоже время функцией Writes регистры PSW в PFW напрямую не записать ?
Writes (HMI_LOCAL_MCH, 0, TYPE_PFW, 500, 6, PSW[30]);

Евгений Кислов
25.06.2018, 19:58
1.1. Будет.
1.2. Не получится.
2. Получится, см. пост Petera ниже.

Посмотрите вот этот пример:
http://www.owen.ru/uploads/example_macromemory_v2.zip

Там в глобальном макросе подготовлены функции, которые упрощают работу с памятью, а в пользовательском макросе - пример их применения.

petera
26.06.2018, 06:54
Добрый день. Начинаю осваивать макросы, появилось несколько вопросов:

Будет ли работать конструкция
Write (HMI_LOCAL_MCH, 0, TYPE_PFW, 260, 0, TYPE_WORD, PSW[1059]);
Интересует именно регистр PSW запишется ли он напрямую в регистр PFW? компилятор при этом не ругается.Или лучше использовать промежуточную переменную?
С PFW уже ругается
Write (HMI_LOCAL_MCH, 0, TYPE_PFW, 260, 0, TYPE_WORD, PFW[1059]); , т.е. напрямую из PFW в PFW уже не получится?

В тоже время функцией Writes регистры PSW в PFW напрямую не записать ?
Writes (HMI_LOCAL_MCH, 0, TYPE_PFW, 500, 6, PSW[30]);



По поводу п.2
Достаточно использовать & перед адресом PSW (использовать указатель на адрес первого элемента массива из 6 регистров PSW)
т.е. такая запись
Writes(HMI_LOCAL_MCH, 0, TYPE_PFW, 500, 6, &PSW[30]);
будет работать

Евгений Кислов
26.06.2018, 07:00
Справедливо, спасибо за замечание, Petera.

SokolovS
26.06.2018, 08:08
1.1. Будет.
1.2. Не получится.
2. Получится, см. пост Petera ниже.

Посмотрите вот этот пример:
http://www.owen.ru/uploads/example_macromemory_v2.zip

Там в глобальном макросе подготовлены функции, которые упрощают работу с памятью, а в пользовательском макросе - пример их применения.

А почему в Copys не используете Reads/Writes? Это гораздо эффективнее должно быть
Для PSB можно массив PSB использовать, тоже будет быстрее, но несколько сложнее реализовать

Евгений Кислов
26.06.2018, 10:20
Выигрыш в эффективности будет сложно заметить (в контексте задач панели). Даже копирование 10к регистров через цикл укладывается в 100-200 мс.
Но, согласен, для PSW корректнее было бы сделать с Writes - так, по крайней мере, было бы компактнее и проще.

petera
26.06.2018, 10:37
Выигрыш в эффективности будет сложно заметить (в контексте задач панели). Даже копирование 10к регистров через цикл укладывается в 100-200 мс.
Но, согласен, для PSW корректнее было бы сделать с Writes - так, по крайней мере, было бы компактнее и проще.

Еще компактней и проще в Copys или вместо ее использовать стандартную сишную функцию memcpy()

например скопировать тридцать пять PSB
memcpy(&PSB[300], &PSB[500], 35); // PSB[300+i]=PSB[500+i], where i=0..34

SokolovS
26.06.2018, 10:42
Еще компактней и проще в Copys или вместо ее использовать стандартную сишную функцию memcpy()

например скопировать тридцать пять PSB
memcpy(&PSB[300], &PSB[500], 35); // PSB[300+i]=PSB[500+i], where i=0..34

С PSB аккуратнее, это байтовый массив, в каждом элементе которого хранится состояние восьми PSB

// PSB
#define BITS_PER_BYTE 8
#define GetPSBStatus( PSB_No ) ( ( PSB[ (PSB_No) / BITS_PER_BYTE ] & ( 1 << ( (PSB_No) % BITS_PER_BYTE ) ) ) != 0 )
#define SetPSB( PSB_No ) PSB[ (PSB_No) / BITS_PER_BYTE ] |= ( 1 << ( (PSB_No) % BITS_PER_BYTE ) )
#define ResetPSB( PSB_No ) PSB[ (PSB_No) / BITS_PER_BYTE ] &= ( ~ ( 1 << ( (PSB_No) % BITS_PER_BYTE ) ) )

(из Lib.h)