Forum: Mikrocontroller und Digitale Elektronik While(1) wird nach setzen des Timer-Interrupts nicht mehr aufgerufen


von Florian C. (flo94)


Lesenswert?

Hallo an alle!

Ich besitze ein ATmega64A Board (Takt auf internen 8MHz RC-Oszillator 
gestellt), an dem ich ein paar Bus-Systeme auspobieren möchte. Gestern 
habe ich es das erste Mal in Betrieb genommen und jetzt ist ein äußerst 
merkwürdiger Fehler aufgetreten, vlt. findet ja eine von euch den 
Fehler...

Ich habe folgenden code programmiert, der einen Timer-Interrupt auslöst 
(sicherheitshalber sind nicht verwendete Bits auf 0 gestetzt) und 
zugleich blinkt eine LED im 1s-Takt in der While(1)-Schleife:
1
#define F_CPU 8000000UL        // define system clock with  8MHz
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
7
8
int main(void)
9
{  
10
  TCNT0 = 0;
11
  TCCR0 &= (~(1<<COM00)) & (~(1<<COM01));  // normal operation mode, OC0 not connected to a pin
12
  TCCR0 |= (1<<WGM01);          // clear on compare matching
13
  TCCR0 &= (~(1<<WGM00));          // with OCR0
14
  TCCR0 |= (1<<CS00);            // set prescaler
15
  TCCR0 &= (~(1<<CS01)) & (~(1<<CS02));  // to 1 -> 12MHz
16
  
17
  OCR0 = 200;                // set compare value for timer0 to 200 (25µs)
18
19
  TIMSK |= (1<<OCIE0);          // enable interrupt for timer0
20
  
21
  DDRA |= (1<<PA0);
22
  DDRD |= (1<<PD1);
23
24
  sei();
25
  
26
  while(1)
27
  {
28
    PORTA ^= (1<<PA0);
29
    _delay_ms(500);
30
  }
31
32
  return 0;
33
}
34
35
36
ISR(TIMER0_COMP_vect)
37
{
38
  PORTD ^= (1<<PD1);
39
}

Mit diesem Code bekomme ich am Pin PD1 mit dem Oszi wie erwartet ein 
20kHz Rechteck-Signal. Jedoch blinkt die LED am Pin PA0 nicht mehr, 
sondern leuchtet dauerhaft!
Deaktiviere ich den Timer durch Auskommentieren der Zeile "CCR0 |= 
(1<<CS00);" toggelt der Pin PD1 logischerweise nichtmehr, aber dafür 
blinkt die LED an Port PA0.
Beides gleichzeitig scheint nicht zu funktionieren, bzw. befindet sich 
das Programm wsl. dauerhaft im ISR...

Was kann dieses eigenartige Verhalten auslösen oder worin liegt der 
Fehler?
Habe bereits Timer2 ausprobiert -> gleiches Ergebnis
Neues Projekt erstellt -> gleiches Ergebnis


Ich hoffe jemand kann mir helfen.

Danke und lG
Florian

: Bearbeitet durch User
von Carl D. (jcw2)


Lesenswert?

.lss Datei erzeugt/angeschaut?
Darin steht, was wirklich passiert. Leider in Assembler, aber das lesen 
zu können und zu verstehen, ist nie verkehrt. Schreiben muß man's ja 
nicht unbedingt selber ;-)

Beitrag #5071025 wurde vom Autor gelöscht.
von Christoph (gizmo)


Lesenswert?

Der Atmega läuft mit 8MHz, deine ISR wird alle 1us, also mit 1MHz Takt 
aufgerufen.

Das lässt dem Atmega nur 8 Takte Zeit um in die ISR zu springen, die 
Register auf dem Stack zu sichern, read-modify-write auf PORTD 
auszuführen, Register vom Stack zurückholen und wieder ins Hauptprogramm 
zu springen.

Der Atmega hängt einfach ununterbrochen im Interrupt weil er keine Zeit 
fürs Hauptprogramm mehr hat.

