Forum: Mikrocontroller und Digitale Elektronik Atmega8 als Servo Switch


von Sven F. (mr_sven)


Angehängte Dateien:

Lesenswert?

Hallo,
Ich hab da nen kleines Problem.
Mein Ziel ist es über einen Atmega8 8 Servos an zu Steuern, dass heißt 
ich habe 5 Servo Eingänge, wovon 4 jeweils auf 4 Servoausgänge 
geschaltet werden.
Die Umschaltung erfolgt über den 5. Eingang.
Die Servos die nicht angesteuert werden sollen dann in eine 
Defaultposition fahren.
Diese Defaultpositionen sollen dann über 3 Taster (INC,DEC,SERVO) 
eingestellt werden.

Momentan bin ich erstmal dabei das Programm für die 
Defaultpositionierung zu scheiben.

Dazu lege ich über einen Timer den 20ms Puls für alle Servos fest und 
über einen Counter für jedes Servos die entsprechende Länge des Puls.
Das Funktioniert soweit.
Wenn ich jetzt allerdings eine der Tasten drücke macht der ganze Atmel 
einen Neustart, dies habe ich nur herausfinden können weil das Servo 
Kurz zuckt und wieder in die Ausgangsposition fährt.
Testweise hatte ich nach dem Incrementieren oder Decrementieren die 
Werte in den EEPROM übernommen, dann hatte das Servo die Position auch 
nach dem Neustart gehalten, nur leider ist das erstens unschön, und 
zweitens macht das Servo beim Starten des Atmels natürlich erstmal 
Sprünge bis die Werte aus dem EEPROM wieder geladen sind.

Jetzt meine Frage, kann es was mit der Doppelbelegung der Ports zu tun 
haben, oder wie ich die Tasten angeschlossen habe?
Ich bin ziemlich ratlos.

von Karl H. (kbuchegg)


Lesenswert?

Sven Fabricius schrieb:

> Wenn ich jetzt allerdings eine der Tasten drücke macht der ganze Atmel
> einen Neustart, dies habe ich nur herausfinden können weil das Servo
> Kurz zuckt und wieder in die Ausgangsposition fährt.


Wenn ein Servo anfährt und dein µC in diesem Moment abstürzt, dann liegt 
das Problem in der Versorgungsspannung. Servos können ziemliche Schweine 
sein, bei dem was sie auf der Versorungsspannung an Schmutz einkoppeln. 
Den musst du loswerden.
Am besten wäre es, wenn die Servos ihre eigene Versorgungsspannung 
komplett getrennt von der µC-Versorgungsspannung hätten. Wenn das nicht 
geht, musst du Spulen und oder Kondensatoren einbauen, die dir den 
Schmutz vom µC fernhalten.

Das du dem Mega8 nicht mal die üblichen 100nF an den Versorgungspins 
spendiert hast, ist eigentlich nur mit einem Wort zu beschreiben: 
leichtsinnig

von holger (Gast)


Lesenswert?

>Das du dem Mega8 nicht mal die üblichen 100nF an den Versorgungspins
>spendiert hast, ist eigentlich nur mit einem Wort zu beschreiben:
>leichtsinnig

Noch leichtsinniger ist es die 330nF zu schalten.
Wenn die leer sind ziehen sie beim schalten kurzfristig
sehr viel Strom. Die 330nF gehören parallel zum Schalter
und nicht zum Pullup/down.

von Sven F. (mr_sven)


Lesenswert?

Den 100nF hatte ich jetzt in der Zeichnung nicht berücksichtigt, ist 
aber drinne. Hatte das ganze auf nem Streifenraster aufgebaut.

Habe zur Spannungsversorung mal 5V 1,5A angeschlossen und gehofft das 
würde helfen.

Das komische ist, dass der Atmel auch resettet auch wenn ich die Servo 
Wechsel Taste drücke die garkeine Positionsveränderung auslößt.

von Sven F. (mr_sven)


Lesenswert?

Das mit dem Taster hatte ich einfach blanco von nem Eval Board 
übernommen, aber werd die mal parallel drauf schalten.

von Karl H. (kbuchegg)


Lesenswert?

Sven Fabricius schrieb:
> Das mit dem Taster hatte ich einfach blanco von nem Eval Board
> übernommen, aber werd die mal parallel drauf schalten.

Lass sie weg.
Tastenentprellen kann man prima in Software.

http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29

Da kriegst du dann als Zugabe auch noch gratis, dass du auf dem Taster 
draufbleiben kannst, und die Entprellroutine liefert dir ständig 
Tastendruck-Impulse. Ideal für dich, oder willst du die Defaultposition 
von links nach rechts ändern, indem du 200 mal auf die Taste drückst?

Und Tasten baut man bei AVR's so ein, dass sie nach Masse schalten. Dann 
kann man den im µC eingebauten Pullup Widerstand benutzen.

von Sven F. (mr_sven)


Lesenswert?

Ok, war mir mit den Tasten immer nicht so sicher, im bezug auf 
Fehlerquellen.
Wenn ich die Tasten gegen Masse schalte, dann muss ich die Abfrage der 
Tasten dann aber invertiern, oder?

von Sven F. (mr_sven)


Lesenswert?

Ach ne, sorry hab mich verguckt

von Karl H. (kbuchegg)


Lesenswert?

Sven Fabricius schrieb:
> Ach ne, sorry hab mich verguckt

Nein, stimmt schon.
Aber wenn du die verlinkten Source Code Quelle benutzt, brauchst du dich 
nicht mehr um die Details kümmern. Einfach ein paar #define richtig 
stellen und so wie in der Demo gezeigt abfragen. Fertig.

1
#define KEY_DDR         DDRC
2
#define KEY_PORT        PORTC
3
#define KEY_PIN         PINC
4
#define KEY_SELECT      0
5
#define KEY_LEFT        1
6
#define KEY_RIGHT       2
7
#define ALL_KEYS        (1<<KEY_SELECT | 1<<KEY_LEF | 1<<KEY_RIGHT)
8
 
9
#define REPEAT_MASK     (1<<KEY_LEFT | 1<<KEY_RIGHT)
10
11
....
12
13
14
#define NR_SERVOS  5
15
16
uint8_t ServoNr;
17
uint8_t ServoPos[NR_SERVOS];
18
19
...
20
21
int main()
22
{
23
24
  ...
25
26
  ServoNr = 0;
27
28
  while(1){
29
    if( get_key_short( 1<<KEY_SELECT )) {
30
      ServoNr++;
31
      if( ServoNr == NR_SERVOS )
32
        ServoNr = 0;
33
    }
34
 
35
    if( get_key_press( 1<<KEY_LEFT ) || get_key_rpt( 1<<KEY_LEFT )) {
36
      ServoPos[ ServoNr ]++;
37
    }
38
39
    if( get_key_press( 1<<KEY_RIGHT ) || get_key_rpt( 1<<KEY_RIGHT )) {
40
      ServoPos[ ServoNr ]--;
41
    }
42
43
    ...
44
  }
45
}

von Sven F. (mr_sven)


Lesenswert?

danke, werde das heute Abend testen, das mit dem array ist ne super 
idee, hatte daran noch garnicht gedacht.

von Josh (Gast)


Lesenswert?

Hallo,

ich habe genau dasselbe Problem mit Atmega32 auf 
Pollin-Atmel-Evaluationsboard-V201.
Die Beschaltung der Taster 33k/330n scheint vom Pollin-Board zu sein.
Getrennte Versorgung des Servo bringt bei mir keinen Unterschied.
Tastendrücke führen gelegentlich/häufig zu Reset.

Kann das jemand bestätigen, dass die Ladestromspitzen bei der 
Beschaltung einen Reset auslösen können?
Ist das bei dem Pollin-Atmel-Evaluationsboard-V201 so?

Danke
Josh

von Sven F. (mr_sven)


Lesenswert?

Bestätigen kann ich das nicht, aber es ist möglich, da ich die Schaltung 
der Taster auch übernommen habe.

von Alexander S. (esko) Benutzerseite


Lesenswert?

Josh schrieb:
> Getrennte Versorgung des Servo bringt bei mir keinen Unterschied.
> Tastendrücke führen gelegentlich/häufig zu Reset.

Teste es doch einfach mal indem du den Servo abklemmst. Drückst du dann 
einen Taster und er resetet immer noch, lag es am Servo.

Aus meiner Erfahrung kann ich sagen, dass die Servos unheimlich die 
Versorgung versauen. Daher auf jeden Fall entkoppeln. Am einfachsten ein 
zweites Netzteil dazu hängen und GNDs verbinden.
Oder ein zweiter 7805.

