@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 | }
|