Forum: Mikrocontroller und Digitale Elektronik Wieso Wert nicht gleich auf 0 setzen?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Hansi H. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Nabend,

Wieso verundet man das Register mit 0? Was macht das für einen Sinn?
1
// a interrupt is only generated if a message was transmitted or received
2
    if (CANSTMOB & (1 << TXOK))
3
    {
4
      // clear MOb
5
      CANSTMOB &= 0;
6
      CANCDMOB = 0;
7
                }

von holger (Gast)


Bewertung
0 lesenswert
nicht lesenswert
>Wieso verundet man das Register mit 0? Was macht das für einen Sinn?

Es macht keinen Sinn.

von Dussel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich wüsste keinen allgemeinen Grund. Für welchen Controller und welchen 
Compiler ist das?

von Peter D. (peda)


Bewertung
1 lesenswert
nicht lesenswert
Hansi  H. schrieb:
> Wieso verundet man das Register mit 0?

Das mußt Du den Autor des Schnipsels fragen.
Vielleicht steht auch was dazu im Datenblatt des unbekannten MCs.

von Hansi H. (Gast)


Bewertung
0 lesenswert
nicht 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
}

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Hansi  H. schrieb:
> Hier der Code.

Und woher ist der?
Ist das ein offizielles Beispiel von Microchip.

von Datenblatt (Gast)


Bewertung
2 lesenswert
nicht 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).

von Hansi H. (Gast)


Bewertung
0 lesenswert
nicht lesenswert

von Hansi H. (Gast)


Bewertung
0 lesenswert
nicht 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.

von Jim M. (turboj)


Bewertung
0 lesenswert
nicht lesenswert
Hansi  H. schrieb:
> Wieso verundet man das Register mit 0? Was macht das für einen Sinn?

Bugreport an den Author des Quellcodes. (Github: Issues).

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

von Walter (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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

von Hansi H. (Gast)


Bewertung
0 lesenswert
nicht 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.

von A. S. (achs)


Bewertung
0 lesenswert
nicht 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.

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Bewertung
0 lesenswert
nicht 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.

von holger (Gast)


Bewertung
0 lesenswert
nicht lesenswert
>Der Compiler wird die Veroderung mit 0 wegoptimieren.

Das darf er nicht weil CANGIT volatile ist.

von A. S. (achs)


Bewertung
0 lesenswert
nicht lesenswert
holger schrieb:
>>Der Compiler wird die Veroderung mit 0 wegoptimieren.
>
> Das darf er nicht weil CANGIT volatile ist.

Es geht ums oder. Das darf er wegoptumieren. Dann sind beide Zeilen 
gleichwertig.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.