SIEMENS, DF&PD

Предыдущее посещение: Вт июл 05, 2016 5:20 Текущее время: Вт июл 05, 2016 5:20

Часовой пояс: UTC + 3 часа




 [ Сообщений: 18 ] 
Автор Сообщение
 Заголовок сообщения: установить бит в 1
СообщениеДобавлено: Пн окт 12, 2009 8:47 
Не в сети
Известный Писатель

Зарегистрирован: Пн май 12, 2008 12:45
Сообщения: 116
Откуда: Tula
Задача: в теге типа "Unsignet 8-bit value" установить требуемый бит в 1. Написал процедуру:

void SetBitOn(char* TagName, int Nbit)
{
signed char TagValue;

TagValue = GetTagSByte(TagName);

if ((TagValue & (int)pow(Nbit-1, 2)) == 0)
{
TagValue = TagValue + (int)pow(Nbit-1, 2);
}

SetTagSByte(TagName, TagValue);
return;
}


Т.е. сначала проверяю состояние бита, а затем, если он не включен, увеличиваю значение тега на (Nbit-1)^2. В принципе задача решена, но не нравится предупреждение компилятора "conversion may loose information" на возможное переполнение в строке
TagValue = TagValue + (int)pow(Nbit-1, 2);

Да и вообще наверняка есть более красивое решение с прямым обращением к нужному Nbit. Кто-нибудь может подсказать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн окт 12, 2009 9:49 
Не в сети
Известный Писатель

Зарегистрирован: Пт фев 29, 2008 15:27
Сообщения: 344
Откуда: Украина
Можно проще:

tag_value = tag_value | (1<<n);

tag_value - значение тега,
n - номер устанавливаемого бита.
Как это работает: операция (1<<n) сдвигает в переменной влево разряды на n позиций. В данном случае переменная у нас единица, т. е. число, в котором установлен только нулевой бит. Вот он и сдвигается на нужную нам позицию. Далее над результатом операции сдвига и переменной tag_value выполняется операция "побитовое ИЛИ" (|). В результате все биты tag_value останутся в том же состоянии, в котором и были, кроме бита в позиции n - он в любом случае будет установлен.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн окт 12, 2009 9:50 
Не в сети
Известный Писатель

Зарегистрирован: Пн фев 09, 2009 14:38
Сообщения: 192
А почему ты так объявляешь?
Цитата:
signed char TagValue;

Зачем тебе знак? Скорее всего из-за этого и ругается.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн окт 12, 2009 12:31 
Не в сети
Известный Писатель

Зарегистрирован: Пн май 12, 2008 12:45
Сообщения: 116
Откуда: Tula
Спасибо, Artemius особенно за комментарии! Так гораздо изящней! Только сдвиг надо делать не на n, а на n-1. Вот окончательный код:

void SetBitOn(char* TagName, int Nbit)
{
unsigned char TagValue;

TagValue = GetTagByte(TagName);
TagValue = TagValue | (1<<(Nbit-1));
SetTagByte(TagName, TagValue);
return;
}

Ну и если кому будет нужен, код установки бита в 0:

void SetBitOff(char* TagName, int Nbit)
{
unsigned char TagValue;

TagValue = GetTagByte(TagName);
if ((TagValue & (int)pow(2, Nbit-1)) != 0)
{
TagValue = TagValue ^ (1<<(Nbit-1));
}
SetTagByte(TagName, TagValue);
return;
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн окт 12, 2009 12:35 
Не в сети
Известный Писатель

Зарегистрирован: Пн май 12, 2008 12:45
Сообщения: 116
Откуда: Tula
Magister писал(а):
А почему ты так объявляешь?
Цитата:
signed char TagValue;

Зачем тебе знак? Скорее всего из-за этого и ругается.


даже если использовать беззнаковую переменную, все равно получаем warning: "conversion may loose information". Просто компилятор чует возможно не корректное изменение переменной с выходом ее за диапазон объявленного типа. Ну да ладно, "warning" не "error" :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн окт 12, 2009 13:39 
Не в сети
Известный Писатель

Зарегистрирован: Пт фев 29, 2008 15:27
Сообщения: 344
Откуда: Украина
Kirilll писал(а):
Только сдвиг надо делать не на n, а на n-1.

Это если считать биты с 1 по 8, а настоящие программеры все считают с нуля! :) К тому же, если кто-то вызовет твою функцию так: SetBitOn("TagName", 0), то она грохнется.
Kirilll писал(а):
if ((TagValue & (int)pow(2, Nbit-1)) != 0)

И, опять же, чтоб красивее было, можно так:
if(TagValue & (1<<Nbit))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн окт 12, 2009 14:47 
Не в сети
Писатель со стажем

Зарегистрирован: Пн июл 06, 2009 9:37
Сообщения: 851
Откуда: Санкт-Петербург
Установка и сброс определенного бита в байте:
Код:
void SetBitOn(char* TagName, int Nbit)
{
SetTagByte(TagName, (GetTagByte(TagName) | (1 << Nbit)));
return;
}


void SetBitOff(char* TagName, int Nbit)
{
SetTagByte(TagName, (GetTagByte(TagName) & (0xFFFF ^ (1 << Nbit))));
return;
}

