Wieso Wert nicht gleich auf 0 setzen?

Gast #5681291
Lesenswert?

Es handelt sich um einen At90CAN128.
Hier der Code.
1
ISR(CANIT_vect)
2
{
3
  uint8_t canpage;
4
  uint8_t mob;
5
  
6
  if ((CANHPMOB & 0xF0) != 0xF0)
7
  {
8
    // save MOb page register
9
    canpage = CANPAGE;
10
    
11
    // select MOb page with the highest priority
12
    CANPAGE = CANHPMOB & 0xF0;
13
    mob = (CANHPMOB >> 4);
14
    
15
    // a interrupt is only generated if a message was transmitted or received
16
    if (CANSTMOB & (1 << TXOK))
17
    {
18
      // clear MOb
19
      CANSTMOB &= 0;
20
      CANCDMOB = 0;
21
      
22

23
      can_t *buf = CanBufferGetDequeuePtr(&CanTxBufferInfo);
24
      
25
      // check if there are any another messages waiting
26
      if (buf != NULL)
27
      {
28
        _CanCopyMessageToMob( buf );
29
        CanBufferDequeue(&CanTxBufferInfo);
30
        
31
        // enable transmission
32
        CANCDMOB |= (1<<CONMOB0);
33
      }
34
      else {
35
        // buffer underflow => no more messages to send
36
        _DisableMobInterrupt(mob);
37
        _transmission_in_progress = 0;
38
      }
39
    }
40
    else {
41
      // a message was received successfully
42
      can_t *buf = CanBufferGetEnqueuePtr(&CanRxBufferInfo);
43
      
44
      if (buf != NULL)
45
      {
46
        // read message
47
        _CanCopyMobToMessage( buf );
48
        
49
        // push it to the list
50
        CanBufferEnqueue(&CanRxBufferInfo);
51
      }
52
      else {
53
        // buffer overflow => reject message
54
        // FIXME inform the user
55
      }
56
      
57
      // clear flags
58
      CANSTMOB &= 0;
59
      CANCDMOB = (1 << CONMOB1) | (CANCDMOB & (1 << IDE));
60
    }
61
    
62
    // restore MOb page register
63
    CANPAGE = canpage;
64
  }
65
  else
66
  {
67
    // no MOb matches with the interrupt => general interrupt
68
    CANGIT |= 0;
69
  }
70
}
Gast #5681340
Lesenswert?

Hallo

Laut Datenblatt des At90CAN128:
To acknowledge a MOb interrupt, the corresponding bits of CANSTMOB 
register (RXOK, TXOK,...) must be cleared by the software application. 
This operation needs a read-modify-write
software routine.

Hansi  H. schrieb:
> CANSTMOB &= 0;
entspricht ja
CANSTMOB = CANSTMOB & 0;

Das Register wird hier zuerst gelesen (read), danach mit & 0 auf 0 
gesetzt (modify) und abschließend wieder geschrieben (write).
Gast #5681352
Lesenswert?

Datenblatt schrieb im Beitrag #568134
> Hansi  H. schrieb:
> CANSTMOB &= 0;
>
> entspricht ja
> CANSTMOB = CANSTMOB & 0;
>
> Das Register wird hier zuerst gelesen (read), danach mit & 0 auf 0
> gesetzt (modify) und abschließend wieder geschrieben (write).
Das macht natürlich Sinn. Danke für die Erklärung.
Gast #5681385
Lesenswert?

Walter schrieb:
> Hansi  H. schrieb:
> CANGIT |= 0;
>
> Register lesen und unverändert zurückschreiben ist mir bisher auch noch
> nicht untergekommen. Wenn das denn sein muss würde ich zumindest
> CANGIT = CANGIT
> schreiben

Zumal ist das wahrscheinlich noch schneller.
Gast #5681395
Lesenswert?

Jim M. schrieb:
> Falls das wirklich so gedacht war (Zusätzlicher Lesezugriff auf das
> Register) dann muss da mindestens ein aussagekräftiger Kommentar sein.

Bei uC, besonders bei serieller IO ist es üblich, das Register gelesen 
und beschrieben werden müssen.

Niemand würde, ohne das DB zu lesen, solch Registerzugriffe in der 
Reihenfolge vertauschen oder "optimieren".

Ein Kommentar? Didaktisch OK. Je nach skills der Zielgruppe. Am Ende 
will man aber weder das DB im Code haben, noch bei jeder RMW-operation 
dabeischreiben, dass es eine sein soll.
#5681412
Lesenswert?

Walter schrieb:
> Hansi  H. schrieb:
>> CANGIT |= 0;
>
> Register lesen und unverändert zurückschreiben ist mir bisher auch
> noch nicht untergekommen.

Der Grund dürfte der gleiche sein wie im Beispiel weiter oben: das Lesen 
des Registers hat einen hardwareseitigen Effekt, der benötigt wird.

Hansi  H. schrieb:
>> Wenn das denn sein muss würde ich zumindest
>> CANGIT = CANGIT schreiben

> Zumal ist das wahrscheinlich noch schneller.

Der Compiler wird die Veroderung mit 0 wegoptimieren.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren