Сценарий WinCC c читает биты из слова - общие предложения C
У меня огромная проблема, и я предполагаю, что причина того, что она не функционирует должным образом, заключается в моих знаниях языка Си, которые, в лучшем случае, давайте посмотрим правде в глаза...
void * KT_Indirect_CNS(int NumCNS, char *CNSDescr[], char *CNSTag[], int *CNSIsBit[], char* lpszPictureName){
#include "apdefap.h"
char TagNameEnable[255],
TagNameTrue[255],
TagNameFalse[255],
TagNameString[255],
TagNameCNS[255],
TagNameCNSString[255],
TagNameTemp[255];
int i,
count;
typedef struct
{
LONG x;
LONG y;
} tPOINT;
#pragma code ("user32.dll");
BOOL GetCursorPos( tPOINT* lpPoint);
#pragma code();
tPOINT pt;
GetCursorPos(&pt);
for (i=1; i<=NumCNS; i++)
{
sprintf(TagNameEnable, "CNS%d.Enabled", i);
SetTagBit(TagNameEnable, 1);
sprintf(TagNameCNS, CNSTag[i-1]);
sprintf(TagNameTrue, "CNS%d.True", i);
sprintf(TagNameFalse, "CNS%d.False", i);
if (CNSIsBit[i-1] == 17)
{
BOOL temp = GetTagBit(TagNameCNS);
if (temp==1)
{
SetTagBit(TagNameTrue, 1);
SetTagBit(TagNameFalse, 0);
count++;
}
else
{
SetTagBit(TagNameTrue, 0);
SetTagBit(TagNameFalse, 1);
}
}
if ((CNSIsBit[i-1] >= 0) && (CNSIsBit[i-1] <=16))
{
int *bits = GetBitsFromWord(GetTagWord(TagNameCNS));
int index = (int)CNSIsBit[i-1];
if (bits[index]==1)
{
SetTagBit(TagNameTrue, 1);
SetTagBit(TagNameFalse, 0);
count++;
}
if (bits[index]==0)
{
SetTagBit(TagNameTrue, 0);
SetTagBit(TagNameFalse, 1);
}
}
sprintf(TagNameString, "CNS%d.String", i);
SetTagChar(TagNameString, CNSDescr[i-1]);
}
if (NumCNS <16)
{
for (i=NumCNS+1; i<=16; i++)
{
sprintf(TagNameTrue, "CNS%d.True", i);
sprintf(TagNameFalse, "CNS%d.False", i);
sprintf(TagNameEnable, "CNS%d.Enabled", i);
SetTagBit(TagNameTrue, 0);
SetTagBit(TagNameFalse, 0);
SetTagBit(TagNameEnable, 0);
}
}
if (count != NumCNS)
{
sprintf(TagNameTemp, "CNS_Page_AllGood");
SetTagBit(TagNameTemp, 0);
SetVisible(lpszPictureName,"KT_CNS",TRUE);
sprintf(TagNameTemp, "CNS_PAGE_MOUSE_X");
SetTagSWord(TagNameTemp, pt.x-5);
sprintf(TagNameTemp, "CNS_PAGE_MOUSE_Y");
SetTagSWord(TagNameTemp, pt.y-150);
sprintf(TagNameTemp, "CNS_PAGE_HEIGHT");
SetTagSWord(TagNameTemp, 30*NumCNS);
}
if (count == NumCNS)
{
sprintf(TagNameTemp, "CNS_Page_AllGood");
SetTagBit(TagNameTemp, 1);
}
return ("Controller Initilized");}
int *GetBitsFromWord(WORD _word){
int bits[16];
bits[0] = (_word & 0x0001)?1:0;
bits[1] = (_word & 0x0002)?1:0;
bits[2] = (_word & 0x0004)?1:0;
bits[3] = (_word & 0x0008)?1:0;
bits[4] = (_word & 0x0010)?1:0;
bits[5] = (_word & 0x0020)?1:0;
bits[6] = (_word & 0x0040)?1:0;
bits[7] = (_word & 0x0080)?1:0;
bits[8] = (_word & 0x0100)?1:0;
bits[9] = (_word & 0x0200)?1:0;
bits[10] = (_word & 0x0400)?1:0;
bits[11] = (_word & 0x0800)?1:0;
bits[12] = (_word & 0x1000)?1:0;
bits[13] = (_word & 0x2000)?1:0;
bits[14] = (_word & 0x4000)?1:0;
bits[15] = (_word & 0x8000)?1:0;
return bits;}
Это сценарии, которые я использую для сбора общих не работающих причин для устройств на заводе... Я предполагал, что это работало, когда я проверял это, глупо я бы добавил... Я думаю, что мои знания об использовании указателя достаточно низки, чтобы сделать Я думаю, это ошибка, которая убьет меня... По сути, мне нужно собрать данные типа WORD (16-битные) из моего ПЛК (s7-400), и мне нужно использовать биты из указанного слова, чтобы определить состояние объектов на экран в WinCC. Дело в том, что я не получаю ожидаемых значений... Он компилируется без проблем, но... У кого-то есть предложения? Как я могу улучшить свой код?
1 ответ
О, мальчик, несколько замечаний по улучшению кода и, возможно, по решению вашей проблемы:
Вы делаете включение внутри функции. Это плохая практика. Затем вы определяете typedef
внутри функции и имеют прагму и прототип. Настоятельно рекомендуется сделать это до запуска функции, поэтому:
#include "apdefap.h"
typedef struct
{
LONG x;
LONG y;
} tPOINT;
#pragma code ("user32.dll");
BOOL GetCursorPos( tPOINT* lpPoint);
#pragma code();
void * KT_Indirect_CNS(int NumCNS, char *CNSDescr[], char *CNSTag[], int *CNSIsBit[], char* lpszPictureName)
{
char TagNameEnable[255],
TagNameTrue[255],
TagNameFalse[255],
TagNameString[255],
TagNameCNS[255],
TagNameCNSString[255],
TagNameTemp[255];
int i, count;
//...
}
В вашем цикле for (i=1; i<=NumCNS; i++)
вы начинаете с 1. В C все индексы начинаются с 0. В остальной части кода я не вижу убедительной причины начинать с 1, поэтому просто начните с нуля: for (i=0; i<NumCNS; i++)
Однако, это не так, что вы делаете.
Но твой GetBitsFromWord
действительно есть проблема. Внутри этой функции вы объявляете массив int bits[16]
и в конце функции вы возвращаете этот массив. Но aray - это так называемая автоматическая (локальная) переменная, которая больше не существует, когда функция возвращается (она размещается в стеке, и эта часть освобождается при возврате и может быть перезаписана последующими вызовами функции).
Вместо этого объявите это как void GetBitsFromWord(WORD _word, int bits[16])
и передать массив битов в качестве параметра от вызывающей стороны.