PCCar.ru - Ваш автомобильный компьютер

PCCar.ru - Ваш автомобильный компьютер (http://pccar.ru/index.php)
-   Общение с машиной (http://pccar.ru/forumdisplay.php?f=14)
-   -   CITROEN-ARDUINO (http://pccar.ru/showthread.php?t=23275)

T_r_D 20.10.2015 23:34

Помогите ещё чутка.
есть бит в котором
01022222
0 - не используются
1 - активно меню или нет
2 - данные меню.
Пишу вот так (переменная равна int)
AM = buf[6] << 3;
Serial.println(AM);
По моему мнению это должно заставить сообщение принять вид
22222000
но в реале почему-то получаю число типо 696.
Этого числа вообще тут быть не может!
При этом видно что значения меняются и данные ячеек меню тоже.

Что я не так делаю?

Вот кусок кода
if(canId == 485) //1E5
{
if (bitRead(buf[0],7) == 1){AP = 1; APV = (buf[0] << 1 / 2) - 191; AM = 0;}
if (bitRead(buf[1],7) == 1){AP = 2; APV = (buf[1] << 1 / 2) - 191; AM = 0;}
if (bitRead(buf[2],7) == 1){AP = 3; APV = (buf[2] << 1 / 2) - 191; AM = 0;}
if (bitRead(buf[4],7) == 1){AP = 4; APV = (buf[4] << 1 / 2) - 191; AM = 0;}
if (bitRead(buf[5],7) == 1){AP = 5; APV = bitRead(buf[5],6); AM = 0;}
if (bitRead(buf[5],4) == 1){AP = 6; APV = bitRead(buf[5],2); AM = 0;}
if (bitRead(buf[6],6) == 1){AP = 7; APV = 0; AM = buf[6] << 3;}
}
Serial.println(AM);

значение в этом байте такие.
00011 None
00111 Classical
01011 Jazz-Blues
01111 Pop-Rock
10011 Vocal
10111 Techno
полностью сообщение с активным меню и предустановкой Classic выглядит как
01000111

autowp 20.10.2015 23:53

Ты путаешь биты и байты.
Бит может быть 0 или 1. 2 быть не может.

Сдвиг осуществляется побитно, а не побайтно.

Хотя код выглядит логично, о каких 22222 речь совершенно не понятно

lti1 21.10.2015 01:36

T_r_D, попробуйте так:

if (bitRead(buf[6],6) == 1){AP = 7; APV = 0; AM = buf[6]^=1<<6;}

В итоге в переменной AM получите:

3 или 00000011 None
7 или 00000111 Classical
11 или 00001011 Jazz-Blues
15 или 00001111 Pop-Rock
19 или 00010011 Vocal
23 или 00010111 Techno

GASCHE 21.10.2015 09:59

Цитата:

Сообщение от T_r_D (Сообщение 340967)
Помогите ещё чутка... 01000111

Я бы побитно сложил ваш байт и маску 00111111
Res := 01000111 AND 00111111, а результат Res = 00000111 проверял на нужные вам цифры 3, 7... И учитывая что последние два бита не несут нужной вам информации или вы не знаете что они означают, я бы их убрал сложением с маской 00111100 с соответствующим перерасчетом цифр 3, 7...

T_r_D 21.10.2015 12:12

Цитата:

Сообщение от autowp (Сообщение 340969)
Ты путаешь биты и байты.
Бит может быть 0 или 1. 2 быть не может.

Сдвиг осуществляется побитно, а не побайтно.

Хотя код выглядит логично, о каких 22222 речь совершенно не понятно

А запись вида xyxzzzzz тебя больше устраивает?
Где x не используемые биты
y бит состояния меню
И z содержание меню.

T_r_D 21.10.2015 12:27

Цитата:

Сообщение от lti1 (Сообщение 340975)
T_r_D, попробуйте так:

if (bitRead(buf[6],6) == 1){AP = 7; APV = 0; AM = buf[6]^=1<<6;}

В итоге в переменной AM получите:

3 или 00000011 None
7 или 00000111 Classical
11 или 00001011 Jazz-Blues
15 или 00001111 Pop-Rock
19 или 00010011 Vocal
23 или 00010111 Techno

А что означает buf[6]^=1<<6 ?

И почему моё смещение не приводит к такому результату?
По сути я хочу первые 5 бит переместить в начало обнулив последним 3
Мне кажется что при смещении какой-то мусор прилетает.
Может сначала спаять с байтом забитым нулями, а потом сместить?
Только хочется это по компактнее расписать, а не с кучей строк и условий.

xmetal 21.10.2015 13:15

Цитата:

Сообщение от T_r_D (Сообщение 341001)
И почему моё смещение не приводит к такому результату?
По сути я хочу первые 5 бит переместить в начало обнулив последним 3
.

Похоже, что при вычислениях все типы по умолчанию приводятся к результирующему типу, а он у тебя int. Поправьте меня, если я не прав. Тогда нужно делать так, если AM нужен int:
if (bitRead(buf[6],6) == 1){AP = 7; APV = 0; AM = (unsigned char)(buf[6] << 3);}
Цитата:

Сообщение от T_r_D (Сообщение 341001)
А что означает buf[6]^=1<<6 ?

1 смещается на 6 бит влево и логически (XOR) побитово складывается с buf[6]. То есть, если биты одинаковые, то результирующий бит будет 0, если разные то 1. Но похоже это не то, что нужно, так как, если в 7 бите buf[6] будет 0, то после этой операции там станет 1 и результат будет опять не тот.

xmetal 21.10.2015 14:38

Извиняюсь, ввел в заблуждение.:huh2: В данном случае buf[6]^=1<<6 будет отрабатывать как надо, так как стоит проверка if (bitRead(buf[6],6) == 1).

T_r_D 21.10.2015 16:26

Цитата:

Сообщение от xmetal (Сообщение 341006)
Извиняюсь, ввел в заблуждение.:huh2: В данном случае buf[6]^=1<<6 будет отрабатывать как надо, так как стоит проверка if (bitRead(buf[6],6) == 1).

В данном случае да, но нужен универсальный способ.

Вечером попробую сделать вот так
AX = buf[6],0 | buf[6],1 | buf[6],2 | buf[6],3 | buf[6],4;

Ну и способ со смещением
if (bitRead(buf[6],6) == 1){AP = 7; APV = 0; AM = (unsigned char)(buf[6] << 3);}

xmetal 21.10.2015 16:59

Цитата:

Сообщение от T_r_D (Сообщение 341017)
Вечером попробую сделать вот так
AX = buf[6],0 | buf[6],1 | buf[6],2 | buf[6],3 | buf[6],4;

Что это дает?


Часовой пояс GMT +4, время: 10:37.

Работает на vBulletin® версия 3.8.4.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot