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
voidNichtUnterbrechenBitte(void)
8
{
9
uint8_ttmp_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 */<-------------nichtsdefiniert!!
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é
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++).
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 ??
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
staticinlinevoidjtag_disable(void)
5
{
6
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
7
{
8
#if defined (__AVR_ATmega16__)
9
uint8_tjtd=1u<<JTD;
10
__asmvolatile("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.
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é