Schau dir mal an wie man mit Atmega Timern eine PWM ausgibt, das 
funktioniert komplett in Hardware und verbraucht keine CPU-Takte.

von Volker S. (vloki)


Lesenswert?

Musst du den Timer Interrupt(Flag) nicht löschen?

Andererseits müsste natürlich die Frequenz viel höher als 20kHz sein,
falls das Programm immer wieder in den IR-Vector springen würde.

(Sorry, kenn mich mit AVR IR-Handling nicht aus)

von Florian C. (flo94)


Lesenswert?

Vielen Dank für die schnellen Antworten!

@Carl Drexler:
Die Datei wird erzeugt, aber auf den ersten Blick erkenne ich garnix, 
habe leider nur Grundahnung in Sachen ASM...

@ Christoph S:
Es war ein Fehler im Kommentar, es sind 25µs, habe es ausgebessert...

von S. Landolt (Gast)


Lesenswert?

Arduino?

von Florian C. (flo94)


Lesenswert?

@Volker SK:
Meines Wissens muss da nichts zurückgesetzt werden, ich habe ähnliche 
Codes (gleiche Syntax und Ablauf) bereits auf anderen Mikrocontrollern 
ohne Probleme implementieren können!
Stimmt, die Frequenz müsste deuitlich höher sein, wenn er dauerhaft im 
ISR hängt, also kann dies nicht der Fehler sein...

@S. Landolt:
Nein, ist dieses Board:
https://www.aliexpress.com/item/Atmega64-development-board-avr-development-board-learning-board-core-board-Free-Shipping/32705245588.html
Und als Entwicklungsumgebung verwende ich das AVR-Studio 7.0

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Florian C. schrieb:
> TCCR0 &= (~(1<<COM00)) & (~(1<<COM01));  // normal operation mode, OC0
> not connected to a pin
>   TCCR0 |= (1<<WGM01);          // clear on compare matching
>   TCCR0 &= (~(1<<WGM00));          // with OCR0
>   TCCR0 |= (1<<CS00);            // set prescaler
>   TCCR0 &= (~(1<<CS01)) & (~(1<<CS02));  // to 1 -> 12MHz

Und da blickst du noch durch? Was hältst du davon?:
1
TCCR0 = (1 << WGM01) | (1 << CS00);

von Kamest (Gast)


Lesenswert?

> Der Atmega läuft mit 8MHz, deine ISR wird alle 1us, also mit 1MHz Takt
> aufgerufen.

Die Interruptroutine wir 40.000 mal pro Sekunde aufgerufen.

> Der Atmega hängt einfach ununterbrochen im Interrupt weil er keine Zeit
> fürs Hauptprogramm mehr hat.

Ununterbrochen nicht, da mindesten 1 Befehl nach dem RETI ausgeführt 
wird.
Das Hauptprogramm dürfte trotzdem nur sehr langsam ausgeführt werden 
(40.000 x Zeit in der IR ist verdammt lang).

Fazit: Das Programm ist ungeeignet für die zu lösende Aufgabe.

von Erwin D. (Gast)


Lesenswert?

S. Landolt schrieb:
> Arduino?

Was ist damit?

von Florian C. (flo94)


Lesenswert?

@Matthias S.
Ich finde es einfacher wenn ich es nach Bit-Typ unterteile, aber daran 
dürfte es nicht scheitern...

@Kamest:
Ich habe auch bereits den Prescaler auf 8 gesetzt -> gleiches Ergebnis

Das Programm dient nur zum Austesten des Timer-Interrupts, muss also 
keinen Sinn Ergeben, sondern dient lediglich zum Beheben des Fehlers...

: Bearbeitet durch User
von Volker S. (vloki)


Lesenswert?

Kamest schrieb:
> Ununterbrochen nicht, da mindesten 1 Befehl nach dem RETI ausgeführt
> wird.
> Das Hauptprogramm dürfte trotzdem nur sehr langsam ausgeführt werden
> (40.000 x Zeit in der IR ist verdammt lang).