1,5A erscheint mir für 8 Servos, die gleichzeitig bewegt werden zu 
knapp. Kommt natürlich auf die Größe und die Last an.

von Sven F. (mr_sven)


Lesenswert?

Später soll das ganze über eine entsprechende Versorgung ermöglicht 
werden, aber momentahn ist 1 maximal 2 Servos dran zum testen.

von Josh (Gast)


Lesenswert?

Ich habe jetzt auch nochmal gesucht und in

[[http://www.mikrocontroller.net/articles/Pollin_ATMEL_Evaluations-Board]]

wird die Problematik mit den Tastern angesprochen. Ich werde testen ob
es bei mir ohne Benutzung der Taster keine Resets mehr gibt.

von Sven F. (mr_sven)


Lesenswert?

Hatte gestern leider keine Zeit um das zu testen, hoffe heute Abend.

von Sven F. (mr_sven)


Lesenswert?

Also, habe gestern das alles nochmal getestet, und ich muss sagen es 
geht.
Die Pollin Tasterschaltung löst definitiv einen Reset aus auch bei 1,5 A 
Stromversorgung und ohne Servo.

Jetzt komme ich natürlich so langsam an die Grenzen des Atmegas.
Habe den Code jetzt soweit optimiert dass ich gerade mal eine Auflösung 
von 50 Positionen habe.
Dabei habe ich noch nicht mal die Eingänge programmiert.
Ich könnte den Atmel zwar noch auf 16MHz takten aber, das bringt mir 
gerade mal 100 Positionen und eigentlich wollte ich ne auflösung von 200 
haben, vieleich sollte ich auf nen anderen Atmel wechseln oder das 
irgentwie aufteilen.

von Peter (Gast)


Lesenswert?

> Jetzt komme ich natürlich so langsam an die Grenzen des Atmegas.

Das glaube ich kaum, meist liegt die Grenze an der Software. Wenn man 
mit C schreibt kann es sehr schnell passieren das man etwas 
ungeschicktes macht und damit sehr viel rechenzeit verbraucht ohne das 
zu wissen.

z.b. ein binary Shift  mit Variablen.

Wenn der Code nicht zu geheim ist, dann lass ihn mal sehen. Es finden 
sich bestimmt genug stellen um entwas zu optimiern.

von Sven F. (mr_sven)


Lesenswert?

Ja, also er Code is natürlich nicht geheim, hab ihn aber gerade nicht 
zur hand, aber ich denke ich kann einiges aus dem Kopf was wichtig ist
1
...
2
#define SERVOPORT RORTD
3
#define Servo0 PD0
4
#define Servo1 PD1
5
#define Servo2 PD2
6
#define Servo3 PD3
7
#define Servo4 PD4
8
#define Servo5 PD5
9
#define Servo6 PD6
10
#define Servo7 PD7
11
12
unsigned int ServoCnt[8];
13
unsigned int ServoUp;
14
15
16
ISR( TIMER1_COMPA_vect )
17
 {
18
  cli();
19
  ServoUp++;
20
  if ( ServoUp == 1000U )   // ServoUp = CPU-Takt / 8 (prescaler) / 20 (Compare) / 50 (20ms)
21
   {
22
     SERVOPORT = 0xFF;
23
     ServoUp = 0U;
24
   }
25
  if ( ServoUp == ServoCnt[0] ) SERVOPORT &= ~( 1<<Servo0 );
26
  if ( ServoUp == ServoCnt[1] ) SERVOPORT &= ~( 1<<Servo1 );
27
  if ( ServoUp == ServoCnt[2] ) SERVOPORT &= ~( 1<<Servo2 );
28
  if ( ServoUp == ServoCnt[3] ) SERVOPORT &= ~( 1<<Servo3 );
29
  if ( ServoUp == ServoCnt[4] ) SERVOPORT &= ~( 1<<Servo4 );
30
  if ( ServoUp == ServoCnt[5] ) SERVOPORT &= ~( 1<<Servo5 );
31
  if ( ServoUp == ServoCnt[6] ) SERVOPORT &= ~( 1<<Servo6 );
32
  if ( ServoUp == ServoCnt[7] ) SERVOPORT &= ~( 1<<Servo7 );
33
  sei();
34
 }   // laut Disassembler so ca 87 Schritte
35
     // muss also dem Compare ein bisschen puffer für andere Instruktionen geben,
36
     // hier jetzt 160 Schritte.
37
 
38
...
39
 
40
int main(void)
41
 {
42
   TCCR1B = (1<<CS11)|(1<<WGM12);  // prescaler = CPU-Takt / 8
43
   OCR1A = 20;                     // Compare = 160 Schritte / 8
44
   TIMSK = (1<<OCIE1A);
45
   sei();
46
47
   ...  // Funktionen für tasten etc.
48
 }

von Peter (Gast)


Lesenswert?

was soll denn das cli(); und das  sei(); dafür ist der Compiler da, das 
sollte man nur in der main verwenden um kurzeitig zu verhindern das ein 
interupt aufgerufen wird.

Dann könnte man das ganze sehr stark optimieren, was aber ein größere 
Umbau ist.


du müssten intern die Daten so ablegen das du in der ISR sie direkt 
verwenden kannst.

>  if ( ServoUp == ServoCnt[0] ) SERVOPORT &= ~( 1<<Servo0 );
SERVOPORT = Daten[ ServoUp ]

das ganze braucht aber recht viel speicher 1000 * 8 byte. Da müsste man 
sich noch etwas einfallen lassen und es sinnvoller zu speichern.

von Sven F. (mr_sven)


Lesenswert?

Mit dem cli und sei wollte ich nur verhindern das der Interupt ncht 
durch den für die tasten unterbrochen wird.

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:

> du müssten intern die Daten so ablegen das du in der ISR sie direkt
> verwenden kannst.
>
>>  if ( ServoUp == ServoCnt[0] ) SERVOPORT &= ~( 1<<Servo0 );

> SERVOPORT = Daten[ ServoUp ]

Äh. Nein
ServoUp ist bei ihm der PWM Zähler

von Karl H. (kbuchegg)


Lesenswert?

Sven Fabricius schrieb:
> Mit dem cli und sei wollte ich nur verhindern das der Interupt ncht
> durch den für die tasten unterbrochen wird.

Das wird er sowieso nicht.
In einer ISR sind Interrupts automatisch gesperrt und sie werden auch 
automatisch wieder freigegeben.

Und nein, es ist nicht egal ob du selbst das sei() in der ISR machst. 
Machst du das selbst, dann erfolgt das sei() einen Tick zu früh.

von Peter (Gast)


Lesenswert?

dann lies dir erstmal die Doku von den Atmels durch. Ein Iterrupt kann 
nicht durch einen anderen Interupt unterbrochen werden. Durch dein 
sei(); hast du aber genau das erreicht und schlimmsten fall der Stack 
überläuft.

von Peter (Gast)


Lesenswert?

> ServoUp ist bei ihm der PWM Zähler
und warum sollte das dageben sprechen? Damit kann du mit einer zuweisung 
alles erledigen. Braucht aber leider viel speicher.

von Karl H. (kbuchegg)


Lesenswert?

Was noch was bringen würde: wenn es dir gelingt die unsigned int auf 
unsigned char runterzuholen. Die Arithmetik bzw. die Vergleiche brauchen 
dann nur noch die halbe Taktanzahl

von Sven F. (mr_sven)


Lesenswert?

Die Idee mit
> SERVOPORT = Daten[ ServoUp ]
ist garnicht so blöd weil ich ja wenn dann nur ne auflösung von 200 
Schritten haben will, dass heist ich müsste dann nur 200 * 1 Byte in dem 
Array haben.

if ( ServoUp >= 200 && ServoUp < 400 )
 SERVOPORT = Daten[ ServoUp - 200 ];

schwieriger ist dann nur die INC und DEC geschichten zu realisieren, 
allerdings sind diese dann nicht Zeitkritisch.

von Sven F. (mr_sven)


Lesenswert?

Sowas is mir gerade durch den Kopf gegangen.

DEC
{
  Daten[ServoCnt[ServoId]] &= ~(1<<ServoId);
  ServoCnt[ServoId]--;
}

INC
{
  ServoCnt[ServoId]++;
  Daten[ServoCnt[ServoId]] |= (1<<ServoId);
}

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:
>> ServoUp ist bei ihm der PWM Zähler
> und warum sollte das dageben sprechen? Damit kann du mit einer zuweisung
> alles erledigen. Braucht aber leider viel speicher.

Ja. Ich habe nicht behirnt, worauf du hinaus willst.
Ein grosses Daten Array in dem die einzelnen Indizes die Zeitachse 
repräsentieren.

von Sven F. (mr_sven)


Lesenswert?

Genau, so in etwa:

Daten:
      1111000 ....
      1100000
      1111000
      1100000

      1111110
      1100000
      1111110
      1100000
| 1ms |

._________
|         |______        Servo 0
._______
|       |________        Servo 1
._________
|         |______        Servo 2
._______
|       |________        Servo 3

.___________
|           |____        Servo 4
._______
|       |________        Servo 5
.___________
|           |____        Servo 6
._______
|       |________        Servo 7

von Karl H. (kbuchegg)


Lesenswert?

Man könnte darüber nachdenken, da so etwas wie ein Run-Length Encoding 
einzubauen, wenn die Größe des Datenarrays ein Problem ist.

Der Update einer Servoposition ist dann zwar besch...eiden, aber die 
Auswertung in der ISR wäre immer noch kein Problem.

von Sven F. (mr_sven)


Lesenswert?

Hab jetzt leider kein WinAVR zur Verfügung,
kann denn jemand mal nach checken wie viele Schritte das sind:
1
unsigned char Daten[200];
2
unsigned int ServoUp;
3
4
ISR( TIMER1_COMPA_vect )
5
 {
6
  ServoUp++;
7
  if ( ServoUp == 1000U )
8
   {
9
     SERVOPORT = 0xFF;
10
     ServoUp = 0U;
11
   }
12
  if ( ServoUp >= 200U && ServoUp < 400U )
13
   SERVOPORT = Daten[ ServoUp - 200U ];
14
 }

von Karl H. (kbuchegg)


Lesenswert?

Nur compiliert.

Die ISR ist exakt 100 Bytes lang (43 Assembler Tokens).
11 Assembler Tokens bilden den Teil

  if ( ServoUp >= 200U && ServoUp < 400U )
   SERVOPORT = Daten[ ServoUp - 200U ];

Wobei der then Zweig aus
  c6:  ee 59         subi  r30, 0x9E  ; 158
  c8:  ff 4f         sbci  r31, 0xFF  ; 255
  ca:  80 81         ld  r24, Z
  cc:  8b bb         out  0x1b, r24  ; 27

besteht.

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
#define SERVOPORT PORTA
5
6
unsigned char Daten[200];
7
unsigned int ServoUp;
8
9
ISR( TIMER1_COMPA_vect )
10
 {
11
  ServoUp++;
12
  if ( ServoUp == 1000U )
13
   {
14
     SERVOPORT = 0xFF;
15
     ServoUp = 0U;
16
   }
17
  if ( ServoUp >= 200U && ServoUp < 400U )
18
   SERVOPORT = Daten[ ServoUp - 200U ];
19
 }
20
21
 int main()
22
 {
23
 }
1
Servo.elf:     file format elf32-avr
2
3
Sections:
4
Idx Name          Size      VMA       LMA       File off  Algn
5
  0 .text         000000ec  00000000  00000000  00000074  2**1
6
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
7
  1 .bss          000000ca  00800060  00800060  00000160  2**0
8
                  ALLOC
9
  2 .debug_aranges 00000020  00000000  00000000  00000160  2**0
10
                  CONTENTS, READONLY, DEBUGGING
11
  3 .debug_pubnames 00000040  00000000  00000000  00000180  2**0
12
                  CONTENTS, READONLY, DEBUGGING
13
  4 .debug_info   000000c0  00000000  00000000  000001c0  2**0
14
                  CONTENTS, READONLY, DEBUGGING
15
  5 .debug_abbrev 00000080  00000000  00000000  00000280  2**0
16
                  CONTENTS, READONLY, DEBUGGING
17
  6 .debug_line   0000009f  00000000  00000000  00000300  2**0
18
                  CONTENTS, READONLY, DEBUGGING
19
  7 .debug_frame  00000030  00000000  00000000  000003a0  2**2
20
                  CONTENTS, READONLY, DEBUGGING
21
  8 .debug_str    00000092  00000000  00000000  000003d0  2**0
22
                  CONTENTS, READONLY, DEBUGGING
23
24
Disassembly of section .text:
25
26
00000000 <__vectors>:
27
   0:  0c 94 2a 00   jmp  0x54  ; 0x54 <__ctors_end>
28
   4:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
29
   8:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
30
   c:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
31
  10:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
32
  14:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
33
  18:  0c 94 3e 00   jmp  0x7c  ; 0x7c <__vector_6>
34
  1c:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
35
  20:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
36
  24:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
37
  28:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
38
  2c:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
39
  30:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
40
  34:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
41
  38:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
42
  3c:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
43
  40:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
44
  44:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
45
  48:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
46
  4c:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
47
  50:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
48
49
00000054 <__ctors_end>:
50
  54:  11 24         eor  r1, r1
51
  56:  1f be         out  0x3f, r1  ; 63
52
  58:  cf e5         ldi  r28, 0x5F  ; 95
53
  5a:  d4 e0         ldi  r29, 0x04  ; 4
54
  5c:  de bf         out  0x3e, r29  ; 62
55
  5e:  cd bf         out  0x3d, r28  ; 61
56
57
00000060 <__do_clear_bss>:
58
  60:  11 e0         ldi  r17, 0x01  ; 1
59
  62:  a0 e6         ldi  r26, 0x60  ; 96
60
  64:  b0 e0         ldi  r27, 0x00  ; 0
61
  66:  01 c0         rjmp  .+2        ; 0x6a <.do_clear_bss_start>
62
63
00000068 <.do_clear_bss_loop>:
64
  68:  1d 92         st  X+, r1
65
66
0000006a <.do_clear_bss_start>:
67
  6a:  aa 32         cpi  r26, 0x2A  ; 42
68
  6c:  b1 07         cpc  r27, r17
69
  6e:  e1 f7         brne  .-8        ; 0x68 <.do_clear_bss_loop>
70
  70:  0e 94 71 00   call  0xe2  ; 0xe2 <main>
71
  74:  0c 94 74 00   jmp  0xe8  ; 0xe8 <_exit>
72
73
00000078 <__bad_interrupt>:
74
  78:  0c 94 00 00   jmp  0  ; 0x0 <__vectors>
75
76
0000007c <__vector_6>:
77
78
unsigned char Daten[200];
79
unsigned int ServoUp;
80
81
ISR( TIMER1_COMPA_vect )
82
 {
83
  7c:  1f 92         push  r1
84
  7e:  0f 92         push  r0
85
  80:  0f b6         in  r0, 0x3f  ; 63
86
  82:  0f 92         push  r0
87
  84:  11 24         eor  r1, r1
88
  86:  2f 93         push  r18
89
  88:  8f 93         push  r24
90
  8a:  9f 93         push  r25
91
  8c:  ef 93         push  r30
92
  8e:  ff 93         push  r31
93
  ServoUp++;
94
  90:  80 91 60 00   lds  r24, 0x0060
95
  94:  90 91 61 00   lds  r25, 0x0061
96
  98:  01 96         adiw  r24, 0x01  ; 1
97
  9a:  90 93 61 00   sts  0x0061, r25
98
  9e:  80 93 60 00   sts  0x0060, r24
99
  if ( ServoUp == 1000U )
100
  a2:  88 5e         subi  r24, 0xE8  ; 232
101
  a4:  93 40         sbci  r25, 0x03  ; 3
102
  a6:  31 f4         brne  .+12       ; 0xb4 <__vector_6+0x38>
103
   {
104
     SERVOPORT = 0xFF;
105
  a8:  8f ef         ldi  r24, 0xFF  ; 255
106
  aa:  8b bb         out  0x1b, r24  ; 27
107
     ServoUp = 0U;
108
  ac:  10 92 61 00   sts  0x0061, r1
109
  b0:  10 92 60 00   sts  0x0060, r1
110
   }
111
  if ( ServoUp >= 200U && ServoUp < 400U )
112
  b4:  e0 91 60 00   lds  r30, 0x0060
113
  b8:  f0 91 61 00   lds  r31, 0x0061
114
  bc:  e8 5c         subi  r30, 0xC8  ; 200
115
  be:  f0 40         sbci  r31, 0x00  ; 0
116
  c0:  e8 3c         cpi  r30, 0xC8  ; 200
117
  c2:  f1 05         cpc  r31, r1
118
  c4:  20 f4         brcc  .+8        ; 0xce <__vector_6+0x52>
119
   SERVOPORT = Daten[ ServoUp - 200U ];
120
  c6:  ee 59         subi  r30, 0x9E  ; 158
121
  c8:  ff 4f         sbci  r31, 0xFF  ; 255
122
  ca:  80 81         ld  r24, Z
123
  cc:  8b bb         out  0x1b, r24  ; 27
124
 }
125
  ce:  ff 91         pop  r31
126
  d0:  ef 91         pop  r30
127
  d2:  9f 91         pop  r25
128
  d4:  8f 91         pop  r24
129
  d6:  2f 91         pop  r18
130
  d8:  0f 90         pop  r0
131
  da:  0f be         out  0x3f, r0  ; 63
132
  dc:  0f 90         pop  r0
133
  de:  1f 90         pop  r1
134
  e0:  18 95         reti
135
136
000000e2 <main>:
137
138
 int main()
139
 {
140
 }
141
  e2:  80 e0         ldi  r24, 0x00  ; 0
142
  e4:  90 e0         ldi  r25, 0x00  ; 0
143
  e6:  08 95         ret
144
145
000000e8 <_exit>:
146
  e8:  f8 94         cli
147
148
000000ea <__stop_program>:
149
  ea:  ff cf         rjmp  .-2        ; 0xea <__stop_program>


Compiliert mit -Os

von Sven F. (mr_sven)


Lesenswert?

43, na das ist doch ne hausnummer, dann kann ich den comperator noch 
halbieren auf 10, dann habe ich 80 inclusive puffer und dann mach ich 
noch nen 16er Quarz drann und habe meine 200 Schitte auflösung

von H.j.Seifert (Gast)


Lesenswert?

Ich habe mir jetzt nicht alles durchgelesen, aber ich glaube, du machst 
einen Denkefehler. Du brauchst nicht alle Servoimpulse sozusagen 
gleichzeitig erzeugen, sondern kannst das ganz gemütlich Stück für Stück 
machen.
|-|__________  Servo1
___|-|________ Servo2
usw.
Beim Einlesen ebenfalls, die kommen nacheinander.

von Sven F. (mr_sven)


Lesenswert?

Grundsätzlich hast du recht, so kommen sie ja auch aus dem Empfänger, 
für das Servo ist es wurscht.
Der Empfänger macht ja nix anderes als das Sendersignal auf die Kanäle 
zu demuxen.
Ich weiß nur nicht inwiefern es die sache vereinfachen würde

von Barny (Gast)


Lesenswert?

>Ich habe mir jetzt nicht alles durchgelesen, aber ich glaube, du machst
>einen Denkefehler. Du brauchst nicht alle Servoimpulse sozusagen
>gleichzeitig erzeugen, sondern kannst das ganz gemütlich Stück für Stück
>machen.
>|-|__________  Servo1
>___|-|________ Servo2
>usw.
>Beim Einlesen ebenfalls, die kommen nacheinander.

Du hast leider nur teilweise recht.
Nur die guten, alten PPM Sendeanlagen arbeiten so.
Wie es bei den PCM Anlagen ausschaut weis ich nicht aber bei den 2G4 
Anlagen kommen immer mehrere Signale gleichzeitig beim Empfänger raus.
Die meißten neuen Graupner Empfänger geben sogar alle Signale (fast) 
gleichzeitig aus.

von Sven F. (mr_sven)


Lesenswert?

Ich bin gerade am überlegen ob ich den Atmel als reinen default 
signalgeber verwende und die Umschaltung der 4 Input Kanäle auf die 
Outputs über ne Art von Latch mit Output Enable mache.
Denn jetzt noch die Abfrage der Inputs da rein zu bringen, könnte 
kompliziert werden.

Mit zwei von denen (74HCT573) dahinter sollte man das doch recht einfach 
hin bekommen oder, ich weiß nur nicht ob die Ausgänge das verkraften 
wenn ich die einfach auf ein ander lege?

von Sven F. (mr_sven)


Angehängte Dateien:

Lesenswert?

Das ist jetzt meine Idee dazu.
Ich habe nur Bauchschmerzen dabei die Ausgänge der Latches einfach so 
auf einander zu legen. Oder sollte ich lieber noch 2 74HCT32 
integrieren?

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.