Официальный сайт компании Arduino по адресу arduino.cc
Что делает код
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Здравствуйте!
Возникла необходимость передать данные по интерфейсу UART на контроллер ATMega 328p. Контроллер прошит и работает правильно. Есть кусок кода от другого контроллера на базе Arduino, он собирает буфер значений и передает их. Проблема в том, что сейчас есть необходимость сделать то же самое на другом устройстве и на языке C++. Камнем преткновения стало обилие специфических для Arduino функций, которые сильно затрудняют понимание кода.
Собственно код:
#define RC_CHANS 8 static int16_t rcData[RC_CHANS]; // interval [1000;2000] uint8_t i,ind,check; uint8_t rcBuf[6+2*RC_CHANS]; rcBuf[0] = '$'; rcBuf[1] = 'M'; rcBuf[2] = '<'; rcBuf[3] = 2*RC_CHANS; check = rcBuf[3]; rcBuf[4] = 200; //MSP_SET_RAW_RC check ^= rcBuf[4]; ind=5; for(i=0;i<RC_CHANS;i++) { rcBuf[ind] = rcData[i] & 0xFF; // вопрос первый: 0xFF - что-то вроде символа-терминатора, означающего конец строки? check ^= rcBuf[ind++]; // вопрос второй: что делает оператор ^= rcBuf[ind] = (rcData[i]>>8) & 0xFF; check ^= rcBuf[ind++]; } rcBuf[ind] = check;
Результатом работы всего этого безобразия является заполненный массив rcBuf. Зачем нужны биты 0xFF и зачем данные из массива rcData переписываются дважды (да еще и с операцией rcData[i]>>8 ).
Прошу прощения за глупые вопросы, но с подобным кодом сталкиваюсь впервые. Прошу знающих людей потратить 10 минут на объяснения. :)
Вообщем-то, в этом коде ВООБЩЕ нет ничего ардуино-специфического. Это же голый C, так что на вашем "другом устройстве" все это должно скомпилироватся вообще без измнений.
Поэтому для понимая, вам нужно почитать про битовые операции в любом учебнике C/C++
Ну или в справочнике по ардуине Arduino - BitwiseAnd Arduino - Bitshift
Берем младший байт rcData[i] и сохраняем его в rcBuf[] . Теоретически из-за того что rcBuf это байтовый массив, то "& 0xFF" можно было и не делать, он бы потерялся "сам по себе", без дополнительных усилий. Но видимо автор, для читабельности, решил что-бы явно было видно "старший байт" - мы выкидываем
Это сокращенный синтаксис для
Ну, а что делает ^ (он же XOR) - думаю уже знаете, если читали первую ссылку.
А тут мы сохраняетм в rcBuf - старший байт . А младший выкидываем. И опять, таки, на мой взгляд & 0xFF - излишне (но и не мешает), так как сдвиговая операцию уже заполнила старший байт нуляем.
В итоге: тут, похоже, происходит копирование данных из массива int-тов (то есть каждый элемент двух-байтовый), в одно-байтовый массив. Плюс, в этот же масив запихивается контрольная сумма, которую расчитывали для старшего и младшего байта.
Спасибо большое!!! :)