Arduino und Assembler Programmierung

OP #7359442
Lesenswert?

Hallo, ich habe ein Arduino Programm geschrieben, das aus Arduino C-code und Assembler code besteht. Aus irgendeinem Grund erkennt der Compiler der Arduino IDE das keyword 'PORTD' im Assembler Programm nicht. Im C-code wird 'PORTD' aber erkannt. Ich habe versucht verschiedenste #includes einzubinden, bisher ohne Erfolg. Der workaround mit der Registeradresse 0x0B(=PORTD) funktioniert zwar, aber vielleicht kann mir jemand helfen, die Ursache dieses Verhaltens zu klären. Hier ist ein Beispielprogramm

1
/******************************************************
2
 * PORTD wird im Assembler Programm nicht erkannt
3
*********************************************************/
4

5
byte LED = 4;  //= PD4
6

7
void setup(){
8
  Serial.begin(9600);
9
  Serial.println();
10
  Serial.println("*** Assembler Test");
11
  Serial.println();
12

13
  pinMode(LED,OUTPUT);  
14
}
15

16
void loop()  {
17
  Serial.println("Assembler");
18
  LEDon();
19
  delay(1000);
20
  LEDoff();
21
  delay(1000);
22
  
23
  Serial.println("*** C Programm");
24
  PORTD = 0x10;
25
  delay(1000);
26
  PORTD = 0x00;
27
  delay(1000);
28
}
29
//*******************
30

31
void LEDon ()  {
32
  asm volatile
33
  (
34
     "ldi r16,0x10\n"
35
     //"out PORTD,r16\n" //<----- PORTD wird nicht erkannt
36
     "out 0x0B,r16\n"    // <-- 0x0B = PORTD
37
  );  
38
}
39

40
void LEDoff ()  {
41
  asm volatile
42
  (
43
     "ldi r16,0x00\n"
44
     //"out PORTD,r16\n" //<----- PORTD wird nicht erkannt
45
     "out 0x0B,r16\n"    // <-- 0x0B = PORTD
46
  );  
47
}

und hier die Fehlermeldung, wenn die Auskommentierung von 'PORTD' entfernt wird :

C:\Users\hansk\AppData\Local\Temp\ccV87F6x.ltrans0.ltrans.o: In function LEDon': D:\Arduino\Programme\Assembler\Neuer Ordner\AssPort/AssPort.ino:37: undefined reference to PORTD' collect2.exe: error: ld returned 1 exit status exit status 1 Fehler beim Kompilieren für das Board Arduino Uno.

Vielen Dank

OP #7359498
Lesenswert?

Hallo Mawin, Der asm-Befehl asm("in %0, %1" : "=r" (value) : "I" (_SFR_IO_ADDR(PORTD)) ); ist mir zu umständlich und wenn er mehrfach im Programm auftaucht zu viel Tipperei. Ok, vieleicht reicht es das "=r" (value) : "I" (_SFR_IO_ADDR(PORTD) Gedöns nur einmal zu benutzen. Aber das muss dann für alle SFR_IO's wieder gemacht werden. Es wäre einfacher gewesen die keywords 'PORTB,'PORTC','PORTD',... zu benutzen. Ich hoffte, es geht mit einem geschickten #include an der richtigen Stelle. Dann ist es einfacher einen *.S Tab zu benutzen. Danke für Deine Antworten.

#7359515
Lesenswert?

Hans K. schrieb:

Hallo Mawin, Der asm-Befehl asm("in %0, %1" : "=r" (value) : "I" (_SFR_IO_ADDR(PORTD)) ); ist mir zu umständlich und wenn er mehrfach im Programm auftaucht zu viel Tipperei.

Dann hast du Pech gehabt, denn das ist der Weg, wie man das macht. Bisher ist aber unklar, wofür du das überhaupt brauchst. In der Regel steckt man sowas, wenn man es mehrfach benötigt, einfach in ein Makro.

Ok, vieleicht reicht es das "=r" (value) : "I" (_SFR_IO_ADDR(PORTD) Gedöns nur einmal zu benutzen. Aber das muss dann für alle SFR_IO's wieder gemacht werden. Es wäre einfacher gewesen die keywords 'PORTB,'PORTC','PORTD',... zu benutzen.

Das sind keine Keywords, sondern Präprozessor-Makros.

OP #7359550
Lesenswert?

Hallo, Nochmal : Es geht nicht um dieses Beispielprogramm! Es ist Schwachsinn das in Assembler zu schreiben. Es geht ums Prinzip von (nicht "keywords" sondern) Präprozessor-Makros.

Übrigens habe ich doch eine Methode gefunden mein geliebtes 'PORTD' zu benutzen. Mit ".EQU PORTD, 0x0B ;PORTD definieren\n" geht's. Vielen Dank an alle

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