|
아래와 같이 문제가 해결이 된 듯 하네요.
어제 마지막에 말씀해주신 IntToStr로 바꾸라고 하신 거 있죠?
StrToInt로 바꾸니깐 char형으로 전환이 되더군요.( *(Edit5->Text.c_str())와는 달리 결과가 제대로 나옮)
제가 보기엔 어제 말씀 하실때 StrToInt를 IntToStr로 잘못 표기를 하신듯...^^ 감사합니다.
그래서 오늘 아침에 드디어 99% 정도 해결이 된 듯 한데요...
근데 딱 한가지 문제가 있는 듯....
뭐냐 하면 아래 구문에서요.........
else if(Table1->FieldByName("Name")->AsString=="CCD")
TotalData[2]=TotalData[2] | ((char)StrToInt(Edit5->Text)<<1);
CCD항목을 한번씩 클릭을 하면 Edit5->Text값이 0부터 3까지 순차 증가하면서 바뀝니다.
그러므로 TotalData[2]에 저장되는 값은 0000 0000-> 0000 0010-> 0000 0100-> 0000 0110로 바뀌어야 하는데요.....두번째에서 세번째로 바뀔때 0000 0010->0000 0100으로 바뀌어야 하는데,
0000 0010->0000 0110로 바뀌더군요.
이유인 즉, 두번째 비트의 1값이 살아 있는상태에서 값이 바뀌는 거죠.(원래는 0이 되어야 하는데..)
그러니간 원래는 두번째 비트는 0으로 되어야 하는 거죠.
그래서 static char TotalData[3]를 char TotalData[3]으로 바꾸니 결과값이 제대로 나옵니다.
근데 이때의 문제점은 전의 결과 값이 누적이 되어야 하는데 누적이 안 된다는 거죠.
그래서 인데 혹 Edit나 함수중에서 여타 자리수를 지정해서 출력해주는 속성이 없나요?
가령 printf("%02d",i)와 같이 02로서 자리수를 지정해서 출력해 주는 속성이 있다면 될 것 같기도 한데요....^^
바쁘신데 수고스럽게 해서 죄송하구요....
좋은 하루 되세요...............그 동안 감사 했습니다........
static char TotalData[3]={0,0,0};//,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// char cBaseData=Edit5->Text;
Table1->Edit();
if(Table1->TableName=="fix.db")
{
if(strchr(Table1->FieldByName("50")->AsString.c_str(),'&'))
{
if(UpDown1->Position >= ( pow(2,StrToInt(Table1->FieldByName("Bit")->AsString))))
{
//ShowMessage("This is FF more value. ^.^");
Edit5->Text=0;
UpDown1->Position=0;
}
else
{
Edit5->Text=AnsiString::IntToHex(UpDown1->Position,1);
}
Table1->FieldByName("50")->AsString="&H"+Edit5->Text;
}
else
{
if(UpDown1->Position >= ( pow(2,StrToInt(Table1->FieldByName("Bit")->AsString))))
{
Edit5->Text=0;//2^StrToInt(Table1->FieldByName("Bit")->AsString)-1;
UpDown1->Position=0;
if(Table1->FieldByName("Name")->AsString=="NTPAL")
TotalData[2]=TotalData[2] & ~(1<<0);
else if(Table1->FieldByName("Name")->AsString=="CCD")
TotalData[2]=TotalData[2] & ~(0x03<<1);
else if(Table1->FieldByName("Name")->AsString=="YDOUT")
TotalData[2]=TotalData[2] & ~(1<<3);
else if(Table1->FieldByName("Name")->AsString=="UVDOUT")
TotalData[2]=TotalData[2] & ~(1<<4);
else if(Table1->FieldByName("Name")->AsString=="REC601")
TotalData[2]=TotalData[2] & ~(1<<5);
else if(Table1->FieldByName("Name")->AsString=="DSYNC")
TotalData[2]=TotalData[2] & ~(1<<6);
else if(Table1->FieldByName("Name")->AsString=="SG135")
TotalData[2]=TotalData[2] & ~(1<<7);
}
else
{
Edit5->Text=UpDown1->Position;
if(Table1->FieldByName("Name")->AsString=="NTPAL")
TotalData[2]=TotalData[2] | ((char)StrToInt(Edit5->Text)<<0);
else if(Table1->FieldByName("Name")->AsString=="CCD")
TotalData[2]=TotalData[2] | ((char)StrToInt(Edit5->Text)<<1)
else if(Table1->FieldByName("Name")->AsString=="YDOUT")
TotalData[2]=TotalData[2] | ((char)StrToInt(Edit5->Text)<<3);
else if(Table1->FieldByName("Name")->AsString=="UVDOUT")
TotalData[2]=TotalData[2] | ((char)StrToInt(Edit5->Text)<<4);
else if(Table1->FieldByName("Name")->AsString=="REC601")
TotalData[2]=TotalData[2] | ((char)StrToInt(Edit5->Text)<<5);
else if(Table1->FieldByName("Name")->AsString=="DSYNC")
TotalData[2]=TotalData[2] | ((char)StrToInt(Edit5->Text)<<6);
else if(Table1->FieldByName("Name")->AsString=="SG135")
TotalData[2]=TotalData[2] | ((char)StrToInt(Edit5->Text)<<7);
}
Table1->FieldByName("50")->AsString=Edit5->Text;
}
heartsim 님이 쓰신 글 :
: ^^넘 죄송하군요. 괜히 아리송한 문제를 질문 드려서 님을 고생케 하구요...^^
: 음..제가 혹시나IntToStr로 변환해서 했는데..역시나 안되구요.
:
: 제 소스를 잠간 말씀 드리면....
: Edit5->Text=UpDown1->Position으로 해서 정수 1값이 에디트에 할당 됩니다.(이게 중요한 듯....)
: 그리고 이 에디트에 있는 값을 전송을 하는 거죠.
: 그러면 정수 1에 대한 아스키 문자가 화면에 찍힙니다.("1"이라는 문자가 아니구요.....)
: 만약 이와 달리 제가 "1"란 문자나 또는 49라는 숫자를 전송하면 화면에는 1이라는 문자가 찍히겠죠.
:
: 제 프로그램의 경우는 좀 이런 면에서 애매모호하다고 해야하나요..
: 만약 그냥 1이라는 문자를 화면에 찍을려면 그냥 AnsiString("1")이든가 Edit5->Text="1"이렇게 하면
: 화면에 속시원히 1이라는 문자가 찍힐텐데요...
: 프로그램을 짜다보니 이렇게 되었습니다.
:
: 그러니간 다시 말씀 드리면 1이라는 아스키숫자를 전송해서 그에 대응되는 문자를 찍고...
: 49라는 숫자를 전송해서 그에 대응되는 아스키문자를 찍는거죠...
:
: ^^도와주신 만큼 제가 잘 하지 못해 죄송하구요...
: 일단 퇴근하고 낼 다시 한번 해볼려구요....
: 제가 해서 안 되면 다시 질문 드리죠...^^
: 좋은 하루되세요...
:
:
:
:
:
:
:
:
:
: 아리랑 님이 쓰신 글 :
: : 앞에 앞에서도 설명했듯이 그냥 1값 또는 0값으로 하면 제대로 나온다는 뜻은 char형으로 변환해야 되는게 아니라 Int형으로 변환해야 된다는 뜻이군요? 분명히 Edit5->Text에는 "1"이나 "0"이 들어있겟군요? 그렇다면 *(Edit5->Text.c_str())이 아니라 IntToStr(Edit5->Text)로 해야 합니다. char형으로 변환하면 '1'은 49 '0'은 48로 변합니다. 즉 1(00000001) << 7,0(00000000) << 7이 아니라 49(00110001) << 7,48(00110000) << 7이 되죠. 당연히 결과 값은 틀립니다. 49의 경우는 제대로 되겟지만(이때도 경우에 따라 다른 비트를 파괴합니다)48은 의도한바대로 되지 않습니다. 그리고 ~를 쓴거보니 비트를 제거하는것같은데 0을 shift해서 ~연산 해봐야 비트가 제거되지 않습니다. TotalData[2]=TotalData[2] & ~(Edit5->Text<<0); 이때 Edit5->Text에 0이 들어있다면 (물론 제대로 동작된다면)이 코드는 비트를 제거해 주지 않습니다. 0번째비트를 제거하려면 ~(1 << 0) 같은 형식으로 해야 합니다.
: :
: : 아래는 제가 주로쓰는 비트연산용인데요.
: :
: : #define IS_SET(flag, bit) ((flag) & (bit))
: : #define SET_BIT(var, bit) ((var) |= (bit))
: : #define REMOVE_BIT(var, bit) ((var) &= ~(bit))
: : #define TOGGLE_BIT(var, bit) ((var) ^= (bit))
: :
: : 님이 원하시는것을 여기에 적용시킨다면 다음과 같이 쓰면 되겟군요.
: :
: : SET_BIT(TotalData[2],1 << 1);
: : REMOVE_BIT(TotalData[2],1 << 1);
: : SET_BIT(TotalData[2],1 << 7);
: : REMOVE_BIT(TotalData[2],1 << 7);
: : .
: : .
: : .
: :
: :
: :
: : heartsim 님이 쓰신 글 :
: : : 아래 말씀 대로 *(Edit5->Text.c_str())로 했는데 결과 값이 좀 다르게 나오드라구요.
: : : ^^;;
: : : 정성스래 알려주셨는데...오히려 제가 더 죄송스럽네요...
: : :
: : : Edit5->Text대신에 그냥 1값을 또는 0값을 써서 하면 값이 제대로 나옵니다.
: : : 또 else문 같은 경우는 에러가 안 나오구요.(AnsiString형인데도...)
: : : 문제는 if문에서 에러가 나는데...말씀대로 했더니 값이 좀 다르게 나오고...
: : : ^^;; 아마 제 소스 상에 보이지 않는 논리적 에러가 있는 듯 하기도 하네요...
: : : 오늘 집에 가서 생각하고 낼 또 이것 가지고 씨름 해야 할 듯...^^
: : : 일단 감사하구요...알려주신 대로 참고 해서 한번 다시 해봐야겠습니다.^^
: : :
: : : 감사해요..............^^
: : :
: : :
: : :
: : :
: : :
: : :
: : :
: : :
: : :
: : :
: : : 아리랑 님이 쓰신 글 :
: : : : Edit5->Text의 char형은 *(Edit5->Text.c_str()) 또는 Edit5->Text[Index]입니다.
: : : : Ex1 : TotalData[2]=TotalData[2] & ~(*(Edit5->Text.c_str()) <<1);
: : : : Ex2 : TotalData[2]=TotalData[2] & ~(Edit5->Text[1] << 1); // 이건 테스트 안해봤군요.
: : : : 물론 Edit5->Text내용중 한 바이트만 해당됩니다.
: : : : 만약 Edit5->Text내용이 하나도 없으면? 당연 에러뜹니다.
: : : :
: : : : heartsim 님이 쓰신 글 :
: : : : : 시리얼 데이터가 전송이 되야 다음 것을 진행을 하는데...어제부터 이건만 잡고 있네요..-.-
: : : : :
: : : : : 제가 질문 드리는 요지는 간단 합니다. 바로 Edit5->Text를 char형을 바꾸어야 한다는 거죠.
: : : : :
: : : : : 일단 제가 첨 질문 했을 때와는 좀 다르게 소스를 짰습니다.
: : : : : 어느정도 결론이 나온 것 같은데, 한가지 문제가 있더라구요.딱 한가지...........
: : : : :
: : : : : 아래에 보시면 2 구문이 있죠.
: : : : : ..... TotalData[2]=TotalData[2] & ~(Edit5->Text<<1);
: : : : : ..... TotalData[2]=TotalData[2] | (Edit5->Text<<0);
: : : : : 위에 것은 if에 있는 것이고 아래것은 else문에 있는 겁니다.
: : : : :
: : : : : 문제는 else문에 있는 것은 에러가 안 나죠.
: : : : : if문에 있는 구문이 에러가 나는데 이유는
: : : : : ~(Edit5->Text<<1);에서 ~연산자 때문이죠.(AnsiString형 이기 때문에........-.---)
: : : : : 근데 이걸 써야 하거든요.
: : : : : 이 상태에서 Edit5->Text를 char형으로 바꾸었죠.이렇게요...(char)Edit5->Text.c_str()
: : : : : 근데 이렇게 하고 실행하면 결과 같이 이상하게 나와요.
: : : : : 어느 장단에 맞춰야 할지........-.-
: : : : : (char)Edit5->Text.c_str()이것이 char형이 아닌가요?
: : : : : 이것만 char형으로 바로 잡으면 될 것 같은데요...
: : : : :
: : : : : 아침에 알려주신 방법은 좀 문제가 있는게...
: : : : : ..... TotalData[2]=TotalData[2] & ~(Edit5->Text<<1);
: : : : : 이 구문이 2번째 비트와 3번째 비트를 차지해서 0부터 4에 의해서 값이 0000 0000에서부터
: : : : : 0000 0110까지 변한다는 거죠.그래서 알려주신 방법은 쓸수가 없더군요.
: : : : :
: : : : :
: : : : :
: : : : : 같은 구문이 있는데, 여기서 한가지 문제가 있죠.
: : : : : 바로 Edit5->Text를 char형으로 바꿔야 하는거죠.
: : : : : 위에 대로 하면 에러가 납니다.
: : : : : 그리고
: : : : :
: : : : :
: : : : :
: : : : : void __fastcall TForm1::UpDown1Click(TObject *Sender, TUDBtnType Button)
: : : : : {
: : : : : static char TotalData[3];//={0,0,0};//,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
: : : : : // char cBaseData=Edit5->Text;
: : : : : Table1->Edit();
: : : : :
: : : : : if(Table1->TableName=="fix.db")
: : : : : {
: : : : : if(strchr(Table1->FieldByName("50")->AsString.c_str(),'&'))
: : : : : {
: : : : : if(UpDown1->Position >= ( pow(2,StrToInt(Table1->FieldByName("Bit")->AsString))))
: : : : : {
: : : : : //ShowMessage("This is FF more value. ^.^");
: : : : : Edit5->Text=0;
: : : : : UpDown1->Position=0;
: : : : : }
: : : : : else
: : : : : {
: : : : : Edit5->Text=AnsiString::IntToHex(UpDown1->Position,1);
: : : : :
: : : : :
: : : : :
: : : : :
: : : : : }
: : : : : Table1->FieldByName("50")->AsString="&H"+Edit5->Text;
: : : : : }
: : : : : else
: : : : : {
: : : : : if(UpDown1->Position >= ( pow(2,StrToInt(Table1->FieldByName("Bit")->AsString))))
: : : : : {
: : : : : Edit5->Text=0;//2^StrToInt(Table1->FieldByName("Bit")->AsString)-1;
: : : : : UpDown1->Position=0;
: : : : : if(Table1->FieldByName("Name")->AsString=="NTPAL")
: : : : : TotalData[2]=TotalData[2] & ~(Edit5->Text<<0);
: : : : : else if(Table1->FieldByName("Name")->AsString=="CCD")
: : : : : TotalData[2]=TotalData[2] & ~(Edit5->Text<<1);
: : : : : else if(Table1->FieldByName("Name")->AsString=="YDOUT")
: : : : : TotalData[2]=TotalData[2] & ~(Edit5->Text<<3);
: : : : : else if(Table1->FieldByName("Name")->AsString=="UVDOUT")
: : : : : TotalData[2]=TotalData[2] & ~(Edit5->Text<<4);
: : : : : else if(Table1->FieldByName("Name")->AsString=="REC601")
: : : : : TotalData[2]=TotalData[2] & ~(Edit5->Text<<5);
: : : : : else if(Table1->FieldByName("Name")->AsString=="DSYNC")
: : : : : TotalData[2]=TotalData[2] & ~(Edit5->Text<<6);
: : : : : else if(Table1->FieldByName("Name")->AsString=="SG135")
: : : : : TotalData[2]=TotalData[2] & ~(Edit5->Text<<7);
: : : : :
: : : : : }
: : : : : else
: : : : : {
: : : : : Edit5->Text=UpDown1->Position;
: : : : :
: : : : :
: : : : : if(Table1->FieldByName("Name")->AsString=="NTPAL")
: : : : : TotalData[2]=TotalData[2] | (Edit5->Text<<0);
: : : : : else if(Table1->FieldByName("Name")->AsString=="CCD")
: : : : : TotalData[2]=TotalData[2] | (Edit5->Text<<1);
: : : : : else if(Table1->FieldByName("Name")->AsString=="YDOUT")
: : : : : TotalData[2]=TotalData[2] | (Edit5->Text<<3);
: : : : : else if(Table1->FieldByName("Name")->AsString=="UVDOUT")
: : : : : TotalData[2]=TotalData[2] | (Edit5->Text<<4);
: : : : : else if(Table1->FieldByName("Name")->AsString=="REC601")
: : : : : TotalData[2]=TotalData[2] | (Edit5->Text<<5);
: : : : : else if(Table1->FieldByName("Name")->AsString=="DSYNC")
: : : : : TotalData[2]=TotalData[2] | (Edit5->Text<<6);
: : : : : else if(Table1->FieldByName("Name")->AsString=="SG135")
: : : : : TotalData[2]=TotalData[2] | (Edit5->Text<<7);
: : : : :
: : : : : }
: : : : : Table1->FieldByName("50")->AsString=Edit5->Text;
: : : : : }
: : : : : }
: : : : : .
: : : : : .
: : : : : .
: : : : : 생략...
: : : : :
: : : : :
: : : : :
: : : : : TotalData[0]=16;
: : : : : TotalData[1]=1;
: : : : :
: : : : : for(int i=0;i<3;i++)
: : : : : {
: : : : : ComPort1->WriteStr(TotalData[i]);
: : : : : }
: : : : : //ComPort1->Close();
: : : : :
: : : : : Table1->Post();
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : : 즐거운 하루 되세요..............................................................................
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : :
: : : : : 아리랑 님이 쓰신 글 :
: : : : : : Test해 봤는데 AnsiString이 SHift되는게 이상하군요. 뭔가 모르는게 있었나 봅니다.
: : : : : :
: : : : : : 해결책은 Edit5->Text의 값을 char형또는 Int형으로 변환후 사용하세요.
: : : : : :
: : : : : : 주의해야 할것은 Edit5->Text값 자체를 shift할것인지, 아니면 Edit5->Text값의 숫자를 shift할것인지 나와있지 않은데요. 뭔이야기냐면 Edit5->Text값에 "1"이 들어가 있다면 1 << 7로 shift할것인지 아니면 49 << 7로 할것인지가 나와있지 않다는겁니다. 여기서 49는 "1"의 Ascii code값입니다.
: : : : : : StrToInt(Edit5->Text)값은 1이 되고(Int형으로 변환), Edit5->Text[0]의 값은 49입니다.
: : : : : : 그리고 char형을 << 7로 shift하면 하위 1비트만 남고 상위비트들은 모조리 잘려나간다는건 잘 아시죠?
: : : : : : 어쨋건 Edit5->Text에 "1"을 집어넣고 shift하니까 << 6 까지는 '1 << 숫자' 형태로 변환되더군요.
: : : : : :
: : : : : : 아래 수정문의 예는 char형으로 변환한것입니다.
: : : : : :
: : : : : : heartsim 님이 쓰신 글 :
: : : : : : : 안녕하세요.빌더 초보입니다.
: : : : : : : 비트 시프트 연산과 관련해 질문이 있어서요.^^
: : : : : : : 먼저 관련 소스입니다.
: : : : : : :
: : : : : : : char TotalData[3]={0,0,0};
: : : : : : char cBaseData = Edit5->Text[1]; // <== char형으로 변환.
: : : : : : :
: : : : : : : TotalData[0]=16;
: : : : : : : TotalData[1]=1;
: : : : : : :
: : : : : : : if(Table1->FieldByName("Name")->AsString=="NTPAL")
: : : : : : : TotalData[2]=TotalData[2] | Edit5->Text;
: : : : : : : else if(Table1->FieldByName("Name")->AsString=="CCD")
: : : : : : TotalData[2]=TotalData[2] | cBaseData << 1 ; // <== 아래도 이렇게 수정
: : : : : : : TotalData[2]=TotalData[2] | Edit5->Text<<1;
: : : : : : : else if(Table1->FieldByName("Name")->AsString=="YDOUT")
: : : : : : : TotalData[2]=TotalData[2] | Edit5->Text<<2;
: : : : : : : else if(Table1->FieldByName("Name")->AsString=="UVDOUT")
: : : : : : : TotalData[2]=TotalData[2] | Edit5->Text<<4;
: : : : : : : else if(Table1->FieldByName("Name")->AsString=="REC601")
: : : : : : : TotalData[2]=TotalData[2] | Edit5->Text<<5;
: : : : : : : else if(Table1->FieldByName("Name")->AsString=="DSYNC")
: : : : : : : TotalData[2]=TotalData[2] | Edit5->Text<<6;
: : : : : : : else if(Table1->FieldByName("Name")->AsString=="SG135")
: : : : : : : TotalData[2]=TotalData[2] | Edit5->Text<<7;
: : : : : : :
: : : : : : : for(int i=0;i<3;i++)
: : : : : : : {
: : : : : : : ComPort1->WriteStr(TotalData[i]);
: : : : : : : }
: : : : : : :
: : : : : : : 위와 같습니다.
: : : : : : : 일단 시프트는 <<(왼쪽으로) 이동하는게 맞는 것 같은데요...
: : : : : : : 그리고 WriteStr을 전송할 때 TotalData를 AnsiString형이 아닌 char형으로 했습니다.
: : : : : : : 여기까지는 프로그램이 돌아가는 것으로 봐서는 문제가 없는 듯........
: : : : : : : 그런데...
: : : : : : : 맨 끝에 Edit5->Text<<7로 했을 때, 1로 세팅을 하면 invalid라고 에러가 나더군요.
: : : : : : : 물론 원인은 char형으로 해서인지 1xxx xxxx로 자리수를 넘어서서 그런 것 같습니다.
: : : : : : : 일단은 int형이나 unsigned형으로 하고 시리얼 전송을 해보니 결과 값이 다르게
: : : : : : : 나오더군요.
: : : : : : : 해결책이 없을가요?
: : : : : : : ^^
: : : : : : :
: : : : : : :
: : : : : : : 즐거운 하루되세요.
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
: : : : : : :
|