Parity check von 32-Bit Wert

OP #4459970
Lesenswert?
• ▲
▼
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?
#4460024
Lesenswert?
• ▲
▼
@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
}

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

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.