Parity check von 32-Bit Wert

OP #4459970
Hallo Leute,

ich verwende in meiner Schaltung einen LTC2418 ADC, welcher über SPI mit 
meinem Mikrocontroller kommuniziert. Das funktioniert soweit auch alles 
sehr gut. Nun bietet das Protokoll des LTC2418 die Möglichkeit die 
Parität der Nachricht zu prüfen, diese muss immer "even" sein. Dazu habe 
ich folgende Funktion geschrieben, welche die Parität eines 32-Bit 
Wertes prüfen soll:
1
// Function, which checks the parity of a received message from the ADC
2
uint8_t check_parity(uint32_t adc_message)
3
{
4
  unsigned int count = 0, pos, check_bit = 1;
5

6

7
  // Calculate parity sum
8
  for(pos = 0; pos < 32; pos++)
9
  {
10
    // Check if the bit at the actual position is 1
11
    if(adc_message & (check_bit << pos))
12
    {
13
      count++;
14
    }
15
  }
16

17
  
18
  // If parity is odd return 0
19
  if(count % 2)
20
  {
21
    return 0;
22
  }
23

24
  return 1;
25
}

Leider ergibt jede Nachricht "odd". Liegt es an meinem Code oder scheint 
es da noch Probleme beim Empfang der Nachricht zu geben?
@Jens K. (mister232)

>sehr gut. Nun bietet das Protokoll des LTC2418 die Möglichkeit die
>Parität der Nachricht zu prüfen, diese muss immer "even" sein.

>// Function, which checks the parity of a received message from the ADC
>uint8_t check_parity(uint32_t adc_message)
{
>  unsigned int count = 0, pos, check_bit = 1;

check_bit muss auch uint32 sein, es sei denn, du hast einen 32 Bit uC, 
dann ist dort int auch 32 Bit breit.
Dann sollte deine Funktion laufen.

Allerdings ist sie reichlich lahm, vor allem auf einem kleinen uC. So 
geht es besser.
1
uint8_t check_parity(uint32_t adc_message)
2
{
3
  int parity, i;
4

5
  // Calculate parity sum
6
  for(i=0, parity=0; i < 32; i++, adc_message>>=1)
7
  {
8
    // Check if bit #0 is 1
9
    if(adc_message & 1)
10
    {
11
      parity++;
12
    }
13
  }
14

15
  if(parity & 1)
16
  {
17
    return 0;  // parity is odd, return 0 (error)
18
  }
19

20
  return 1;
21
}


Noch schneller und besser ist es so, zumindest auf einer 32 Bit CPU.
1
uint8_t check_parity(uint32_t adc_message)
2
{
3

4
  adc_message = adc_message ^ (adc_message>>16);
5
  adc_message = adc_message ^ (adc_message>>8);
6
  adc_message = adc_message ^ (adc_message>>4);
7
  adc_message = adc_message ^ (adc_message>>2);
8
  adc_message = adc_message ^ (adc_message>>1);
9

10
  if (adc_message & 1) {
11
  return 0;    // odd parity, error
12
  };
13

14
  return 1;    // even parity, OK
15
}

Auf einer kleinen CPU könnte eine 16/8 Bit Hilfsvariable die 
Geschwindigkeit erhöhen, falls der Compiler das nicht clever allein 
erkennt.
1
uint8_t check_parity(uint32_t adc_message)
2
{
3

4
  uint16_t tmp16;
5
  uint8_t tmp8;
6

7
  tmp16 = adc_message ^ (adc_message>>16);
8
  tmp8  = tmp16 ^ (tmp16>>8);
9
  tmp8  = tmp8  ^ (tmp8>>4);
10
  tmp8  = tmp8  ^ (tmp8>>2);
11
  tmp8  = tmp8  ^ (tmp8>>1);
12

13
  if (tmp8 & 1) {
14
  return 0;    // odd parity, error
15
  };
16

17
  return 1;    // even parity, OK
18
}
Oder so:
1
uint8_t check_parity(uint32_t adc_message)
2
{
3
  int i;
4
  uint8_t parity = 1;
5

6
  // Calculate parity sum
7
  for(i=0; i < 32; i++, adc_message>>=1)
8
  {
9
    parity ^= (uint8_t)(adc_message & 1);
10
  }
11

12
  return parity;
13
}

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.