-=FISHER=-

Преобразование массива в код (Си)

314 сообщения в этой теме

ARV    278
Только что, -=FISHER=- сказал:

Есть массив из 8 элементов типа char, каждый элемент равен либо 1 либо 0. Так же есть переменная code типа char.

Тогда речь не о переводе строкового бинарного представления в число. Вы уж определитесь :) 

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


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

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
Alex    528
8 минут назад, -=FISHER=- сказал:

Нужно сделать так чтобы из этого:

Тогда сие :

1 час назад, -=FISHER=- сказал:

Верно

Неверно. :)

UPD: Упс... Опередили...

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


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
2 минуты назад, ARV сказал:

Вы уж определитесь :) 

Я думаю всем всё стало ясно и более того код работает. :)

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


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

@-=FISHER=- , Вы расскажите лучше в чём конкретно загвозка. Код медленно исполняется, хотите чтобы побыстрее было ? Или что ?

А то, ведём дискуссию, а смысла её не понимаем...

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


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
Только что, Alex сказал:

А то, ведём дискуссию, а смысла её не понимаем...

Это маленький кусочек большего кода, точнее его предисловие. И мне нужно было понять, не работает вот этот перевод массива или дело уже в последующей обработке команды. Общими с вами усилиями я пришел к выводу что загвоздка дальше по коду. А дальше код моего многострадального удлинителя поворотников (на авто)...

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


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

А чем обусловлено хранение 8-ми бит данных вот таким образом :

trig[8] = {1,0,0,1,1,0,1,1}; 

?
Нельзя ли как то ужать их сразу изначально в один байт ?

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


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
20 минут назад, Alex сказал:

Нельзя ли как то ужать их сразу изначально в один байт ?

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

Если вкратце то, так: в while(1) считываем последовательно состояние трёх (а в примере написал 8 просто чтобы логичнее смотрелось) ножек МК. И получаем с помощью кода который обсуждался выше одну из пяти последовательностей, которые я назвал код команды (code): 000, 010, 011, 110, 111 что в десятеричной системе будет 0, 2, 3, 6, 7 соответственно. И далее запускаем функцию обработки команды get_command(code), где с помощью switch запускаем соответствующую для пришедшего кода команду.

void get_command(char mode) //функция обработки команды

{

 if (!((old_code)==mode)) //проверяем пришла новая команда или опять предыдущая, если новая то
 {
   switch(mode)
   {
	case 0: {Lights_pause(); break;} //пауза между вспышками
	case 2: {Stand_by(); break;} //не один поворотник не включен
	case 3: {Lights_On_Right(); break;} //включен правый поворотник
	case 6: {Lights_On_Left(); break;} //включен левый поворотник
	case 7: {Lights_On_All(); break;} //включена аварийка, т.е. оба поворотника
	break;
   }
   old_code=mode; //записываем предыдущую команду во временную переменную
 }

}

 

Изменено пользователем -=FISHER=-

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


Ссылка на сообщение
Поделиться на других сайтах
Yurkin2015    285
6 минут назад, -=FISHER=- сказал:

считываем последовательно состояние трёх ... ножек МК

Ну, при считывании сразу в code и пишите и никаких сдвигов-преобразований не надо.

code = 0;
if(PIN1) code |= 0x01;
if(PIN2) code |= 0x02;
if(PIN3) code |= 0x04;

 

  • Одобряю 1

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


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
4 минуты назад, Yurkin2015 сказал:

Ну, при считывании сразу в code и пишите и никаких сдвигов-преобразований не надо.

Краткость пока не моя сестра, вы правы...

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


Ссылка на сообщение
Поделиться на других сайтах
ARV    278
Только что, Yurkin2015 сказал:

Ну, при считывании сразу в code и пишите и никаких сдвигов-преобразований не надо

А если все ножки на одном порту - так и вообще крррасота!

code = PINB;

 

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


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
1 минуту назад, ARV сказал:

А если все ножки на одном порту - так и вообще крррасота!


code = PINB;

 

Но ведь нужно ещё дребезг обработать.

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


Ссылка на сообщение
Поделиться на других сайтах
ARV    278
Только что, -=FISHER=- сказал:

Но ведь нужно ещё дребезг обработать

а в чем проблема? 

code = PINB;
_delay_ms(10); // задержка на время дребезга
if(code != PINB) code = 0;

 

  • Лайк 1

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


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
2 минуты назад, ARV сказал:

а в чем проблема?

А что если нужно смотреть только на ножки PB0, PB1 и PB2 как их замаскировать от остальных ножек этого порта?

 

Изменено пользователем -=FISHER=-

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


Ссылка на сообщение
Поделиться на других сайтах
ARV    278
Только что, -=FISHER=- сказал:

А что если нужно смотреть только на ножки PB0, PB1 и PB2 как из замаскировать от остальных ножек этого порта?

не менее элементарно

#define K1   _BV(PB0)
#define K2   _BV(PB1)
#define K3   _BV(PB2)
#define ANY_K (K1 | K2 | K3)

code = PINB & ANY_K;

Не знаю, как у вас, но в моих проектах кнопки всегда на массу замыкаются, т.е. значения инвертированные получаются: не 1 при нажатии, а 0. поэтому в моем случае код чуть-чуть иной:

code = ~PINB & ANY_K;

А дальше уже все так же...

Изменено пользователем ARV

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


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
5 минут назад, ARV сказал:

не менее элементарно

 

боже это гениально, а расшифруйте вот это пожалуйста _BV(PB1)

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


Ссылка на сообщение
Поделиться на других сайтах
ARV    278
Только что, -=FISHER=- сказал:

расшифруйте вот это пожалуйста _BV(PB1)

Это стандартный макрос GCC

#define _BV(x)   (1 << (x))

Означает "Bit Value", т.е. выдает 1 на указанном месте в байте

  • Одобряю 1

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


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
6 минут назад, ARV сказал:

Это стандартный макрос GCC


#define _BV(x)   (1 << (x))

 

Это сократило мне ~400 байт кода! Просто шикарно! Спасибо!!!

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


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
40 минут назад, ARV сказал:

Не знаю, как у вас, но в моих проектах кнопки всегда на массу замыкаются, т.е. значения инвертированные получаются: не 1 при нажатии, а 0. поэтому в моем случае код чуть-чуть иной:


code = ~PINB & ANY_K;

Тут под словом кнопка я имел ввиду сигнал из вне. А он положительный у меня.

А я правильно понял что все эти макроподстановки в итоге можно заменить на

code=PINB&0b00000111;
_delay(10);
if(code!=PINB){code=0;}

 

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


Ссылка на сообщение
Поделиться на других сайтах
ARV    278
Только что, -=FISHER=- сказал:

А я правильно понял что все эти макроподстановки в итоге можно заменить на

Нет. Раз в code вы помещали инвертированное и замаскированное значение PINB, то и в дальнейшем сравнивать надо с инвертированным и замаскированным значением, а не как у вас - у вас может быть всегда не равно...

Согласно моему принципу нисходящего программирования, о котором я вам говорил, получение состояния внешних "кнопок" надо оформить отдельной функцией, и тогда вопроса что с чем сравнивать даже не возникло бы:

uint8_t get_button(void){
   return ~PINB & ANY_K;
}

// теперь 

code = get_button();
_delay_ms(10);
if(code != get_button()) code = 0;

При этом спустя годы ваша get_button() может получать коды хоть из интернета - остальное все по-прежнему будет работать...

Изменено пользователем ARV
  • Одобряю 1

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


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
2 минуты назад, ARV сказал:

Нет.

#define K1   _BV(PB0) //это значит K1 = (0b00000001)
#define K2   _BV(PB1) //это значит K2 = (0b00000010)
#define K3   _BV(PB2) //это значит K3 = (0b00000100)
#define ANY_K (K1 | K2 | K3) //это значит ANT_K = ((0b00000001) | (0b00000010) | (0b00000100)) = 0b00000111

code = PINB & ANY_K; //это значит PINB & 0b00000111;

получается я неверно понял?

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


Ссылка на сообщение
Поделиться на других сайтах
ARV    278
Только что, -=FISHER=- сказал:

получается я неверно понял?

Читайте внимательнее: ваша ошибка была не в понимании битовых масок, а вот в этом:

 

Только что, -=FISHER=- сказал:

if(code!=PINB){code=0;}

Cравнивать надо с числом, полученным тем же способом, как ранее записывали в code.

  • Одобряю 1

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


Ссылка на сообщение
Поделиться на других сайтах
-=FISHER=-    5
6 минут назад, ARV сказал:

Читайте внимательнее: ваша ошибка была не в понимании битовых масок, а вот в этом:

Всё, дошло.

10 минут назад, ARV сказал:
20 минут назад, -=FISHER=- сказал:

if(code!=PINB){code=0;}

Cравнивать надо с числом, полученным тем же способом, как ранее записывали в code.

Дак как же тогда (если именно этот пример рассматривать), вопрос открытым остался. Так?

code=PINB&0b00000111;
_delay(10);
if(code!=(PINB&0b00000111)){code=0;}

 

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


Ссылка на сообщение
Поделиться на других сайтах
ARV    278
Только что, -=FISHER=- сказал:

Так?

Так

  • Лайк 1

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


Ссылка на сообщение
Поделиться на других сайтах
ruhi    25
2 часа назад, -=FISHER=- сказал:

боже это гениально, а расшифруйте вот это пожалуйста _BV(PB1)

Дело то пошло! :)

Как говорится: если начать сначала, то есть большая вероятность дойти до нужного результата! :) 

А еще мне нравится:

"В волшебно-ингредиентном супе Нет волшебного ингредиента!"

Изменено пользователем ruhi

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


Ссылка на сообщение
Поделиться на других сайтах
ruhi    25
1 час назад, -=FISHER=- сказал:

Так?

так чуть-чуть удобнее, при наличии привычки, которую очень полезно развивать:

code=PINB & 0x07;

_delay(10);

if(code!=(PINB & 0x07)){code=0;}

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


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

Создайте аккаунт или войдите в него для комментирования

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

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас