Биты и преобразование
- Войдите на сайт для отправки комментариев
Чт, 14/06/2012 - 09:55
Помогите пожалуйста с кодом, что то я не понимаю. Мне нужно инвертировать текущий бит в одном массиве байт, если в другом массиве отмечена переменная. И так каждый раз в цикле. Мигание одной лампочкой в наборе байт.
void DoBlinking() { int data_size = sizeof(main_data); int blink_size = sizeof(blink_data); if(data_size != 0 && blink_size != 0) { for(int i=0; i<data_size; i++) { byte m_d = main_data[i]; byte b_d = blink_data[i]; if(b_d > 0x00) { for(int b=0; b<8; b++) { byte curr_bit_data = bitRead(m_d,b); byte curr_bit_blink = bitRead(b_d,b); if(curr_bit_blink == 1) { //Был 1 Serial.print("was "); Serial.print(curr_bit_data); bitWrite(curr_bit_data, b, ~curr_bit_data ); Serial.print(" set "); Serial.print(curr_bit_data); // а становится черти-чем 9, 17, 33, 65, 129 итд.. } Serial.println("~~~~~~~~~~~~~~~"); delay(1000); } } } } }
Благодарю.
Вместо Serial.print(curr_bit_data);
Сделайте Serial.println(curr_bit_data,BIN); - тогда число выведется в двоичном виде. Проще будет понять какие биты установились.
А вместо
bitWrite(curr_bit_data, b, ~curr_bit_data );
Попробуйте
curr_bit_data ^= 1 << b;
И еще, строка 16-ть.
Зачем она? У вас же получается что curr_bit_data всегда только 0 или 1. Только первый бит установлен. Наверное логичней будет
curr_bit_data=m_d
Благодарю за помощь, опять вы меня выручаете.
Я сделал вот так.
Я использую 13 сдвиговых регистров чтобы управлять большим массивом Пираний.
Строка 16 нужна чтобы понимать что из себя представлеят текуший бит. Был ли он зажжен ранее. Все 8 бит задейсвованны в этом байте - ведь они двигаются как паровозик по микросхемам при заливке новых данных. Каждый бит - это 1 из 8 ножек.
P.S. Мне очень хочется стать "пилотом F1". Думаю что я на верном пути, благодарю Вас еще раз. С вашей помощью это происходит быстрее.
И у вас так заработало? По идее же XOR в этом случае должен всегда тупо сбрасывать curr_bit_data в ноль. А вы, вроде, хотели инвертирование. Если же это "то что нужно", то не проще ли просто написать curr_bit_data=0;? А если инвертировать, то нужно было not логический делать curr_bit_data = !curr_bit_data;
Кстати не обязательно менять каждый бит отдельно менять. Можно "одним махом восьмерых побивахом" (а в случае int сразу 16-ть). Причем менять только "те которые нужно". Смотрите:
Вообщем весь этот DoBlinking(), если выкинуть Serial.print-ты можно ужать до одной строчки (там еще и куча If-фов лишняя, которые никакой погоды не делает).
А если, потом почитать http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry
То можно сразу, без циклов и светики устанавливать "пачкой". По 8-мь штук за раз. Одним присваиванием байта.
Да, вы как всегда правы. Ступил. Конечно curr_data = !curr_data не XOR a NOT
Проверил. теперь все работает как нужно.
Благодарю за ссылку. Обязательно разберусь.
>Благодарю за ссылку. Обязательно разберусь.
Вначале дожмите код который есть. Строка 04 повторяет условие в строке 06. Ничего полезного, кроме захламления кода - не делает.
Строку 11 - тоже можно убрать. Без нее поведение не изменится. Ну съэкономится пара микросекунд в случае если b_d=0 ну и что? Строка 17 - все равно ничего неправильного не даст сделать. Так что можно спокойно убрать что-бы код был легче. Тем более что во всех других случаях, эти микросекунды будут тратится на проверку этого условия.
> Ступил. Конечно curr_data = !curr_data не XOR a NOT
А не зря он вам тут премерещился. Только применять его нужно не к одному биту, а ко всему байту. Еще раз вгляделся в то что получилось итогово: да мы же изобрели велосипед!!! Всмотритесь: вы, многословно, через цикл, я, чуть компактней, но все равно не идеально, заново реализовали XOR!!!!!
Пустите такой скетч:
Учитывая это, ваш блин можно сделать еще проще
Попробуйте. По идее должно вести себя так же как и ваша текущая версия.