Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Бит тест на int32 число
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=4495
Страница 1 от 1

Автор:  michev [ Сря Юли 11, 2007 10:28 am ]
Заглавие:  Бит тест на 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--;
}
....

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

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

Автор:  BrainStorm [ Сря Юли 11, 2007 10:38 am ]
Заглавие: 

Код:
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
   }
}

Автор:  Yanek [ Сря Юли 11, 2007 10:59 am ]
Заглавие: 

Може и така:

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


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

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

Автор:  Gogo [ Сря Юли 11, 2007 11:13 am ]
Заглавие: 

Пробвай така:
Код:
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--;
}
....

Автор:  michev [ Сря Юли 11, 2007 11:14 am ]
Заглавие: 

Много БЛАГОДАРЯ Yanek!
Грешката била вярна ;) - оптимизатора бил виновен.
Изключих го и всичко тръгна.

Автор:  michev [ Сря Юли 11, 2007 11:21 am ]
Заглавие: 

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 при условие чи винаги е единица. Или нещо не съм разбрал идеята ти?

Автор:  michev [ Сря Юли 11, 2007 11:46 am ]
Заглавие: 

Та в крайна сметка се получи работещ код ;)
Код:
#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);
}

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

Автор:  Gogo [ Сря Юли 11, 2007 12:01 pm ]
Заглавие:  Re: Бит тест на int32 число

Може би аз не те разбрах или не си задал правилно въпроса си!
michev написа:
нужно е да проверя дали бит Н от едно 20 битово число е = 1.

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

Автор:  michev [ Сря Юли 11, 2007 12:09 pm ]
Заглавие:  Re: Бит тест на int32 число

Gogo написа:
Може би аз не те разбрах или не си задал правилно въпроса си!

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

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

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

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

Автор:  Yanek [ Сря Юли 11, 2007 1:31 pm ]
Заглавие:  Re: Бит тест на int32 число

michev, така или иначе вече си го направил. Освен това твоя и на Gogo начини са идентични. Реално при сравнението все едно ще се заемат 4 байта, независимо дали е обявено като локална променлива mask или не е. На компилатора така или иначе са му необходими 4 байта за да шифтва дали mask дали единицата.

Автор:  \__ [ Сря Окт 03, 2007 11:24 am ]
Заглавие: 

Код:
if (cmd & (long)(1<<nbit)) {
    .. zna4i e 1
}

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/