Forum: Mikrocontroller und Digitale Elektronik ATMEGA 8515 -- SREG nicht definiert -- AVR Studio 7


von André D. (dufman)


Lesenswert?

Ich hatte hier mal danach gesucht, wie man das EEPROM eines ATMEGA mit 
irgendwelchen Werten beschreiben kann, weil ich irgendwie das Problem 
hatte, dass der Wert nie gespeichert wurde. Ich las dann etwas über 
Interrupts deaktivieren und Statusregister usw....

Hier fand ich dann folgendes Programmierbeispiel:
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Interrupts_mit_avr-gcc

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <inttypes.h>
4
 
5
//...
6
 
7
void NichtUnterbrechenBitte(void)
8
{
9
   uint8_t tmp_sreg;  // temporaerer Speicher fuer das Statusregister
10
 
11
   tmp_sreg = SREG;   // Statusregister (also auch das I-Flag darin) sichern
12
   cli();             // Interrupts global deaktivieren
13
 
14
   /* hier "unterbrechnungsfreier" Code */
15
 
16
   /* Beispiel Anfang
17
     JTAG-Interface eines ATmega16 per Software deaktivieren 
18
     und damit die JTAG-Pins an PORTC für "general I/O" nutzbar machen
19
     ohne die JTAG-Fuse-Bit zu aendern. Dazu ist eine "timed sequence"
20
     einzuhalten (vgl Datenblatt ATmega16, Stand 10/04, S. 229): 
21
     Das JTD-Bit muss zweimal innerhalb von 4 Taktzyklen geschrieben 
22
     werden. Ein Interrupt zwischen den beiden Schreibzugriffen wuerde 
23
     die erforderliche Sequenz "brechen", das JTAG-Interface bliebe
24
     weiterhin aktiv und die IO-Pins weiterhin für JTAG reserviert. */
25
 
26
   MCUCSR |= (1<<JTD);
27
   MCUCSR |= (1<<JTD); // 2 mal in Folge ,vgl. Datenblatt fuer mehr Information
28
 
29
   /* Beispiel Ende */
30
 
31
   SREG = tmp_sreg;     // Status-Register wieder herstellen 
32
                      // somit auch das I-Flag auf gesicherten Zustand setzen
33
}


Soweit, so gut...
Nur sah ich dann, dass die Variable bzw. das Register SREG nicht 
vordefiniert ist. Wenn ich andere "Kürzel" verwende, schlägt mir AVR 
Studio eigentlich immer die bereits definierten Sachen vor.

Aber SREG kennt das Programm irgendwie nicht.
Habe in der iom8515.h nachgesehen....  und tatsächlich ist da nichts 
definiert, wie im folgenden Auszug der iom8515.h zu sehen ist:
1
/* Timer/Counter Interrupt MaSK register */
2
#define TIMSK   _SFR_IO8(0x39)
3
4
/* General Interrupt Flag Register */
5
#define GIFR    _SFR_IO8(0x3A)
6
7
/* General Interrupt Control Register */
8
#define GICR    _SFR_IO8(0x3B)
9
10
/* 0x3D..0x3E SP */
11
12
/* 0x3F SREG */     <------------- nichts definiert !!
13
14
/* Interrupt vectors */
15
16
/* External Interrupt Request 0 */
17
#define INT0_vect_num    1
18
#define INT0_vect      _VECTOR(1)
19
#define SIG_INTERRUPT0      _VECTOR(1)

Habe ich eine falsche Version der iom8515.h oder muss ich selbst was 
definieren ?

Muss ich vielleicht noch  eine zusätzliche Datei inkludieren ?

Und warum ist bei den Definitionen in der iom8515.h der Adresswert von 
irgendeinem Port/Register oder was auch immer....   immer um 0x20 
niedriger als es mir im I/O-View des AVR-Studio angezeigt wird ???
(z.B. OCR1A = 0x2A in iom und 0x4A im AVR Studio)

Vielen Dank schonmal im Voraus...

Grüße
André

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

SREG wird in avr/common.h definiert, das wiederum von avr/io.h 
includiert wird.

Um dir die Stelle der Definition anzeigen zu lassen, compiliere mit -g3 
-save-temps und schaue ins .i File (C) bzw. ins .ii File (C++).

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

...hier noch wein kleines Testprogramm
1
#include <avr/io.h>
2
3
uint8_t sreg (void)
4
{
5
    return SREG;
6
}

Mit avr-gcc-5.2.1 (.s File mit -save-temps):
1
...
2
__SREG__ = 0x3f
3
...
4
sreg:
5
  in r24,__SREG__
6
  ret

von André D. (dufman)


Lesenswert?

Ja, danke erst mal, Johann....
Aber ich fürchte, das geht etwas über meinen Horizont hinaus...
Ich habe mit AVR-Studio immer nur den Build-Button betätigt und 
fertig...

