Forum: Mikrocontroller und Digitale Elektronik AVR STK500: Motoransteuerung / einfaches Assemblerprogramm


von Alecsx (Gast)


Lesenswert?

Hi!

Ich habe seit kurzem ein STK500 und will mit dem ATmega8515 einen 
12V-Motor ansteuern.
Die Hardware stimmt soweit, von einem PIN des Boards geht es auf einen 
Optokoppler (und wieder zurück auf GND), der Optokoppler gibt das ganze 
an einen Leistungstransistor weiter, der letzten Endes den Motor 
bestromt.

Bisher bediene ich mich eines kleinen Tricks: Ich habe das 
vorinstallierte Beispiel-Programm auf dem STK500 so umgeschrieben, dass 
nurnoch der Zähler funktioniert. Nun schließe ich entsprechend den PIN 
an den Optokoppler an, der 2^0 repräsentiert. Folglich läuft der Motor 
bei allen ungeraden Zahlen, bei den geraden Zahlen steht er. 
(Funktioniert so auch wirklich!)

Ich würde das ganze jetzt gerne mit einem "richtigen" Programm 
realisieren, nur leider weis ich nicht sorecht wo ich anfangen soll - 
trotz Einlesen in mehrere Tutorials. An und für sich dürfte das Programm 
ja nur so 10 Zeilen Code haben. Im Wortlaut ungefähr so:

Wenn Switch0 betätigt wird, lege HIGH auf PB00 (Pin0 PortB). Wird 
Switch1 betätigt, lege LOW auf PB00. Die Switches liegen z.B. auf PortD 
und geben laut Datasheet eine 1 aus (sind also "Öffner"). Folglich: Wenn 
PD00 (Pin 0 Port D) == 0, lege HIGH auf PB00, usw. Das sind allerdings 
Taster, also nicht direkt "lege HIGH sobald PD00 == 0", sondern das 
ganze über Zwischenspeicher lösen, damit man nicht den Knopf gedrückt 
halten muss, um den Motor anzusteuern.

So, soweit gehen meine Gedanken bisher, eventuell könnte sie ja jemand 
etwas ausarbeiten und mir die für das Programm nötigen Befehle 
schmücken. Eine Erklärung, dass ich das alles auch noch verstehe, wäre 
spitze! Komm nicht sorecht weiter ...

Vielen Dank schonmal.

von Krapao (Gast)


Lesenswert?

Umgearbeitetes Beispiel aus Entprellung müsste passen

1
/************************************************************************/
2
/*                                                                      */
3
/*                      Not so powerful Debouncing Example              */
4
/*                      No Interrupt needed                             */
5
/*                                                                      */
6
/*              Author: Peter Dannegger                                 */
7
/*                                                                      */
8
/************************************************************************/
9
10
#include <avr/io.h>
11
#include <util/delay.h>
12
13
#define debounce( port, pin )                                         \
14
({                                                                    \
15
  static uint8_t flag = 0;     /* new variable on every macro usage */  \
16
  uint8_t i = 0;                                                      \
17
                                                                      \
18
  if( flag ){                  /* check for key release: */           \
19
    for(;;){                   /* loop ... */                         \
20
      if( !(port & 1<<pin) ){  /* ... until key pressed or ... */     \
21
        i = 0;                 /* 0 = bounce */                       \
22
        break;                                                        \
23
      }                                                               \
24
      _delay_us( 98 );         /* * 256 = 25ms */                     \
25
      if( --i == 0 ){          /* ... until key >25ms released */     \
26
        flag = 0;              /* clear press flag */                 \
27
        i = 0;                 /* 0 = key release debounced */        \
28
        break;                                                        \
29
      }                                                               \
30
    }                                                                 \
31
  }else{                       /* else check for key press: */        \
32
    for(;;){                   /* loop ... */                         \
33
      if( (port & 1<<pin) ){   /* ... until key released or ... */    \
34
        i = 0;                 /* 0 = bounce */                       \
35
        break;                                                        \
36
      }                                                               \
37
      _delay_us( 98 );         /* * 256 = 25ms */                     \
38
      if( --i == 0 ){          /* ... until key >25ms pressed */      \
39
        flag = 1;              /* set press flag */                   \
40
        i = 1;                 /* 1 = key press debounced */          \
41
        break;                                                        \
42
      }                                                               \
43
    }                                                                 \
44
  }                                                                   \
45
  i;                           /* return value of Macro */            \
46
})
47
 