Ja stimmt, das _delay_ms(500) Macro wird wohl sehr viel läääääänger 
brauchen.

von Volker S. (vloki)


Lesenswert?

Volker S. schrieb:
> Kamest schrieb:
>> Ununterbrochen nicht, da mindesten 1 Befehl nach dem RETI ausgeführt
>> wird.
>> Das Hauptprogramm dürfte trotzdem nur sehr langsam ausgeführt werden
>> (40.000 x Zeit in der IR ist verdammt lang).
>
> Ja stimmt, das _delay_ms(500) Macro wird wohl sehr viel läääääänger
> brauchen.


Florian C. schrieb:
> Das Programm dient nur zum Austesten des Timer-Interrupts, muss also
> keinen Sinn Ergeben, sondern dient lediglich zum Beheben des Fehlers...
Muss der wirklich in so kleinen Zeitabständen kommen?

Beitrag #5071053 wurde vom Autor gelöscht.
von Florian C. (flo94)


Lesenswert?

So, habe den Prescaler jetzt auf 8 gesetzt und die Delay auf 100ms:
2.5kHz Augabe an PD1 und LED an PA0 trotzdem dauerhaft an ...

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Florian C. schrieb:
> @Matthias S.
> Ich finde es einfacher wenn ich es nach Bit-Typ unterteile, aber daran
> dürfte es nicht scheitern...

Es geht hier nicht um den Bittyp, sondern darum, das du den Timer in 
Häppchen initialisierst, was manchmal zu lustigen Effekten führen kann. 
Ein atomarer Zugriff, der alle Bits so setzt, wie sie sein sollen, 
bewahrt einen davor.
Das ganze geht übrigens auch komplett ohne Interrupt und läuft im 
Hintergrund, wenn du 'Toggle On Compare Match' benutzt und PB4 (OC0) als 
Ausgang.

von Carl D. (jcw2)


Lesenswert?

Christoph S. schrieb:
> Der Atmega läuft mit 8MHz, deine ISR wird alle 1us, also mit 1MHz Takt
> aufgerufen.
Das steht aber nur im Kommentar. Das Compare-Register wird auf 200 
gesetzt.

Hier mal eine überarbeitete Timer-Initialisierung:
1
  TCCR0 = 
2
          (0b00<<COM00)  // normal operation mode, OC0 not connected to pin
3
        | (0b10<<WGM00)  // clear on compare matching with OCR0
4
        | (0b001<<CS00); // set prescaler to /1  8MHz -> 125ns Tick
5
6
  OCR0 = 200;    // 200*125ns -> Interrupt alle 25μs

Bei 8MHz sollte das 25μs-Pinwackeln nicht zu 5-stelliger Verlängerung 
des delay() führen.

: Bearbeitet durch User
von Florian C. (flo94)


Lesenswert?

Hatte dadurch bisher noch nie Probleme, kann es aber gerne auch ander 
versuchen.

Ich habe jetzt mal den zweiten Kanal des Oszis an den Ausgang der LED 
geklemmt:
Die LED toggelt mit der gleichen Frequenz wie der 
Timer-Interrupt-Ausgang, lediglich um 180° phasenverschoben! Wie kann 
das sein?

von Volker S. (vloki)


Lesenswert?

Florian C. schrieb:
> Und als Entwicklungsumgebung verwende ich das AVR-Studio 7.0

Kannst du damit nicht debuggen?
Müsste man doch leicht erkennen könne , was da schief läuft.

von Florian C. (flo94)


Lesenswert?

@Carl Drexler:
Habe deine Initialisierung probiert -> selbes Ergebnis

Beitrag #5071067 wurde von einem Moderator gelöscht.
von Anständiger Definer (Gast)


Lesenswert?

Kurzes OT

Matthias S. schrieb:
> Und da blickst du noch durch? Was hältst du davon?:TCCR0 = (1 << WGM01)
> | (1 << CS00);

Danke, jetzt bestätigen die avr Jünger selbst, dass die 1 << 
Schreibweise nicht zu lesen ist.
Und noch besser die Variante von CD (0b00<<COM00). ?

von S. Landolt (Gast)


Lesenswert?

> Wie kann das sein?
Ständiger Neustart nach erstmaligem ISR-Aufruf? Aber warum?

von Carl D. (jcw2)


Lesenswert?

Florian C. schrieb:
> @Carl Drexler:
> Habe deine Initialisierung probiert -> selbes Ergebnis

Ja hoffentlich. Ich hab ja die selben Werte übergeben, nur anders 
(durchschaubarer) formuliert. Nur die Kommentare waren im Original 
"leicht veraltet".

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Anständiger Definer schrieb:
> Danke, jetzt bestätigen die avr Jünger selbst, dass die 1 <<
> Schreibweise nicht zu lesen ist.
> Und noch besser die Variante von CD (0b00<<COM00). ?

Aha? Dann erklär doch bitte mal, was du meinst.
Die Schreibweise
1
TCCR0 = (1 << WGM01) | (1 << CS00);
setzt genau die Bits WGM01 und CS00 im TCCR0 Register. Alle anderen 
werden auf 0 gesetzt. Wenn du das nicht verstehst:
https://www.mikrocontroller.net/articles/Bitmanipulation

von Carl D. (jcw2)


Lesenswert?

S. Landolt schrieb:
>> Wie kann das sein?
> Ständiger Neustart nach erstmaligem ISR-Aufruf? Aber warum?

Vielleicht weil die HW nicht die Interruptvektoren hat, die der Compiler 
vermutet. Deshalb .lss-File anschauen.

von (prx) A. K. (prx)


Lesenswert?

Die M103C Fuse.

von Carl D. (jcw2)


Lesenswert?

Matthias S. schrieb:
> Anständiger Definer schrieb:
>> Danke, jetzt bestätigen die avr Jünger selbst, dass die 1 <<
>> Schreibweise nicht zu lesen ist.
>> Und noch besser die Variante von CD (0b00<<COM00). ?
>
> Aha? Dann erklär doch bitte mal, was du meinst.
> Die Schreibweise
>
1
> TCCR0 = (1 << WGM01) | (1 << CS00);
2
>
> setzt genau die Bits WGM01 und CS00 im TCCR0 Register. Alle anderen
> werden auf 0 gesetzt. Wenn du das nicht verstehst:
> https://www.mikrocontroller.net/articles/Bitmanipulation

Er meint, daß ich die Bits zusammengeschrieben hab und dann auf das 
unterste Bit ausrichte. Damit sieht man direkt den Wert aus dem DB.

von Florian C. (flo94)


Lesenswert?

Das steht im lss-File: (mein Programm heißt TI_Error)
1
TI_Error.elf:     file format elf32-avr
2
3
Sections:
4
Idx Name          Size      VMA       LMA       File off  Algn
5
  0 .data         00000000  00800100  00800100  0000016c  2**0
6
                  CONTENTS, ALLOC, LOAD, DATA
7
  1 .text         00000118  00000000  00000000  00000054  2**1
8
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
9
  2 .comment      00000030  00000000  00000000  0000016c  2**0
10
                  CONTENTS, READONLY
11
  3 .note.gnu.avr.deviceinfo 0000003c  00000000  00000000  0000019c  2**2
12
                  CONTENTS, READONLY
13
  4 .debug_aranges 00000028  00000000  00000000  000001d8  2**0
14
                  CONTENTS, READONLY, DEBUGGING
15
  5 .debug_info   000008a5  00000000  00000000  00000200  2**0
16
                  CONTENTS, READONLY, DEBUGGING
17
  6 .debug_abbrev 000007f7  00000000  00000000  00000aa5  2**0
18
                  CONTENTS, READONLY, DEBUGGING
19
  7 .debug_line   000002e7  00000000  00000000  0000129c  2**0
20
                  CONTENTS, READONLY, DEBUGGING
21
  8 .debug_frame  00000048  00000000  00000000  00001584  2**2
22
                  CONTENTS, READONLY, DEBUGGING
