Отговори на тема  [ 11 мнения ] 
Бит тест на int32 число 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Юли 11, 2007 10:16 am
Мнения: 1730
Мнение Бит тест на int32 число
Здравейте.
От скоро започнах да се занимавам с avr микроконтролери.
Вчера седнах да пиша една програмка за ATmega8, която да ми управлява чип свързан към MCU-то (lmx2306).
Всичко вървеше нормално докато не се сблъсках със следния проблем -
нужно е да проверя дали бит Н от едно 20 битово число е = 1.
Начина по който го направих определено е нещо грешен или аз пропускам нещо.
Код:
AVR-GCC

int32_t cmd;
cmd = 0xAAAAA; //10101010101010101010
....
typedef unsigned char byte;

byte nbit;
byte i;

i = 0;
nbit = 20

while (i<21) {
  if (  ((1<<nbit) & cmd) >> nbit  ) {
     //bit nbit ot cmd e 1
      ...

  }
  i++;
  nbit--;
}
....

Въпроса ми е - къде греша и има ли друг начин да направя това?

Поздрави,
Десислав Мичев


Сря Юли 11, 2007 10:28 am
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Пон Юли 04, 2005 11:51 pm
Мнения: 651
Местоположение: София
Мнение 
Код:
while (i<21) {
  if (  ((1<<nbit) & cmd) >> nbit  ) {
     //bit nbit ot cmd e 1
      ...

  }
  i++;
  nbit--;
}


пробваи така:

Код:
for(i=0;i<20;i++) {
  if(cmd & (1<<i) ) {
     //bit i ot cmd e 1
   }
}

_________________
От наше село са види връо, ама от връо се невиди наше село ... що така и я незнам .. ?!?


Сря Юли 11, 2007 10:38 am
Профил ICQ WWW
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Пет Юни 29, 2007 10:59 pm
Мнения: 113
Мнение 
Може и така:

Код:
nbit=0; 
while(cmd>0)
  {
    if(cmd & 1)
    {
      //tuk ako e edinica
    }
    nbit++; //samo za da broi bitovete
    cmd>>=1;
  }


По този начин си спестяваш труда да знаеш колко битово е числото, т.е. на кой бит се намира най-старшата единица.

Още нещо да кажа:
Възможно е ако нямаш код в блока с условието оптимизатора да пренебрегва изцяло условието. Ако си сигурен, че е изключен значи причината е другаде;


Сря Юли 11, 2007 10:59 am
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Фев 24, 2005 11:41 pm
Мнения: 1049
Местоположение: Pz
Мнение 
Пробвай така:
Код:
AVR-GCC

int32_t cmd,mask;
cmd = 0xAAAAA; //10101010101010101010
....
typedef unsigned char byte;

byte nbit;
byte i;

i = 0;
nbit = 20

while (i<21) {
  mask = 1;
  if (  (mask<<nbit) & cmd) {
     //bit nbit ot cmd e 1
      ...

  }
  i++;
  nbit--;
}
....


Сря Юли 11, 2007 11:13 am
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Юли 11, 2007 10:16 am
Мнения: 1730
Мнение 
Много БЛАГОДАРЯ Yanek!
Грешката била вярна ;) - оптимизатора бил виновен.
Изключих го и всичко тръгна.


Сря Юли 11, 2007 11:14 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Юли 11, 2007 10:16 am
Мнения: 1730
Мнение 
Gogo написа:
Пробвай така:
Код:
AVR-GCC

int32_t cmd,mask;
cmd = 0xAAAAA; //10101010101010101010
....
typedef unsigned char byte;

byte nbit;
byte i;

i = 0;
nbit = 20

while (i<21) {
  mask = 1;
  if (  (mask<<nbit) & cmd) {
     //bit nbit ot cmd e 1
      ...

  }
  i++;
  nbit--;
}
....

Както казах - начинаещ съм, но ми се вижда нелогично да резервирам 4 байта за mask при условие чи винаги е единица. Или нещо не съм разбрал идеята ти?