48
//
49
// Testapplikation für
50
// http://www.mikrocontroller.net/topic/241147#2451586
51
// 
52
int main(void)
53
{
54
  DDRB |= (1<<PB0);
55
  DDRB |= (1<<PB1);
56
  // Defaultwerte: 
57
  // PORTB.0 Ausgang low
58
  // PORTB.1 Ausgang low
59
  // PIND.0 Eingang, externer Pull-up = SWITCH0 active-low
60
  // PIND.1 Eingang, externer Pull-up = SWITCH1 active-low
61
62
  for(;;)
63
  {
64
    if( debounce( PIND, PD0 ) )
65
      PORTB ^= 1<<PB0;
66
    if( debounce( PIND, PD1 ) )
67
      PORTB ^= 1<<PB1;
68
  }
69
}

von Krapao (Gast)


Lesenswert?

> An und für sich dürfte das Programm ja nur so 10 Zeilen Code haben.

Inkl. Entprellung in Assembler eher nicht, siehe oben.

von spess53 (Gast)


Lesenswert?

Hi

>Umgearbeitetes Beispiel aus Entprellung müsste passen

Klasse Assemblerprogramm!

MfG Spess

von Krapao (Gast)


Lesenswert?

Ja ja, reite nur drauf rum :-)

von Karl H. (kbuchegg)


Lesenswert?

Schaut mir nach einem Fall für das
AVR-Tutorial
aus.

In aller Kürze: Was du vor hast, sieht zwar einfach aus, ist es aber 
nicht. Tastenentprellung ist schon etwas komplexer und kommt im Tut erst 
relativ spät vor.

Wenn ich mir deine Ausdrucksweise allerdings so ansehe, solltest du das 
Tut aber eher von vorne weg durchmachen.

von Jan Steiner (Gast)


Lesenswert?

@Alecsx

Leistungstransistoren sind keine Energiequellen, ergo können sie keinen 
Motor bestromen, und genau hier fängt dein Problem an.

Du hast Null Ahnung.

von Uwe (Gast)


Lesenswert?

Hi!
ohne entprellen, mit Sicherheitsinit, aus ist dominant:
1
     ldi  R16, low(Ramend)
2
     out  SPL,R16
3
     ldi  R16,high(Ramend)
4
     out  SPH,R16
5
     clr  R16
6
     out  PortB,R16
7
     out  PortD,R16
8
     ldi  R16,(1<<Pinb0)
9
     out  DDRB,R16
10
     ldi  R16,(1<<Pind0|1<<Pind1)
11
     out  Portd,R16
12
HP:  sbis Pind,1
13
     cbi  Portb,0
14
     sbis Pind,0
15
     sbi  Portb,0
16
     rjmp HP

Viel Erfolg, Uwe

von Uwe (Gast)


Lesenswert?

Mist verschrieben, jetzt aber

Hi!

ohne entprellen, mit Sicherheitsinit, aus ist dominant:
1
     ldi  R16, low(Ramend)
2
     out  SPL,R16
3
     ldi  R16,high(Ramend)
4
     out  SPH,R16
5
     clr  R16
6
     out  PortB,R16
7
     out  PortD,R16
8
     ldi  R16,(1<<Pinb0)
9
     out  DDRB,R16
10
     ldi  R16,(1<<Pind0|1<<Pind1)
11
     out  Portd,R16
12
HP:  sbis Pind,0
13
     sbi  Portb,0
14
     sbis Pind,1
15
     cbi  Portb,0
16
     rjmp HP

von Alecsx (Gast)


Lesenswert?

@Jan Steiner:
Klar, das dass ein Leistungstransistor keine Energiequelle ist, der 
Motor wird zwischen + und Kollektor reingeschalten, die Basis vom 
Leistungstransistor liegt am Optokoppler. Wie schon gesagt: Die Hardware 
passt soweit, der Motor läuft ja schließlich mit dem Beispielprogramm.

Und wenn ich mir das Beispielprogramm so ansehe:
1
[...]
2
.def Temp =r16 ; Temporary register
3
[...]
4
sbis PIND,0x00 ; If (Port D, pin0 == 0)
5
inc Temp ; then count LEDS one down
6
sbis PIND,0x01 ; If (Port D, pin1 == 0)
7
inc Temp ; then count LEDS one up
8
[...]

müsste ich den Befehl doch eigentlich nur so anpassen, dass anstelle von 
"then count LEDs one up" mein einzelner pin auf high gesetzt wird. Wäre 
das nicht über eine Konstante denkbar? Eben 1 und 0. Also anstelle von 
inc eine Konstante einlesen, und mit dem andern Switch (Port D, pin 1) 
die Konstante durch eine andere (-> 0) ersetzen.
So nach dem Motto:
1
[...]
2
;Code-Ausschnitt!
3
sbis PIN,0x00
4
LDI Temp, 1
5
sbis PIN,0x01
6
LDI Temp, 0
7
[...]

Najo auf jeden Fall danke schonmal für alle hilfreichen Antworten!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.