Stránka 1 z 1

Funkce Arduino vrací neočekávaný výsledek

Napsal: 28 čer 2020, 19:55
od bdn
Funkci je předána hodnota c=136d, což je 0x88

Má být: Funkce má vyrobit uint32_t takto:
<0x18><0xE7><c><~c>, což je 0x18E78877

Skutečnost je:
v příkladu 1 vrací: FFFF8877
v příkladu 2 vrací: 18E68877

Kód: Vybrat vše

static void put_ir_nec( uint8_t c)
{
  uint32_t nn;

  nn = 0;
  nn += (uint8_t)(0x18) << 24;
  nn += (uint8_t)(~0x18) << 16;
  nn += (uint8_t)(c) << 8;
  nn += (uint8_t)(~c); // lsb

  Serial.println(c, HEX);  // RS232 returns: 88
  Serial.println(nn, HEX); // RS232 returns: FFFF8877,  expected: 18E78877
}


Kód: Vybrat vše

static void put_ir_nec( uint8_t c)
{
  uint32_t nn;

  nn = 0x18E70000;
  nn += (uint8_t)(c) << 8;
  nn += (uint8_t)(~c); // lsb

  Serial.println(c, HEX);  // RS232 returns: 88
  Serial.println(nn, HEX); // RS232 returns: 18E68877, expected: 18E78877
}

Napsal: 28 čer 2020, 20:00
od mikollar
nebude problem v tomto (uint8_t)? ja by som tam pouzil uint32_t. Netvrdim ze na 100% to bude tym, ale podobny problem som uz mal

Napsal: 29 čer 2020, 10:04
od bdn
Tak vyřešeno. Arduino používá C++, kde se musí dávat pozor při převodou z uint8_t. Vysvětlení z fóra:
You are running into integer promotion to a signed integer. Google C++ integer promotion for the details of what happens when a byte value is bitshifted like you do with c<<8. If you want an unsigned result, you must cast specifically.

Toto funguje:

Kód: Vybrat vše

static void put_ir_code_1( uint8_t c)
{
  uint32_t nn;

  nn = 0x18E70000;
  nn += ((uint16_t)(c) << 8);
  nn += (uint8_t)(~c); // lsb
  Serial.println(nn, HEX); // RS232 returns: 18E78877, expected: 18E78877
}

Napsal: 29 čer 2020, 13:52
od samec
Nemôžeš posuvať 8 bitové číslo viac ako 7 krát.
Výsledok pre väčší posun nie je definovaný a bude závisieť od konrétneho prekladača.