Сря Юли 11, 2007 11:21 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Юли 11, 2007 10:16 am
Мнения: 1730
Мнение 
Та в крайна сметка се получи работещ код ;)
Код:
#define F_CPU 10000000UL

#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>

typedef int32_t int32;
typedef unsigned char byte;

#define LMX_PORT   PORTB
#define LMX_LE      PB0
#define LMX_DATA   PB1
#define LMX_CLK      PB2

#define bitH(a,b)   a |= (1<<b)
#define bitL(a,b)   a &= ~(1<<b)
//int32 comand;
int32 lmxData;

void send2LMX() {
static byte i;
i = 0;
 
  bitL(LMX_PORT, LMX_LE); // LMX_LE = 0

  while (i<21) {
      if  (lmxData & 1)   bitH(LMX_PORT, LMX_DATA);
   
      bitH(LMX_PORT, LMX_CLK); // LMX_CLK = 1
   //   _delay_us(20);
      bitL(LMX_PORT, LMX_CLK); // LMX_CLK = 0
      bitL(LMX_PORT, LMX_DATA); // LMX_DATA = 0

      lmxData >>= 1;
      i++;
  }
 
  bitH(LMX_PORT, LMX_LE); // LMX_LE = 1
  return;
}

int main(void) {

   DDRB = _BV(LMX_LE) | _BV(LMX_DATA) | _BV(LMX_CLK);
   sei();


   lmxData = 0xaaaaa;
   send2LMX();
    for (;;) {
        sleep_mode();
   }

    return (0);
}

Благодаря за бързите отговори и хубавите идеи.


Сря Юли 11, 2007 11:46 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Фев 24, 2005 11:41 pm
Мнения: 1049
Местоположение: Pz
Мнение Re: Бит тест на int32 число
Може би аз не те разбрах или не си задал правилно въпроса си!
michev написа:
нужно е да проверя дали бит Н от едно 20 битово число е = 1.

По начина на @Yanek става, но условието ще се изпълни на всяка срещната еденица, а не само ако бит Н е "1". Освен това, стойността на cmd след проверката ще се промени. Ако е без значение - добре, но не си го упоменал в "заданието".


Сря Юли 11, 2007 12:01 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Юли 11, 2007 10:16 am
Мнения: 1730
Мнение Re: Бит тест на int32 число
Gogo написа:
Може би аз не те разбрах или не си задал правилно въпроса си!

В мен е проблема :)
Gogo написа:
michev написа:
нужно е да проверя дали бит Н от едно 20 битово число е = 1.

По начина на @Yanek става, но условието ще се изпълни на всяка срещната еденица, а не само ако бит Н е "1".

Тука не схващам. Каква е разликата м/у двата начина при условие че въртя цикъл за да премина през всичките 21 бита на cmd?
Gogo написа:
Освен това, стойността на cmd след проверката ще се промени. Ако е без значение - добре, но не си го упоменал в "заданието".

Нека се променя. Така или инъче за да програмирам LMX2306 трябва да извикам функцията 3 пъти с 3 различни стойности на cmd.


Сря Юли 11, 2007 12:09 pm
Профил
Ранг: Новодошъл
Ранг: Новодошъл

Регистриран на: Пет Юни 29, 2007 10:59 pm
Мнения: 113
Мнение Re: Бит тест на int32 число
michev, така или иначе вече си го направил. Освен това твоя и на Gogo начини са идентични. Реално при сравнението все едно ще се заемат 4 байта, независимо дали е обявено като локална променлива mask или не е. На компилатора така или иначе са му необходими 4 байта за да шифтва дали mask дали единицата.


Сря Юли 11, 2007 1:31 pm
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Пет Сеп 21, 2007 1:51 pm
Мнения: 5
Местоположение: Варна
Мнение 
Код:
if (cmd & (long)(1<<nbit)) {
    .. zna4i e 1
}


Сря Окт 03, 2007 11:24 am
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 11 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни