Erster Blinkversuch ATmega328

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Erster Blinkversuch ATmega328

Beitrag von Mathias »

Ich habe meinen ersten Versuch mit AVR gemacht.
Wie erwartet blinkt die LED, welche am PIN13 meines Arduino Nano hängt sehr schnell.
Erhöhe ich den sleep von 100 auf 255, dann blinkt die LED wie erwarte ein bisschen langsamer.
Nehme ich aber 256 oder höher, dann hat die LED einen Dauerbrenner.
Wieso komme ich in der Schleife nicht über die Byte-Grenze hinaus, obwohl ich int16 deklariert habe ?

Hat evtl. der FPC 3.0.2-r1:35394 da einen Bug ?

Code: Alles auswählen

program test;
uses
  atmega328p;
 
procedure mysleep(t: int16);
var
  i: int16;
begin
  for i := 0 to t do begin
    asm
      nop;
    end;
  end;
end;
 
begin
  DDRB := 255;
  repeat
    PORTB := 0;
    mysleep(100);
 
    PORTB := 255;
    mysleep(100);
  until 1 = 2;
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
kupferstecher
Beiträge: 436
Registriert: Do 17. Nov 2016, 11:52

Re: Erster Blinkversuch ATmega328

Beitrag von kupferstecher »

Kannst du mal das Assemblerlisting hochladen?

Und du hast auch tatsächlich den Wert in mysleep angepasst und nicht den hinter DDRB? 8)

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Erster Blinkversuch ATmega328

Beitrag von Timm Thaler »

Sollte eigentlich gehen. Das Kompilat sieht bei mir so aus:

Code: Alles auswählen

PsTEST_ss_MYSLEEPsSMALLINT:  [color=#0000FF]// Prozedur[/color]
	push	r29
	push	r28
	push	r3
	push	r2
	in	r28,61
	in	r29,62
	subi	r28,6
	sbci	r29,0
	in	r0,63
	cli
	out	62,r29
	out	63,r0
	out	61,r28  [color=#0000FF]// bis hierher Vorgeplänkel, Stackpointer sichern, Statusregister sichern[/color]
	std	Y+2,r24
	std	Y+3,r25  [color=#0000FF]// Variable übernehmen[/color]
	ldd	r2,Y+2
	ldd	r3,Y+3  [color=#0000FF]// Variable t in Register[/color]
	cp	r2,r1
	cpc	r3,r1  [color=#0000FF]// Prüfen auf Null, immer bei for-loop[/color]
	brlt	.Lj6
	ldi	r18,-1
	ldi	r19,-1  [color=#0000FF]// init i mit Null minus 1, Startwert for-loop[/color]
	std	Y+4,r18
	std	Y+5,r19  [color=#0000FF]// i zwischenspeichern[/color]
.Lj7:
	ldd	r19,Y+4
	ldd	r20,Y+5  [color=#0000FF]// i wieder holen[/color]
	ldi	r18,1
	add	r19,r18
	adc	r20,r1  [color=#0000FF]// i + 1[/color]
	std	Y+4,r19
	std	Y+5,r20  [color=#0000FF]// und wieder zwischenspeichern[/color]
#  CPU AVR5
	nop  [color=#0000FF]// das NOP[/color]
#  CPU AVR5
	ldd	r18,Y+4
	ldd	r19,Y+5  [color=#0000FF]// i wieder rausholen[/color]
	cp	r18,r2
	cpc	r19,r3  [color=#0000FF]// und mit t vergleichen[/color]
	brlt	.Lj7  [color=#0000FF]// wiederholen solange kleiner[/color]
.Lj6:
	subi	r28,-6  [color=#0000FF]// Stackpointer wiederherstellen[/color]
	sbci	r29,-1
	in	r0,63
	cli
	out	62,r29
	out	63,r0
	out	61,r28
	pop	r2
	pop	r3
	pop	r28
	pop	r29
	ret  [color=#0000FF]// und fertsch mit Prozedur[/color]
 
main:
	call	FPC_INIT_FUNC_TABLE  [color=#0000FF]// Vorgeplänkel für den Controller, Stack einrichten und so[/color]
	ldi	r18,-1
	out	4,r18  [color=#0000FF]// DDRB = 255[/color]
.Lj10:
	out	5,r1  [color=#0000FF]// PORTB = 0[/color]
	mov	r24,r1  [color=#0000FF]// lobyte von 256, könnte auch gleich in r25[/color]
	ldi	r26,1  [color=#0000FF]// hibyte von 256[/color]
	mov	r25,r26  [color=#0000FF]// muss man nicht verstehen[/color]
	call	PsTEST_ss_MYSLEEPsSMALLINT  [color=#0000FF]// Prozedur aufrufen[/color]
	ldi	r18,-1
	out	5,r18  [color=#0000FF]// PORTB = 255[/color]
	mov	r24,r1
	ldi	r26,1
	mov	r25,r26  [color=#0000FF]// siehe oben[/color]
	call	PsTEST_ss_MYSLEEPsSMALLINT  [color=#0000FF]// Prozedur aufrufen[/color]
	rjmp	.Lj10  [color=#0000FF]// Endlossschleife[/color]
 
Wie man sieht, ist die for-Schleife hier reichlich ineffizient. Das liegt aber am Inline-Assembler. Da speichert der Compiler lieber zwischen, weil er nicht weiss, was an Registern geändert wird.

In r1 steht immer NULL, das wird bei vielen Berechnungen oder Vergleichen für schnellen Zugriff benutzt.

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Erster Blinkversuch ATmega328

Beitrag von Timm Thaler »

Kommentiert man das asm aus, werden die Variablen nicht zwischengespeichert und die for-Schleife sieht deutlich angenehmer aus.

Code: Alles auswählen

PsTEST_ss_MYSLEEPsSMALLINT:
	cp	r24,r1
	cpc	r25,r1
	brlt	.Lj6
	ldi	r18,-1
	ldi	r19,-1
.Lj7:
	ldi	r20,1
	add	r18,r20
	adc	r19,r1
	cp	r18,r24
	cpc	r19,r25
	brlt	.Lj7
.Lj6:
	ret
 
Das ist die komplette Prozedur. Das zeigt aber auch, dass man for nicht für genaues Timing verwenden kann, weil je nach verwendbaren Registern und Compilereinstellungen die Schleife jedesmal anders aussehen kann.

Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Erster Blinkversuch ATmega328

Beitrag von Mathias »

Sollte eigentlich gehen. Das Kompilat sieht bei mir so aus:
Mit was hast du kompiliert ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Erster Blinkversuch ATmega328

Beitrag von Timm Thaler »

Wie meinen?

Ich hab den aktuellen Trunk mit fpcupdeluxe installiert: Laz 1.9.0, FPC 3.1.1, SVN 55979 für win32/win64, dazu den AVR Embedded Crosscompiler.
Kompiliert mit Ziel Embedded-avr-AVR5
Optimierung Stufe 3

Die Optimierung hat entscheidenden Einfluss auf die Schleife, zum Beispiel wird in Stufe 1 und 2 oft eine for-Schleife mit uint16 gemacht, auch wenn die Laufvariable uint8 ist, und in Stufe 3 hat die gleiche Schleife dann uint8.

Aber: Das hat zwar Einfluss auf die Laufzeit und die Speicherbelegung, prinzipiell sollte das Programm jedoch funktionieren.

Hast Du die test.s gefunden? Stell die doch mal hier rein.

Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Erster Blinkversuch ATmega328

Beitrag von Mathias »

prinzipiell sollte das Programm jedoch funktionieren.
Tut es aber nicht.

Ich habe den es mal so kompiliert:

Code: Alles auswählen

./ppcrossavr [color=#FF0000]-O4[/color] test.pas
Der Fehler ist leider immer noch. :roll:
Ich hab den aktuellen Trunk mit fpcupdeluxe installiert: Laz 1.9.0, FPC 3.1.1, SVN 55979 für win32/win64, dazu den AVR Embedded Crosscompiler.
Kompiliert mit Ziel Embedded-avr-AVR5
Optimierung Stufe 3
Diese Version funktioniert bei mir leider nicht, sobald ich die Unit ATmega328p einbinde, dann kommt folgender Fehler:

Code: Alles auswählen

Projekt kompilieren, OS: embedded, CPU: avr, Ziel: Project1: Exit code 256, Fehler: 1
Free Pascal Compiler version 3.1.1-r20:37407 [2017/10/08] for avr
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Embedded
Compiling Project1.pas
Assembling project1
Linking Project1
/usr/bin/avr-ld: Project1.elf section `.text' will not fit in region `text'
 
 
 
 
 
Project1.pas(32,0) Error: Error while linking
Noch etwas, diese Unit musste ich über Project-Einstellungen manuell mit folgendem Pfad einbinden: /home/tux/fpcupdeluxe/fpcsrc/rtl/embedded/avr/ , ansonsten wird sie gar nicht gefunden.

Musstest du dies auch machen, oder hat es bei dir die Unit automatisch gefunden ?

Dieses Problem habe ich erst kürzlich entdeckt, weil ich bei diesem Thread: http://www.lazarusforum.de/viewtopic.ph ... ber#p98472 , die Unit Atmega328p gar nicht eingebunden hatte.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Erster Blinkversuch ATmega328

Beitrag von Timm Thaler »

Ich hab die Unit gar nicht eingebunden bzw. bei Deinem Test ausgeklammert.

Ich geb zu, ich hab einmal mit LazWizardforAVR aus diesem Forum http://forum.lazarus.freepascal.org/ind ... ic=35486.0 ein AVR Projekt erstellt und nutze seitdem immer das gleiche Projekt-Template.

Das kommt davon, wenn man sich seine Infos über Wochen aus verschiedenen Foren zusammensucht und solange probiert, bis man irgendwas Funktionierendes hat, auch wenn man dann nicht mehr weiss, warum es funktioniert.

Achso, bei mir steht unter Projekteinstellungen => Compiler => Benutzerdefinierte noch

-Cpavr5
-Wpatmega328p
-a

Und unter Pfade => andere Units

C:\Tools\Lazarus\fpc\units\avr-embedded\;C:\Tools\Lazarus\cross\lib\avr_embedded\

Damit funktioniert es hier, warum weiss ich nicht.

Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Erster Blinkversuch ATmega328

Beitrag von Mathias »

Habe habe das Tool gerade probiert und deine Pfade ergänzt.

Code: Alles auswählen

atmega328p.pp(7,4) Fatal: Circular unit reference between ATmega328P and ATmega328P
Hast du keine fertiges Helloworld Project, das du hochladen kannst ?
Dann könnte ich an diesem experimentieren. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Erster Blinkversuch ATmega328

Beitrag von Mathias »

@Timm Thaler

Könntest du mir ein funktionierendes minimal Project hochladen ?
Dann würde ich sicher auch ein wenig weiter kommen. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
kupferstecher
Beiträge: 436
Registriert: Do 17. Nov 2016, 11:52

Re: Erster Blinkversuch ATmega328

Beitrag von kupferstecher »

Hallo Mathias,

im Anhang ein Lazarusprojekt für den Atmega328p. Ich hab mir gerade den neuesten FPC runtergeladen (Rev.37442) und das Projekt erfolgreich kompiliert mit Strg+F9. Um das Programm mit Shift+F9 auch gleich noch hochzuladen musst du die entsprechende Kommandozeile in den Projekteinstellungen unter 'Compilereinstellungen/Compiler-Kommandos/Nachher Ausführen/Befehl' eintragen.

Die Unit atmega328p darf nicht "händisch" eingebunden werden, das geschieht automatisch durch den Kompiler, ihm muss über den Parameter -Wpatmega328p der Controller übergeben werden.

Durch die folgende Kommandozeile kann ich das Projekt auch in der Konsole kompilieren:
"ppcrossavr -O1 -Cpavr5 -Wpatmega328p -XPavr-embedded- Mega328pProject.lpr"

Da ich keinen atmega328p habe, konnte ich das Programm auch nicht testen.
Dateianhänge
Mega328pProject.zip
(4.89 KiB) 119-mal heruntergeladen

Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Erster Blinkversuch ATmega328

Beitrag von Mathias »

im Anhang ein Lazarusprojekt für den Atmega328p. Ich hab mir gerade den neuesten FPC runtergeladen (Rev.37442) und das Projekt erfolgreich kompiliert mit Strg+F9. Um das Programm mit Shift+F9 auch gleich noch hochzuladen

Code: Alles auswählen

Fatal: Can't find unit ATMEGA328P used by Mega328pProject
Das komische dabei, wen ich zB. PORTD mit der recht M-Taste anklicke und Deklaration suche, dann öffnet Lazarus die ATmega328P Unit.

In dem Ordner /home/tux/fpcupdeluxe/fpc/units/avr-embedded/rtl befindet sich auch keine atmega328*, bei mir hat es dort nur atmega128* Dateien.
Durch die folgende Kommandozeile kann ich das Projekt auch in der Konsole kompilieren:
"ppcrossavr -O1 -Cpavr5 -WpatmeTasraga328p -XPavr-embedded- Mega328pProject.lpr"

Code: Alles auswählen

Mega328pProject $ /home/tux/fpcupdeluxe/fpc/bin/x86_64-linux/ppcrossavr -O1 -Cpavr5 -Wpatmega328p -XPavr-embedded- Mega328pProject.lpr
Free Pascal Compiler version 3.1.1-r20:37437 [2017/10/10] for avr
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Embedded
Compiling Mega328pProject.lpr
Fatal: Can't find unit system used by Mega328pProject
Fatal: Compilation aborted
Irgendwas stimmt mit meinem Crosscompiler nicht. :roll:

Hast du deinem Lazarus auch mit fpcupdelux erstellt ?
Wen ja, hast du auch folgende Parameter bei "Setup+" ?

Code: Alles auswählen

avr-embedded
  options : -Cpavr51
  subarch : avr51
Da ich keinen atmega328p habe, konnte ich das Programm auch nicht testen.
Kein Arduino Uno oder Nano zur Hand ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
kupferstecher
Beiträge: 436
Registriert: Do 17. Nov 2016, 11:52

Re: Erster Blinkversuch ATmega328

Beitrag von kupferstecher »

Der Befehlssatz muesste avr5 sein, nicht avr51, also:
options : -Cpavr5
subarch : avr5
Auf der Wikiseite AVR gibts einen Link zu den Befehlssaetzen.
Der Befehlssatz muss schon stimmen, aber ob dein Fehler damit zusammenhaengt, weiss ich auch nicht.

Ich hab den Crosscompiler nicht mit Fpcupdelux erstellt, ich kann dir morgen mal meine Vorgehensweise beschreiben.

Arduino hab ich keinen, bisher hab ich mit dem Atmega32 und Atmega8 gearbeitet. Die Unit SerialPort ist uebrigens fuer den Atmega32, eine Anpassung an den Atmega328p sollte aber recht einfach sein, fuer ein erstes "Hello Mathias".

Gruesse~

Mathias
Beiträge: 6946
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Erster Blinkversuch ATmega328

Beitrag von Mathias »

Der Befehlssatz muesste avr5 sein, nicht avr51, also:
options : -Cpavr5
subarch : avr5
Ich habe des probiert.

Code: Alles auswählen

Compile Project, OS: embedded, CPU: avr, Target: Mega328pProject: Exit code 256, Errors: 1
AVRStandard.pas(15,3) Error: Assembler avr-embedded-as not found, switching to external assembling
Was mich noch verwundert, bei deinem Project, hat es nirgends ein uses atemga???
Aber wen ich [Alt + up] drücke, dann wird die Unit ATmega328p geöffnet. :roll:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: Erster Blinkversuch ATmega328

Beitrag von Timm Thaler »

Mathias hat geschrieben:Was mich noch verwundert, bei deinem Project, hat es nirgends ein uses atemga???
Doch, das sollte unter Projekteinstellungen stehen:
Laz-emb-01.png

Antworten