mikrocontroller.net

Forum: Projekte & Code AVR8ASM-Projekte


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.
Autor: Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich wollte einen DC-Getriebemotor, PWM gesteuert, rechts / links laufen 
lassen können. Das heisst mit verschiedenen, per Hand, einstellbaren 
Geschwindigkeiten.

Ein Handencoder ( so nenne ich ihn ) bzw. Drehgeber (auch 
Inkrementaldrehgeber, Quadraturencoder, Drehencoder, Drehimpulsgeber 
genannt) schien mir dazu bestens geeignet.

Daraus ist das folgende AVR8-Assemblerprogramm für einen ATmega88PA 
im Auslieferungszustand enstanden, das mittels ATMEL STUDIO 7 
programmiert wurde.

Es verwendent lediglich vier Vergleiche um die Handencoderdrehrichtung 
zu erkennen. Arbeit also nicht mit der üblichen LUT programmierweise.

Alle weiteren Informationen in der Header.inc & Hardware.inc

Als Vorlagen bzw. wie man so etwas überhaupt realisieren kann diente mir 
:

https://www.mikrocontroller.net/articles/Drehgeber

und Vorallem Hannes Lux sein Programmausschnitt

Beitrag "Re: Hilfe zu Drehencoder-Auswertung nach Wiki"


Bernd_Stein

Autor: Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ach, habe vergessen zu erwähnen, das der Handencoder von *Panasonic EVEQ 
DBRL416B*
beim nach links drehen, also gegen den Uhrzeigersinn ( C.C.W ) in einer 
oder einigen Raststellungen ziemlich heftig prellt.
Die B-Spur schaltet nämlich direkt an den Rastungen und dies führt in 
einigen Raststellungen zum sofortigen Schalten bei minimalem Drehwinkel.

Man kann das Programm auch sehr gut zum Testen von Handencodern 
benutzen.
In jeder Raststellung dreht man mehrmals eine Rastung vor und wieder 
zurück und sieht sich dabei an was die LEDs an PortB machen.

Der Encoder ist wie im DB gezeigt beschaltet.


Bernd_Stein

Autor: Falk B. (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernd S. schrieb:
> Ach, habe vergessen zu erwähnen, das der Handencoder von *Panasonic EVEQ
> DBRL416B*
> beim nach links drehen, also gegen den Uhrzeigersinn ( C.C.W ) in einer
> oder einigen Raststellungen ziemlich heftig prellt.

Dagegen hilft die passende Auswertung.

https://www.mikrocontroller.net/articles/Drehgeber#Dekoder_f.C3.BCr_Drehgeber_mit_wackeligen_Rastpunkten

Geht auch in Assembler.

Autor: Falk B. (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm, 12 Warnung sind nicht so dolle für so ein kleines Projekt.

Severity  Code  Description  Project  File  Line
Warning    .def: 'YH' redefinition (r29->r29)  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  67
Warning    .def: 'XH' redefinition (r27->r27)  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  65
Warning    .def: 'XL' redefinition (r26->r26)  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  64
Warning    .def: 'YL' redefinition (r28->r28)  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  66
Warning    .def: 'ZH' redefinition (r31->r31)  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  69
Warning    .def: 'ZL' redefinition (r30->r30)  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  68
Warning    Register r26 already defined by the .DEF directive  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  64
Warning    Register r27 already defined by the .DEF directive  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  65
Warning    Register r28 already defined by the .DEF directive  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  66
Warning    Register r29 already defined by the .DEF directive  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  67
Warning    Register r30 already defined by the .DEF directive  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  68
Warning    Register r31 already defined by the .DEF directive  Einfache Motorsteuerung  C:\Users\Brunner.000\Downloads\Einfache Motorsteuerung\Header.inc  69

: Bearbeitet durch User
Autor: Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)
Datum:

Bewertung
-4 lesenswert
nicht lesenswert
Falk B. schrieb:
> Dagegen hilft die passende Auswertung.
>
> 
https://www.mikrocontroller.net/articles/Drehgeber#Dekoder_f.C3.BCr_Drehgeber_mit_wackeligen_Rastpunkten
>
> Geht auch in Assembler.
>
Dann mach mal ;-)
Wie bereits erwähnt kenne ich den Artikel.

>
> Hmmm, 12 Warnung sind nicht so dolle für so ein kleines Projekt.
>
Hmm, das hätte ich jetzt nicht von dir erwartet, dass du nicht erkennst 
das diese Warnungen lediglich kommen, weil die X,Y und Z-Register die 
wahrscheinlich in der .def schon so benannt worden sind, ich ebenfalls 
so benannt habe ( r26 -> xl, r27 -> xh usw. ).


Bernd_Stein

Autor: c-hater (Gast)
Datum:

Bewertung
5 lesenswert
nicht lesenswert
Bernd S. schrieb:

> Wie bereits erwähnt kenne ich den Artikel.

Warum nutzt du sinnvolle Konzepte nicht, wenn du sie schon kennst?

> Hmm, das hätte ich jetzt nicht von dir erwartet, dass du nicht erkennst
> das diese Warnungen lediglich kommen, weil die X,Y und Z-Register die
> wahrscheinlich in der .def schon so benannt worden sind, ich ebenfalls
> so benannt habe ( r26 -> xl, r27 -> xh usw. ).

Natürlich hat er das verstanden.

Was du allerdings nicht verstehst: Warnungen sind da, um zu Warnen. Wenn 
du die Warnung geprüft hast und dir sicher bist, das das so in Ordnung 
geht, dann sorge dafür, dass die Warnung verschwindet, damit erstens 
niemand davon unnötig irritiert wird und zweitens neue Warnungen im Zuge 
von Codeänderungen oder -erweiterungen nicht in der Flut alter (bereits 
als unberechtigt verifizierter) Warnungen untergehen.

So geht Software-Entwicklung. Auch (und gerade) in Assembler. Da gibt es 
nämlich weiss Gott genug Fallstricke und wenig Möglichkeiten für den 
Assembler, dem Programmierer zu helfen. Da nutzt man dann wenigstens 
konsequent die, die es gibt.

Das Zauberwort in diesem Fall heisst: .undef

Autor: Uhu U. (uhu)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
c-hater schrieb:
> Auch (und gerade) in Assembler.

Dem echt harten Hund sind Warnungen schnuppe. .undef ist was für 
Weicheier ;-)

Autor: Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
c-hater schrieb:
> Das Zauberwort in diesem Fall heisst: .undef
>
Das nenne ich doch mal sinnvolle Kritik.
Gefällt mir jetzt auch besser wenn keine Warnungen da sind.

>
> Warum nutzt du sinnvolle Konzepte nicht, wenn du sie schon kennst?
>
Würd mich ja interessieren, ob dies wirklich sinnvoller ist und mit 
meiner Breadboardschaltung testen, aber es gibt ja kein fertiges 
AVR8ASM-Programm und erst recht nicht für den ATmega88.

Übrigens es ist von Vorteil an der L298N-Platine, bei der ich beide 
Ausgänge und Signaleingänge parallel verschaltet habe, den EN-Eingang 
mit einem Pulldown-Widerstand zu versehen, da es beim Einschalten der 
Versorgungsspannung sonst für einen Augenblick zu einem ungewolltem 
Drehen des Motors kommen kann.

Ich habe auch die IB_2-Platine mit dem BTS7960, dort wäre es von 
Vorteil den High-Side-Zweig beim Bremsen zu nutzen da dieser besser 
leitet, aber Programmtechnisch ist dies aufwändiger.

Beitrag "Re: Motorsteuerung mit L298N und Attiny"

Beitrag "BTS7960B_IBT_2 Chinaplatine"


Bernd_Stein

: Bearbeitet durch User
Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernd S. schrieb:

> Würd mich ja interessieren, ob dies wirklich sinnvoller ist

Ist es natürlich, das sagen schon die Gesetze der Logik. Wenn eine 
Hardware einen systemimmanenten Mechanismus anbietet, um mögliche Fehler 
zu unterdrücken, dann nutzt man den natürlich.

> und mit
> meiner Breadboardschaltung testen, aber es gibt ja kein fertiges
> AVR8ASM-Programm und erst recht nicht für den ATmega88.

So what? Du bist Programmierer.

Übrigens muss man den Mechanismus nicht sklavisch so abbilden, wie in 
der Vorlage. Für einen einzelnen schnellen Encoder wäre das suboptimal. 
Die Vorlage nutzt den Mechanismus effizent für mehrere, relativ langsame 
Encoder.

Der Kern ist also, den Mechanismus zu verstehen. Die Implementierung 
kann dann ganz erheblich von der Vorlage abweichen. Sogar so sehr, das 
das gemeinsame Konzept kaum noch erkennbar ist.

Autor: Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
c-hater schrieb:
> So what? Du bist Programmierer.
>
Nein - vielleicht du.

Ich merke schon, jetzt wird wieder nur rumgequatscht aber nicht konkret 
daraufhin gearbeitet eine AVR8-Assemblerversion aus dem µC-Artikel zum 
Drehgeber zu erstellen, damit ich beide Versionen mal austesten kann.

In meinen Theorien klappen die Mechanismen auch immer wunderbar.
Wenn ihr also nur rumquatschen wollt, dann mach ich dabei nicht mehr 
mit.


Bernd_Stein

Autor: Karl M. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Bernd S.,

für LunaAVR verwenden wir schon seit Anfang an, nur eine Assembler 
Version.
Da das interne FrameWork auf Assembler implementierte Bibliotheken 
(Interface und Module) basiert.

https://avr.myluna.de/doku.php?id=de:download

Wenn es Dich interessiert, schau mal in das Interface "KeyMgr", eine 
kurze Beschreibung steht im Interface auch direkt drin.

Anbei einige Bilder dort hin.

Hier ist ein Beispielcode, man kann sich auch die erzeugte 
Assemblerausgabe in der *.s Datei ansehen.
'---------------------------------------
' KeyManager Samble Code
' 2019-08-06
'---------------------------------------

'---------------------------------------
' System Settings
'---------------------------------------
const F_CPU = 8000000
avr.device   = atmega328p
avr.clock  = avr.F_CPU
avr.stack  = 42

'---------------------------------------
' Macros
'---------------------------------------
#define BV(n)  as (1<<(n))
#define NBV(n)  as (not BV(n))

#macro BEGIN_ATOMIC
asm
xIn _TMP0,SREG
cli
endasm
#endmacro

#macro END_ATOMIC
asm
xOut   SREG,_TMP0
endasm
#endmacro

'---------------------------------------
' Library
'---------------------------------------
#library "Library/KeyMgr.interface"
#library "Library/Wdt.interface"

part I/O Ports
// Tasten
#define SW1    as PORTB.0
#define SW2    as PORTB.1
#define KEY_PORT  as PORTB

const SW1_BIT    = 0
const SW1_MASK    = BV(SW1_BIT)
const SW2_BIT    = 1
const SW2_MASK    = BV(SW2_BIT)
endpart

'---------------------------------------
' Init
'---------------------------------------
part I/O Ports
// Tasten
// nur der Vollständigkeit halber.
SW1.mode = input, pullup
SW2.mode = input, pullup
endpart

part KeyManager
const KEYMGR_CYCLE_TIME = 16 ' ms, see WDT settings

const KEYMGR_MASK    = (SW1_MASK or SW2_MASK)
const KEYMGR_REPEAT_MASK = 0 ' no key with repeat function

KeyMgr.RepeatTime    = word(300/ KEYMGR_CYCLE_TIME +.5)
KeyMgr.LongPressTime = word(800/ KEYMGR_CYCLE_TIME +.5)
KeyMgr.InterruptMode = 1
KeyMgr.Init(KEY_PORT, KEYMGR_MASK, KEYMGR_REPEAT_MASK, 0) ' run on timer interrupt

WDT_Init()
endpart

avr.Interrupts.Enable()

do

// Taster gedrückt
if KeyMgr.KeyPress(SW1_MASK) then
' ...
endif

if KeyMgr.KeyPress(SW2_MASK) then
' ...
endif

// Taster losgelassen
if KeyMgr.KeyRelease(SW1_MASK) then
' nur ein Beispiel
endif

if KeyMgr.KeyRelease(SW2_MASK) then
' nur ein Beispiel
endif


loop

' Main Sub-Functions

procedure WDT_Init()
WDT.isr = WDT_vect
WDT.Clock = 16ms
WDT.mode = Interrupt
endproc

isr WDT_vect fastauto
avr.KeyMgr.Debounce() ' <-- call KeyManager Debounce
endisr

Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl M. schrieb:

> Wenn es Dich interessiert, schau mal in das Interface "KeyMgr", eine
> kurze Beschreibung steht im Interface auch direkt drin.

Das ist völlig ungeeignet, denn es nutzt gerade nicht die Besonderheit 
von Rotationsencodern. Das ist für Taster. Sagt ja auch schon allein der 
Name...

Kann mann allenfalls für den "Drücker" eines handbetätigten Encoders 
nutzen.

Autor: Karl M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
c-hater schrieb:
> Karl M. schrieb:
>
>> Wenn es Dich interessiert, schau mal in das Interface "KeyMgr", eine
>> kurze Beschreibung steht im Interface auch direkt drin.
>
> Das ist völlig ungeeignet, denn es nutzt gerade nicht die Besonderheit
> von Rotationsencodern. Das ist für Taster. Sagt ja auch schon allein der
> Name...
>
> Kann mann allenfalls für den "Drücker" eines handbetätigten Encoders
> nutzen.

Danke,

korrekt, da habe ich mich vertan.

Für Drehencoder findet man auch das entsprechende 
RotaryEncoder.interface im Datenbestand.

Einen 4-fach Version gibt es auch noch auf meiner Festplatte.

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.

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