Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

Битовый сдвиг массива. Пишу прогу для декодирования RDS.

Сб сен 15, 2018 19:15:18

Здравствуйте, пишу прогу для декодирования RDS данных RDa5807, дошел до расчета crc, а точнее нужно вытащить 16 бит данных из массива длинной 13 байт, проблема в том что 16 битные данные чередуются 10 битным контрольным слово. Как я понял самое простое это сдвиг либо влево на 26 бит, либо в право на 10 бит. Но к сожалению знаний как сделать по битный сдвиг массива на Си у меня нет. Буду признателен за помощь в данном вопросе.

Re: Битовый сдвиг массива. Пишу прогу для декодирования RDS.

Вс сен 16, 2018 08:40:56

В 13 байтах массива 104 бита. Как расположены данные? Вам только 16 бит надо или 4 раза по 16? Зачем "двигать" весь массив? Если вам известно, где размещаются нужные данные, то что мешает вычислить нужные 3(или 2) байта, взять из них биты данных и собрать их в 16-битную переменную?

Re: Битовый сдвиг массива. Пишу прогу для декодирования RDS.

Вс сен 16, 2018 09:59:11

4 раза по 16, но при этом данные в массиве расположены со сдвигом, то есть первый блок берем без проблем, а затем идет сдвиг на 10 бит по байтам

Re: Битовый сдвиг массива. Пишу прогу для декодирования RDS.

Вс сен 16, 2018 21:00:06

первый блок берем без проблем

А он у Вас little endian или big endian?

Я с PIC имел дело последний раз лет 20 назад. Не помню ни фига.
Вот пример, который должен работать и с little endian, и с big endian.

Код:
unsigned short parse_buf(unsigned char *in, int offset_in_bit)
{
  unsigned long tmp;

  tmp = *((unsigned long *)(in+offset_in_bit/8));
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  tmp =  ((tmp>>24)&0xff)|((tmp<<8)&0xff0000)|((tmp>>8)&0xff00)|((tmp<<24)&0xff000000);
#endif
  tmp<<=offset_in_bit%8;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  tmp =  ((tmp>>16)&0xffff);
#endif
  return(*((unsigned short *)(&tmp)));
}

Re: Битовый сдвиг массива. Пишу прогу для декодирования RDS.

Вс сен 16, 2018 21:20:26

Я только начинаю изучать си, так что little endian или big endian не скажу правильно, спасибо за предложение. Вот думаю может проще сделать так взять три байта массива в которых содержится блок данных перенести их в переменную long, и ее уже двигать как надо.

Re: Битовый сдвиг массива. Пишу прогу для декодирования RDS.

Вс сен 16, 2018 21:48:04

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

Я так и сделал. Но для этого надо знать порядок байтов в long. Это и есть little endian или big endian: https://ru.wikipedia.org/wiki/%D0%9F%D0 ... 0%BE%D0%B2

Re: Битовый сдвиг массива. Пишу прогу для декодирования RDS.

Вс сен 16, 2018 23:44:46

Ясно, я то хотел сделать структуру из char, соответственно указав какой старший байт ну а какой младший, длинной лонг, ну а структура видится как целое число, и свободно двигается. В общем Си тонкостей много как и вариантов решения.

Re: Битовый сдвиг массива. Пишу прогу для декодирования RDS.

Пн сен 17, 2018 05:52:57

Если решать "в лоб", получится простая формула. Не вдаваясь в синтаксис языка, для случая, когда нужные данные начинаются в 0 и 1 элементе массива и для int x[4] и a[13] будет:
x[i]=a[3*i]<<(8+2*i)+a[3*i+1]<<(2*i)+a[3*i+2]>>(8-2*i)
Нетрудно изменить формулу, если данные лежат в двух "старших" элементах массива.

Re: Битовый сдвиг массива. Пишу прогу для декодирования RDS.

Пн сен 17, 2018 08:43:27

В общем не стал сильно мучится сделал так
Код:
unsigned short RED_BLOCK (char t,char sdvig){
    short dat;
unsigned long dan = 0;
   dan = bit_buffer[t++];
   dan = (dan<<8)|bit_buffer[t++];
   dan = (dan<<8)|bit_buffer[t++];
   dan = dan>>sdvig;
   dat = dan&0xffff;
   return dat;
}

Берем не обходимые байты и смещаем на необходимую величину. Осталось разобраться с коррекцией ошибки полученных по RDS данных.
Ответить