23
  9 .debug_str    00000420  00000000  00000000  000015cc  2**0
24
                  CONTENTS, READONLY, DEBUGGING
25
 10 .debug_loc    00000049  00000000  00000000  000019ec  2**0
26
                  CONTENTS, READONLY, DEBUGGING
27
 11 .debug_ranges 00000018  00000000  00000000  00001a35  2**0
28
                  CONTENTS, READONLY, DEBUGGING
29
30
Disassembly of section .text:
31
32
00000000 <__vectors>:
33
   0:  0c 94 46 00   jmp  0x8c  ; 0x8c <__ctors_end>
34
   4:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
35
   8:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
36
   c:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
37
  10:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
38
  14:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
39
  18:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
40
  1c:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
41
  20:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
42
  24:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
43
  28:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
44
  2c:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
45
  30:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
46
  34:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
47
  38:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
48
  3c:  0c 94 78 00   jmp  0xf0  ; 0xf0 <__vector_15>
49
  40:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
50
  44:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
51
  48:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
52
  4c:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
53
  50:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
54
  54:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
55
  58:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
56
  5c:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
57
  60:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
58
  64:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
59
  68:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
60
  6c:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
61
  70:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
62
  74:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
63
  78:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
64
  7c:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
65
  80:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
66
  84:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
67
  88:  0c 94 50 00   jmp  0xa0  ; 0xa0 <__bad_interrupt>
68
69
0000008c <__ctors_end>:
70
  8c:  11 24         eor  r1, r1
71
  8e:  1f be         out  0x3f, r1  ; 63
72
  90:  cf ef         ldi  r28, 0xFF  ; 255
73
  92:  d0 e1         ldi  r29, 0x10  ; 16
74
  94:  de bf         out  0x3e, r29  ; 62
75
  96:  cd bf         out  0x3d, r28  ; 61
76
  98:  0e 94 52 00   call  0xa4  ; 0xa4 <main>
77
  9c:  0c 94 8a 00   jmp  0x114  ; 0x114 <_exit>
78
79
000000a0 <__bad_interrupt>:
80
  a0:  0c 94 00 00   jmp  0  ; 0x0 <__vectors>
81
82
000000a4 <main>:
83
#include <util/delay.h>
84
85
86
      int main(void)