Mit diesen ganzen Parameterangaben habe ich mich noch nie beschäftigt... 
sieht für mich irgendwie alles nach DOS aus...   oder ist das auch 
Bestandteil des AVR-Studio ??

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

André D. schrieb:
> Ich habe mit AVR-Studio immer nur den Build-Button betätigt und
> fertig...

Das einzige, was ich mit AVR-Studio gemacht hab, war den Klops wieder zu 
entsporgen.  VOn daher kann ich dir da nicht weiterhelfen.  Die IDE ist 
u.a. eine Overfläche für den Compiler (avr-gcc).  Wie der bedient wird 
hat mit dem Studio nix zu tun.

André D. schrieb:
> Und warum ist bei den Definitionen in der iom8515.h der Adresswert von
> irgendeinem Port/Register oder was auch immer....   immer um 0x20
> niedriger als es mir im I/O-View des AVR-Studio angezeigt wird ???
> (z.B. OCR1A = 0x2A in iom und 0x4A im AVR Studio)

Keine Ahnung das der Klops anzeigt.  Nicht-Xmega habe unterschiedliche 
Adressen für IN / OUT bzw. LDS / STS.  Adresse 0x0 für IN entspricht 
z.B. Adresse 0x20 für LDS.

Um diese unterschiedlichen Offsets brauchst du dich aber nicht zu 
kümmern, das wird alles vom Compiler erledigt.  Diese Offsets musst du 
nur bei (Inline-)Assembler beachten.

>      JTAG-Interface eines ATmega16 per Software deaktivieren


Im Datebnblatt steht:
1
MCU Control and Status Register - MCUCSR
2
3
· Bit 7 - JTD: JTAG Interface Disable
4
5
When this bit is zero, the JTAG interface is enabled if the JTAGEN
6
Fuse is programmed. If this bit is one, the JTAG interface is disabled.
7
In order to avoid unintentional disabling or enabling of the JTAG
8
interface, a timed sequence must be followed when changing this bit:
9
The application software must write this bit to the desired value twice
10
within four cycles to change its value.

>    MCUCSR |= (1<<JTD);
>    MCUCSR |= (1<<JTD); // 2 mal in Folge ,vgl. Datenblatt fuer mehr

Mögliches Problem entsteht wenn der erzeugte Code länger als 4 Ticks 
braucht, was z.B. bei deaktivierter Optimierung passieren könnte.  Daher 
würd ich da ne eigene Funktion machen, die das erledigt und eine 
bestimmte Sequenz garantiert.  Beispiel:
1
#include <avr/io.h>
2
#include <util/atomic.h>
3
4
static inline void jtag_disable (void)
5
{
6
    ATOMIC_BLOCK (ATOMIC_RESTORESTATE)
7
    {
8
#if defined (__AVR_ATmega16__)
9
        uint8_t jtd = 1u << JTD;
10
        __asm volatile ("sts %a0, %1"  "\n\t"
11
                        "sts %a0, %1"
12
                        :: "n" (& MCUCSR), "r" (jtd): "memory");
13
#else
14
#error Fix jtag_disable for MCU!
15
#endif
16
    } // atomic block
17
}


Außerdem würd ich auf keinen Fall eine 1 auf-odern, weil das Probleme 
gibt falls das JTRF Flag gesetzt ist.

Falls der Wert von MCUCSR früh (vor main) gelesen werden soll, um die 
Reset-Ursache (WatchDog, PowerDown, External, ...) zu erfahren, ist 
nochmal anderer Code notwendig.

: Bearbeitet durch User
von André D. (dufman)


Lesenswert?

Danke nochmal Johann...

Aber ganz ehrlich ?...   Ich arbeite lieber mit so nem "Klops" als mich 
durch die Eingabe von Kommandozeilen um 30 Jahre zurückversetzt zu 
fühlen, ich habe für Nostalgie nicht viel übrig.....

Das Programmbeispiel, zu dem Du so viel geschrieben hattest...   also, 
es ging mir lediglich darum, zu zeigen, dass hier geschrieben wurde, wie 
man das mit dem Statusregister und dem cli / sei managed....
Der Kram mit dem JTAG-Gedönse kannste Dir eigentlich wegdenken, da steht 
stattdessen irgendwas mit EEPROM schreiben / lesen.....

Aber das Hauptproblem war ja bei mir, dass "SREG" gar nicht bekannt 
(definiert) ist.

Ich weiß Deine Bemühungen zu schätzen, jedoch werde ich mit meinen 47 
Jahren nicht noch anfangen, mir den ganzen Kommandozeilenkram nochmal 
anzugucken, das ist eher was für Leute, die damit ihr ganzes Leben lang 
zu tun hatten, für mich wäre das eher eine Lebensaufgabe....

Grüße aus Bochum....
André

von Peter D. (peda)


Lesenswert?

Laß das mit dem SREG, nimm die atomic.h.

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.