Перейти к содержанию
    

Последовательность действий - побитовая инверсия и сдвиг

Компилятор WinAVR-20090313

 

Неужели ((~PIND) >> 4) и (~(PIND >> 4)) должны давать одинаковый результат?

 

PIND у меня равен 0b1110????

 

~(PIND >> 4) получается 0b11110001 как и должно быть.

 

(~PIND) >> 4 получается тоже 0b11110001, хотя мне кажется должно быть 0b00000001

 

Я ошибаюсь?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

PIND у меня равен 0b1110????

 

(~PIND) >> 4 получается тоже 0b11110001, хотя мне кажется должно быть 0b00000001

PIND равен 00001110. После инвертирования получится 11110001. А если учесть, что компилятор в выражениях расширяет операнды до int, то единиц будет еще больше. Ну и сдвиг на 4 с расширением знака даст все единицы, причем в обоих случаях. Как у тебя получилось что-то другое - хз

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нормальные компиляторы на такой оператор выдают предупреждение или ремарку. Например, IAR "ругается" таким образом

Remark[Pa091]: operator operates on value promoted to int (with possibly unexpected result)

Если уж приспичило писать именно так, а не другим способом инвертировать биты, то наложите байтовую маску после инвертирования, но до сдвига.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как определён Ваш PIND?

Он не мой - это регистр ввода с порта.

 

PIND равен 00001110. После инвертирования получится 11110001. А если учесть, что компилятор в выражениях расширяет операнды до int, то единиц будет еще больше. Ну и сдвиг на 4 с расширением знака даст все единицы, причем в обоих случаях. Как у тебя получилось что-то другое - хз

Ничего что у меня сначала инверсия, потом сдвиг? Или раскрывать скобки уже не обязательно?

 

temp = PIND;
temp = ~temp;
SomeVar = temp >> 4;

Работает адекватно.

 

Под ???? подразумевались недостающие четыре бита?

Любые биты, в данном случае не имеющие значения и ничего не меняющие.

 

Нормальные компиляторы на такой оператор выдают предупреждение или ремарку. Например, IAR "ругается" таким образом

 

Если уж приспичило писать именно так, а не другим способом инвертировать биты, то наложите байтовую маску после инвертирования, но до сдвига.

И что мне это даст?

Гораздо проще

((~PIND) >> 4) & 0xf;

Но вопрос в другом - мне казалось что сначала должна была быть инверсия, потом сдвиг. Я не прав? Или данная конструкция что-то нарушает и не может быть применена?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И что мне это даст?

Гораздо проще

((~PIND) >> 4) & 0xf;

У вас то же самое, что я предлагаю, но по-моему более корректно будет

(((~PIND)&0xFF)>>4)

Но вопрос в другом - мне казалось что сначала должна была быть инверсия, потом сдвиг. Я не прав? Или данная конструкция что-то нарушает и не может быть применена?
Все правильно, инверсия, а потом сдвиг. Только перед инверсией беззнаковая переменная типа volatile unsigned char преобразуется в переменную типа signed int и только потом инвертируется и сдвигается сообразно правилам сдвига для знаковой переменной. Если вы хотите работать именно с байтовой переменной, то пишите

((PIND^0xFF) >> 4)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Компилятор WinAVR-20090313

 

Неужели ((~PIND) >> 4) и (~(PIND >> 4)) должны давать одинаковый результат?

 

PIND у меня равен 0b1110????

 

~(PIND >> 4) получается 0b11110001 как и должно быть.

 

(~PIND) >> 4 получается тоже 0b11110001, хотя мне кажется должно быть 0b00000001

 

Я ошибаюсь?

Разбираем по шагам:

PIND = 0b1110**** (PIND это 8 битное число)

результат инвертирования (почему смотри ниже) будет иметь тип int (в avr-gcc тип int это знаковое 16 битное число). поэтому 8 битное беззнаковое число будет расширено до знакового 16 битного

~PIND == ~(0b00000000 1110****) == 0b11111111 0001***

(~PIND) >> 4 с правой стороны этого выражения числовая константа (без явного указания типа), а по стандарту си она должна интерпретироваться как тип int. При операции сдвига меньший операнд по стандарту си должен быть расширен до бОльшего (именно по этой причине компилятор делал инвертирование в 16 битах). т.е. имеем: (~PIND) >> 4 == 0b11111111 0001**** >> 4 == 0b11111111 11110001

итого, если результат приводится к 8ми битному типу то должно получиться 0b11110001.

Если это не так, то надо более точно разбираться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если это не так, то надо более точно разбираться.

Вот я и пытаюсь добиться определения PIND в WinAVR ибо "Он не мой - это регистр ввода с порта." это не определение на языке C. Отсюда и плясать надо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот я и пытаюсь добиться определения PIND в WinAVR ибо "Он не мой - это регистр ввода с порта." это не определение на языке C. Отсюда и плясать надо.

#define PIND    _SFR_IO8(0x09)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, всё так, большое спасибо. Теперь всё встало на свои места, всё понятно. Прошу прощения за причинённые неудобства 8)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#define PIND    _SFR_IO8(0x09)

Если совсем правильно, то

(*(volatile uint8_t *)(mem_addr))

где mem_addr это адрес порта D

таким образом PIND это uint8_t т.е. ровно 8 битное беззнаковое число.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просто мы же в разделе AVR, мне казалось что особо указывать что есть PIND не нужно. Хотя (*(volatile uint8_t *)(mem_addr)) я не нашёл - оно где?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просто мы же в разделе AVR, мне казалось что особо указывать что есть PIND не нужно. Хотя (*(volatile uint8_t *)(mem_addr)) я не нашёл - оно где?

include/avr/sfr_defs.h

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не прошло и полгода!

И хоть после драки кулаками не машут, но на будущее. Не у всех установлен WinAVR, а получить результирующий ответ можно было уже после ответа на второй пост.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...