87
      {
88
        TCNT0 = 0;
89
  a4:  12 be         out  0x32, r1  ; 50
90
        TCCR0 &= (~(1<<COM00)) & (~(1<<COM01));  // normal operation mode, OC0 not connected to a pin
91
  a6:  83 b7         in  r24, 0x33  ; 51
92
  a8:  8f 7c         andi  r24, 0xCF  ; 207
93
  aa:  83 bf         out  0x33, r24  ; 51
94
        TCCR0 |= (1<<WGM01);          // clear on compare matching
95
  ac:  83 b7         in  r24, 0x33  ; 51
96
  ae:  88 60         ori  r24, 0x08  ; 8
97
  b0:  83 bf         out  0x33, r24  ; 51
98
        TCCR0 &= (~(1<<WGM00));          // with OCR0
99
  b2:  83 b7         in  r24, 0x33  ; 51
100
  b4:  8f 7b         andi  r24, 0xBF  ; 191
101
  b6:  83 bf         out  0x33, r24  ; 51
102
        TCCR0 |= (1<<CS01);            // set prescaler
103
  b8:  83 b7         in  r24, 0x33  ; 51
104
  ba:  82 60         ori  r24, 0x02  ; 2
105
  bc:  83 bf         out  0x33, r24  ; 51
106
        TCCR0 &= (~(1<<CS00)) & (~(1<<CS02));  // to 1 -> 12MHz
107
  be:  83 b7         in  r24, 0x33  ; 51
108
  c0:  8a 7f         andi  r24, 0xFA  ; 250
109
  c2:  83 bf         out  0x33, r24  ; 51
110
        
111
        OCR0 = 200;                // set compare value for timer0 to 12 (12 * 0.08333µs = 1µs)
112
  c4:  88 ec         ldi  r24, 0xC8  ; 200
113
  c6:  81 bf         out  0x31, r24  ; 49
114
115
        TIMSK |= (1<<OCIE0);          // enable interrupt for timer0
116
  c8:  87 b7         in  r24, 0x37  ; 55
117
  ca:  82 60         ori  r24, 0x02  ; 2
118
  cc:  87 bf         out  0x37, r24  ; 55
119
        
120
        DDRA |= (1<<PA0);
121
  ce:  d0 9a         sbi  0x1a, 0  ; 26
122
        DDRD |= (1<<PD1);
123
  d0:  89 9a         sbi  0x11, 1  ; 17
124
125
        sei();
126
  d2:  78 94         sei
127
        
128
        while(1)
129
        {
130
          PORTA ^= (1<<PA0);
131
  d4:  91 e0         ldi  r25, 0x01  ; 1
132
  d6:  8b b3         in  r24, 0x1b  ; 27
133
  d8:  89 27         eor  r24, r25
134
  da:  8b bb         out  0x1b, r24  ; 27
135
  #else
136
    //round up by default
137
    __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
138
  #endif
139
140
  __builtin_avr_delay_cycles(__ticks_dc);
141
  dc:  2f ef         ldi  r18, 0xFF  ; 255
142
  de:  30 e7         ldi  r19, 0x70  ; 112
143
  e0:  82 e0         ldi  r24, 0x02  ; 2
144
  e2:  21 50         subi  r18, 0x01  ; 1
145
  e4:  30 40         sbci  r19, 0x00  ; 0
146
  e6:  80 40         sbci  r24, 0x00  ; 0
147
  e8:  e1 f7         brne  .-8        ; 0xe2 <main+0x3e>
148
  ea:  00 c0         rjmp  .+0        ; 0xec <main+0x48>
149
  ec:  00 00         nop
150
  ee:  f3 cf         rjmp  .-26       ; 0xd6 <main+0x32>
151
152
000000f0 <__vector_15>:
153
        return 0;
154
      }
155
156
157
      ISR(TIMER0_COMP_vect)
158
      {
159
  f0:  1f 92         push  r1
160
  f2:  0f 92         push  r0
161
  f4:  0f b6         in  r0, 0x3f  ; 63
162
  f6:  0f 92         push  r0
163
  f8:  11 24         eor  r1, r1
164
  fa:  8f 93         push  r24
165
  fc:  9f 93         push  r25
166
        PORTD ^= (1<<PD1);
167
  fe:  92 b3         in  r25, 0x12  ; 18
168
 100:  82 e0         ldi  r24, 0x02  ; 2
169
 102:  89 27         eor  r24, r25
170
 104:  82 bb         out  0x12, r24  ; 18
171
 106:  9f 91         pop  r25
172
 108:  8f 91         pop  r24
173
 10a:  0f 90         pop  r0
174
 10c:  0f be         out  0x3f, r0  ; 63
175
 10e:  0f 90         pop  r0
176
 110:  1f 90         pop  r1
177
 112:  18 95         reti
178
179
00000114 <_exit>:
180
 114:  f8 94         cli
181
182
00000116 <__stop_program>:
183
 116:  ff cf         rjmp  .-2        ; 0x116 <__stop_program>

von (prx) A. K. (prx)


Lesenswert?

M103C Fuse programmiert. Stackpointer zeigt dorthin, wo der M64 RAM hat, 
aber eben nicht der M103C. Erster Interrupt ok, Return geht ab in den 
Wald.

von Anständiger Definer (Gast)


Lesenswert?

@MS
Nimm erst den Stock aus deinem ...

CD schrieb über die unübersichtliche Initialisierung. Und warum 
unübersichtlich! Weil durch die 1 << das Auge abgelenkt wird. Viel 
zuviele unnötige Zeichen.

Man kann ein C Programm auch in einer Zeile schreiben. Warum macht man 
das nicht? Denk darüber nach, bevor du wieder mit Puls antwortest.

von Florian C. (flo94)


Lesenswert?

@A. K.: was bedeutet das und wie kann dies vermieden werden?


Jeder hat andere Vorlieben und am Ende kann man alle anderen 
Schreibweisen auch nachvollziehen, daher soll doch jeder programmieren 
wie es ihm beliebt, hauptsache man hält sich an Ansi C...

von Zeichenexperte (Gast)


Lesenswert?

Anständiger Definer schrieb:
> Viel zuviele unnötige Zeichen.

So wie dein Beitrag.

von Carl D. (jcw2)


Lesenswert?

Vektor passt.
Ist das mit -Os übersetzt?
Die ISR scheint mir etwas lang. Aber das ist eben auch ein Chip mit 
H-Kennzeichen. Der kann nicht mal per PIN-Write mit einen Ausgang 
wackeln.
Aber 8*25=200 Takte braucht der nicht für die ISR.
Langsameres delay() ja, aber höchstens 2..3x.

von S. Landolt (Gast)


Lesenswert?

Diese M103-Fuse ist (unglücklicherweise) werksseitig programmiert. Um 
einen echten ATmega64A zu haben, muss sie deaktiviert werden.

von Florian C. (flo94)


Angehängte Dateien:

Lesenswert?

@Carl Drexler:
Ich denke auch, dass das Delay nicht deutlich länger sein müsste...

@S. Landolt:
Ok, kann ich diese M103-Fuse einfach in den Fusebits deaktivieren?


Im Anhang befindet sich ein Foto vom Oszillogramm: oben der LED-Ausgang, 
unten der Timer-Interrupt Ausgang...

von (prx) A. K. (prx)


Lesenswert?

Florian C. schrieb:
> Ok, kann ich diese M103-Fuse einfach in den Fusebits deaktivieren?

Ja.

von S. Landolt (Gast)


Lesenswert?

> Ok, kann ich diese M103-Fuse einfach in den Fusebits deaktivieren?
Ja. Da sie, M103C um korrekt zu sein, im Extended Fuse Byte nur noch 
zusammen mit dem WDTON liegt, kann zumindest nichts schief gehen.

von Carl D. (jcw2)


Lesenswert?

Anständiger Definer schrieb:
> @MS
> Nimm erst den Stock aus deinem ...
>
> CD schrieb über die unübersichtliche Initialisierung. Und warum
> unübersichtlich! Weil durch die 1 << das Auge abgelenkt wird. Viel
> zuviele unnötige Zeichen.
>
> Man kann ein C Programm auch in einer Zeile schreiben. Warum macht man
> das nicht? Denk darüber nach, bevor du wieder mit Puls antwortest.

Das ist aber auch nicht wirklich schwer, wenn man will. Seit C11 
(spätestens) sind Bit-Konstanten sogar Standard.

Und eine wie auch immer Abneigung gegen eine Chip-Familie an der Frage
Bit-Nummer oder Bit-Maske festzumachen, dafür bin ich ca 40 Jahre zu 
alt.

Ich benutze selbst lieber mehr als C und hab dann
Avr::Timer0::Wgm = Avr::Timer0::WGM::CTC;
da stehen. Sogar wenn Wgm über 2 HW-Register verteilt ist.

von Florian C. (flo94)


Angehängte Dateien:

Lesenswert?

Im Anhang befinden sich meine Fuse-Bits.
Hier gibt es nirgens das M103 Fusebit... Nach Aktivierung des 
WDTON-Fusebit kam es zu unvorhergesehenem Verhalten im Oszillogramm, 
daher habe ich es wieder deaktiviert, aber das Ergebnis war das Selbe...

von Anständiger Sefiner (Gast)


Lesenswert?

Carl D. schrieb:
> Und eine wie auch immer Abneigung gegen eine Chip-Familie an der Frage
> Bit-Nummer oder Bit-Maske festzumachen, dafür bin ich ca 40 Jahre zu
> alt.
Der Chip kann nix dafür, das liegt schon an den Codern. ?

von Volker S. (vloki)


Lesenswert?

Florian C. schrieb:
> Im Anhang befindet sich ein Foto vom Oszillogramm: oben der LED-Ausgang,
> unten der Timer-Interrupt Ausgang...

Sieht aus als wäre der Wechsel beim Timer etwas früher.
Der IR killt (wegen der M103C Kompatibilität?) irgendwie die 
Zählvariable des delay Macros?

von S. Landolt (Gast)


Lesenswert?

Die nennen das 'CompMode'!

Egal wie es ausgeht, mein Dank an A.K., dass er meiner Erinnerung auf 
die Sprünge geholfen hat.
(Und gleich morgen gehe ich in die Apotheke, vielleicht haben sie ja 
etwas gegen akuten Gedächtnisschwund)

von (prx) A. K. (prx)


Lesenswert?

S. Landolt schrieb:
> Die nennen das 'CompMode'!

Ja, ziemlich idiotisch.

> Egal wie es ausgeht, mein Dank an A.K., dass er meiner Erinnerung auf
> die Sprünge geholfen hat.

Hätte er den M128 genommen, wärst du sicherlich gleich drauf gekommen - 
bei dem stolpert(e) wohl jeder mal drüber. Der M64 ist technisch 
gleich, aber halb getestet, folglich hat er auch diese in diesem Fall 
sinnlose Fuse.

: Bearbeitet durch User
von Florian C. (flo94)


Lesenswert?

WOW, ES FUNKTIONIERT!!
Vielen vielen Dank, es lag tatsächlich am "CompMode" Fusebit!
Nachdem ich es deaktiviert und gesetzt habe geht jetzt beides 
einwandfrei!

Da wäre ich ja NIE drauf gekommen!

Wieso ist das nur standardmäßig gsetzt, ist ja idiotisch -.-

: Bearbeitet durch User
Beitrag #5071120 wurde vom Autor gelöscht.
von (prx) A. K. (prx)


Lesenswert?

Florian C. schrieb:
> Wieso ist das nur standardmäßig gsetzt, ist ja idiotisch -.-

Der ATmega128 ist dadurch ein funktionskompatibler Nachfolger vom 
ATMega103. So konnte man den M103 direkt durch den M128 ersetzen, ohne 
etwas ändern zu müssen. Beim M64 ist das bloss ein Schmutzeffekt.

: Bearbeitet durch User
von Florian C. (flo94)


Lesenswert?

Trotzdem sollte das eher opt-in sein als standardmäßig gesetzt...

von (prx) A. K. (prx)


Lesenswert?

Florian C. schrieb:
> Trotzdem sollte das eher opt-in sein als standardmäßig gesetzt...

Dann wäre er nicht mehr plug-in-compatible gewesen. Sie hätten natürlich 
die Logistik um einen Pseudo-Typ M103A bereichern können, der in der 
abschliessenden Typ-Programmierung anders eingestellt wird als der M128. 
Könnte mir vorstellen, dass es bei Atmel danach Bisspuren am Arsch gab.

Jeder der hier schon länger unterwegs ist kennt das eigentlich. Also 
dass der M128 beim ersten Return nach einem Unterprogrammaufruf 
wegfliegt. Hier wars eben ein Interrupt.

: Bearbeitet durch User
von Florian C. (flo94)


Lesenswert?

Ok macht etwas Sinn, aber hätte ich trotzdem nicht so gemacht...

Bin leider selten in diesem Forum und das war mein erster Thread hier, 
also war mir das neu und alle bisherigen µCs die ich programmiert habe 
hatten da keinerlei Probleme...

von Peter D. (peda)


Lesenswert?

Florian C. schrieb:
> Wieso ist das nur standardmäßig gsetzt, ist ja idiotisch -.-

Vermutlich gab es einen Kunden, der richtig große Stückzahlen des 
Mega103 abgenommen hat und der hat es Atmel diktieren können.
Und damit auch diese krude SPI-Programmierung über die UART-Pins, wo 
auch viele drauf reinfallen.

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.