хотя маску для сброса я как-то по другому делал, не помню уже
жаль нет циклического сдвига и инверсии... (или есть? =)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт окт 13, 2009 13:57 
Не в сети
Известный Писатель

Зарегистрирован: Пн авг 08, 2005 9:54
Сообщения: 337
Откуда: Украина, ПАО "НКМЗ"
Александр В.. писал(а):
Установка и сброс определенного бита в байте:
Код:
void SetBitOff(char* TagName, int Nbit)
{
SetTagByte(TagName, (GetTagByte(TagName) & (0xFFFF ^ (1 << Nbit))));
return;
}

хотя маску для сброса я как-то по другому делал, не помню уже
жаль нет циклического сдвига и инверсии... (или есть? =)

у меня маска для сброса бита в слове в таком виде:
Код:
SetTagByte(TagName, (GetTagByte(TagName) & (~ (1 << Nbit))));


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср окт 14, 2009 6:53 
Не в сети
Известный Писатель

Зарегистрирован: Пн май 12, 2008 12:45
Сообщения: 116
Откуда: Tula
всем спасибо, все работает!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт июн 28, 2011 8:13 
Не в сети
Написал больше чем Вы читали

Зарегистрирован: Вс янв 25, 2009 22:05
Сообщения: 1906
Откуда: Киров
LexUS писал(а):
Код:
SetTagByte(TagName, (GetTagByte(TagName) & (~ (1 << Nbit))));


А что в этом коде знак тильды (~) означает?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт июн 28, 2011 8:30 
Не в сети
Известный Писатель

Зарегистрирован: Ср фев 16, 2011 14:23
Сообщения: 434
Откуда: Санкт-Петербург, Москва
Побитовое дополнение - все биты 1 становятся 0 и наоборот.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт июн 28, 2011 19:55 
Не в сети
Это точно не человек

Зарегистрирован: Чт фев 16, 2006 12:27
Сообщения: 7509
Откуда: Украина
Alexey_Spb_82 писал(а):
Побитовое дополнение - все биты 1 становятся 0 и наоборот.

Что в простонародьи также зовётся побитовой инверсией:-)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт дек 23, 2011 16:52 
Не в сети
Новый писатель

Зарегистрирован: Пт дек 16, 2011 9:59
Сообщения: 33
прочитал не помогло.подскажите как сделать си-екшн.что бы допустим бит под номером 5 изменял своё состояние с 0 в 1 с периодичностью ну..в 1сек.хотя это не принципиально.а все другие биты не изменяли своего состояния.
или ссылку на ответ.поиском не могу найти


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт дек 23, 2011 16:53 
Не в сети
Новый писатель

Зарегистрирован: Пт дек 16, 2011 9:59
Сообщения: 33
ещё подробнее.
т.е надо прочитать 5й бит.если1 то сделать его=0.если 0 то 1.и так цикл бесконечный


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Сб дек 24, 2011 3:04 
Не в сети
Известный Писатель

Зарегистрирован: Ср фев 16, 2011 14:23
Сообщения: 434
Откуда: Санкт-Петербург, Москва
Периодичность изменения можно реализовать при помощи цикличных действий в WinCC.

P.S. JAY, если вы не можете предположить хотя бы пути решения этой задачи, есть ли вам смысл заниматься АСУ ТП?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вс дек 25, 2011 22:50 
Не в сети
Новый писатель

Зарегистрирован: Пт дек 16, 2011 9:59
Сообщения: 33
не тебе решать чем мне заниматься.и если можешь дать совет то дай,а не можешь.не пиши.
_______________
п.с на заводе сказали я и делаю


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн дек 26, 2011 9:53 
Не в сети
Известный Писатель

Зарегистрирован: Пт окт 30, 2009 10:27
Сообщения: 435
Откуда: Москва
В Graphics Designer есть такая замечательная штука - Dynamic Wizard.
А в нём уже есть такая штуковина - Setting/Resetting a bit, которая позволяет создать скрипт динамически... Например, для взвода бита 5 в теге "1" по клику:
Код:
#include "apdefap.h"
void OnClick(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName)
{
// WINCC:TAGNAME_SECTION_START
// syntax: #define TagNameInAction "DMTagName"
// next TagID : 1
#define TAG_0 "Project_WINCC::1"
// WINCC:TAGNAME_SECTION_END

// WINCC:PICNAME_SECTION_START
// syntax: #define PicNameInAction "PictureName"
// next PicID : 1
// WINCC:PICNAME_SECTION_END

DWORD dwHelp1,dwHelp2;

dwHelp1=GetTagDWordWait(TAG_0);
dwHelp2=dwHelp1|32; //как раз тот самый бит
SetTagDWordWait(TAG_0,dwHelp2);

}

Это результат работы визарда. Далее полагаю сами сможете?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн дек 26, 2011 18:13 
Не в сети
Новый писатель

Зарегистрирован: Пт дек 16, 2011 9:59
Сообщения: 33
вот тошо надо.спасибо!!)))


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
 [ Сообщений: 18 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения

Перейти:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group