Forum: Mikrocontroller und Digitale Elektronik SREG – Status Register beim Attiny 841


von Henry (Gast)


Lesenswert?

Hallo
Es geht mir um das Register "SREG – Status Register" beim Attiny 841.
Laut DB muss das Bit 7 (I) gesetzt werden damit Interrupt funktionieren. 
Bei einigen Tuts und Beispielen stand, das es nicht unbedingt notwendig 
wenn man sei() verwendet. Habe ein Beispiel dazu:
1
#define F_CPU 16000000UL    // Angabe der Frequenz, wichtig für die Zeit
2
#include "avr/io.h"        // Einbindung Datei Ausgänge
3
#include "avr/interrupt.h"
4
5
ISR (INT0_vect)                // ISR für INT0
6
  {
7
  PORTA ^= (1<<PINA5);        // ISR für LED 2 - PA5 Toggelt   
8
  }
9
ISR (PCINT0_vect)              // ISR für PCINT0
10
  {
11
  PORTA ^= (1<<PINA5);      // ISR für LED 2 - PA5 Toggelt
12
  }
13
void external()
14
  {
15
  DDRA |= (1<<PINA5);        // DDRA auf Ausgang LED PA5
16
  sei();                 // Freigabe Interrupt
17
  GIMSK |= (1<<INT0);         // Aktivierung des INT0 (externer Interrupt)
18
  MCUCR |= (1<<ISC01);        // Konfigurieren als fallende Flanke
19
  }
20
void pin_change()
21
  {
22
  GIMSK|= (1<<PCIE0);        // Freigabe Pin Change Interrupt 0 
23
  PCMSK0|=(1<<PCINT7);      // Abfrage Taster PA7 --> PCINT7 (Taster rechts)
24
  }
25
int main()
26
  {
27
  external();            // Aufruf external_interrupt
28
  pin_change();          // Aufruf pin_change_interrupt
29
  while(1)            // Programmschleife ohne Inhalt
30
    {
31
    //……
32
    }
33
  }
Der Taster an PA7 (nach GND) toggelt die LED an PA5. Alles ohne SREG 
aber mit sei().
Welche Aussage stimmt?

von Michael D. (nospam2000)


Lesenswert?


von Falk B. (falk)


Lesenswert?

Henry schrieb:
> Es geht mir um das Register "SREG – Status Register" beim Attiny 841.
> Laut DB muss das Bit 7 (I) gesetzt werden damit Interrupt funktionieren.

Das ist auch so, siehe Interrupt. Gilt auch für die neuesten AVRs.

> Bei einigen Tuts und Beispielen stand, das es nicht unbedingt notwendig
> wenn man sei() verwendet.

Jaja. Mensch, sei() ist ein C-Makrto, welches dein Assemblerbefehl sei 
umsetzt, eben damit das Bit gesetzt wird (Set Interrupt Bit)!

> Habe ein Beispiel dazu:

Schlechtes Beispiel, weil in beiden ISRs die gleich LED geschaltet wird. 
Wie unterscheidt man das dann?

von Veit D. (devil-elec)


Lesenswert?

Hallo,

die Frage ist falsch herum gestellt.  :-)
Wie du das Bit im SREG Register setzt ist erstmal egal. Aber es muss 
gesetzt werden damit deine Interrupts überhaupt funktionieren. sei und 
cli sind, wie Falk schon geschrieben hat, nur Makros für den SREG 
Zugriff um einem das Leben leichter zu machen.

von Henry (Gast)


Lesenswert?

Veit D. schrieb:
> sei und
> cli sind, wie Falk schon geschrieben hat, nur Makros für den SREG
> Zugriff um einem das Leben leichter zu machen.

Hatte den Hinweis auch gefunden, das es mit sei gemacht wird, wusste nur 
nicht das es ein Makro ist.

Falk B. schrieb:
> Schlechtes Beispiel, weil in beiden ISRs die gleich LED geschaltet wird.
> Wie unterscheidt man das dann?

Diese Frage kann ich dir nicht beantworten. Bin selber erst am lernen 
damit und schon sehr froh das es soweit geht.
Kennst du ein besseres Beispiel oder hast du eine Lösung dazu?

von Veit D. (devil-elec)


Lesenswert?

Hallo,

du musst dich nur für einen Interrupt entscheiden. Wobei gesagt sei, 
dass man Taster zum Led schalten nicht mit Interrupts verwendet. Außer 
man hat ganz ganz ganz gute Gründe dafür. Weil Taster prellen musste das 
Signal noch entprellen. Der Interrupt wird also mehrfach hintereinander 
ausgelöst und zufällig schaltet die Led um. Kann auch sein das nichts 
passiert. Oder nur kurz blitzt. In der Regel pollt man aller paar ms 
mechanische Kontakte in der Hauptschleife. Das wird schon nur Mut. Zum 
lernen kannste natürlich gern Interrupts verwenden. Nur würde ich da 
Zähler einbauen, dann siehste wie oft der Taster prellt.

von Henry (Gast)


Lesenswert?

Das mit dem prellen habe ich bemerkt. Mir ist auch klar das man Taster 
lieber anders im Programm verwenden kann. Dazu verwende ich dann das 
Programm von Peter. Wollte lernen wie man einen changer interrupt macht 
bzw nutzen kann. Im allgemeinen geht es hierbei um die Nutzung von 
Interrupt z.B. für Timer oder Watchdog (oder ADC). Im Gegensatz zu 
anderen hat ja der Attiny 841 rund 31 mögliche Interrups.

von Heiner (Gast)


Lesenswert?

Henry schrieb:
> Das mit dem prellen habe ich bemerkt. Mir ist auch klar das man Taster
> lieber anders im Programm verwenden kann. Dazu verwende ich dann das
> Programm von Peter. Wollte lernen wie man einen changer interrupt macht
> bzw nutzen kann. Im allgemeinen geht es hierbei um die Nutzung von
> Interrupt z.B. für Timer oder Watchdog (oder ADC). Im Gegensatz zu
> anderen hat ja der Attiny 841 rund 31 mögliche Interrups.

Timer, Watchdog und ADC haben doch eigene ISR - was willste denn da mit 
einem INT0 bzw PCINTxy machen??

Programm verwenden von Peter (nehme an, Du meinst das 
Tastenentprellprogramm von Peter D.) - weißt Du überhaupt, wie man das 
verwendet, wenn Du schon bei sei() und cli() scheiterst?

von Henry (Gast)


Lesenswert?

Auf deinen Kommentar habe ich schon gewartet. Ist doch erstaunlich wie 
überhäblich du bist. Es schein keinen zu geben dem du es erlauben kannst 
selber etwas zu lernen. Wenn du meine Beitrag richtig gelesen hättest, 
hättest du vielleicht gesehen das ich die 31 Interrupt beim Attiny 841 
angegeben habe. Da stehen auch noch andere drin. Mir geht es hierbei um 
change Interrupt und die Nutzung.
Das sei ein Makro ist war mir nicht bewusst. Das letzte mal hast du 
gefragt wozu man sei verwendet, was ich dir ohne Probleme beantworten 
konnte. Wenn du mal das Datenblatt anschaust, steht da eindeutig was von 
dem Register SREG und dem Bit 7. Du unterstellst mir immer das ich das 
DB nicht lese, dann kann ja meine Frage nur Zufall sein.
Langsam musst du aufhören Stimmung gegen mich zu machen und dir eine 
anderes Opfer suchen.
Das Programm oben funktioniert, obwohl du mir das nicht zutraust, 
komisch, es geht wirklich, obwohl man es besser machen könnte. Anstatt 
hier zu hetzen solltest du was dagegen tun.

von Checker (Gast)


Lesenswert?

@ Henry, reagiere nicht auf solche Beiträge wie von Heiner. Der will nur 
stänkern. Ignorieren und gut ist.

von Heiner (Gast)


Lesenswert?

Henry schrieb:
> Auf deinen Kommentar habe ich schon gewartet. Ist doch erstaunlich
> wie
> überhäblich du bist. Es schein keinen zu geben dem du es erlauben kannst
> selber etwas zu lernen.

Warum sollte ich Dir nicht erlauben, etwas zu lernen? Ich würde mich 
freuen, wenn dies der Fall wäre

> Das Programm oben funktioniert, obwohl du mir das nicht zutraust,
> komisch, es geht wirklich, obwohl man es besser machen könnte.

Habe ich doch nicht bezweifelt, oder?


>  Anstatt hier zu hetzen solltest du was dagegen tun.
Wogegen sollte ich was tun?

von Henry (Gast)


Lesenswert?

Hallo
Es freut mich das wir wenigstens bei einoigen Punkten gleicher Meinung 
sind. Da das Programm der erste Versuch in dieser Richtung ist, sind 
Fehler sicher erlaubt. Ansonsten versuche ich aus funktionierenden 
Programmen zu lernen. Wenn die Funktiom gegeben ist kann man sich auf 
den Ablauf konzentrieren. Auch an Hand des DB und der notwendigen 
Register kann man eine ganze Menge lernen. Da die Hersteller ein sehr 
umfangreiches DB schreiben, beim Attiny 841 sind es ja 366 Seiten. Da 
kann man leicht etwas übersehen.
Eine Hilfe besteht für mich nicht in Kritik oder schlimmer sonder in dem 
Weg zum Ziel. Allein der Hinweis

Veit D. schrieb:
> du musst dich nur für einen Interrupt entscheiden.

heisst für mich das es auch einfacher möglich ist. Wenn das Programm 
anschaue sehe ich das 2 Interrupt drin sind, ok. Nächste Aufgabe, 
rauskriegen welches Interrupt nicht notwendig ist.
Wichtig für mich ist dabei, die Funktion geht, Taster reagiert und LED 
leuchtet (freu). Dann kann ich mir dem nächsten Problem zuwenden.
Auch wenn du mit Kritik kommst, versuche es positiv zu machen, dann 
lohnt es für beide.

von Henry (Gast)


Lesenswert?

Habe das Programm überarbeitet und vereinfacht.
1
#define F_CPU 16000000UL      // Angabe der Frequenz, wichtig für die Zeit
2
#include "avr/io.h"          // Einbindung Datei Ausgänge
3
#include "avr/interrupt.h"      // Einbindung der interrupt.h
4
5
ISR (PCINT0_vect)              // ISR für PCINT0
6
  {
7
  PORTA ^= (1<<PINA5);      // ISR für LED 2 - PA5 Toggelt
8
  }
9
10
int main(void)
11
  {  // Ausgänge festlegen
12
    DDRA|= (1<<PINA5);
13
    // Eingänge festlegen
14
    PORTA|= (1<<PINA7);
15
    // Interrupt Service Routine PCINT einstellen
16
    GIMSK |= (1<<PCIE0);      // PA0 - PA7 PCINT erlaubt
17
    MCUCR |= (1<<ISC01);        // Konfigurieren als fallende Flanke
18
    PCMSK0 |= (1<<PCINT7);      // PCINT auf PA7 erlaubt
19
    sei();
20
    while(1)
21
      {
22
      }
23
  }
Der Taster prellt natürlich noch. Ansonsten funktioniert das Programm.

von Heiner (Gast)


Lesenswert?

@Henry

Ok, toll.

Wie verknüpfst Du nun Peter’s Tastenentprellprogamm mit Deinem?

Denn ohne dieses wird Dein Programm nicht korrekt fkt, da die Tasten 
prellen

von Henry (Gast)


Lesenswert?

So ein Tag, das ich das noch erleben darf. Ein OK von dir ist einfach 
Toll.
Nichts zu meckern, ich glaubs nicht. (freu, freu ...)
Zum Problem. Das mit dem prellen kann man deutlich merken.
Es gibt einmal die (allg.) Tasterentprellung von Peter Da. Diese 
verwende ich auf verschiedenen Prozessoren, unter anderem auch auf dem 
Attiny 841. Bei meiner Suche im Netz bin ich auf das Programm von Peter 
gestossen, glaub es heist Knighrider. Habe es mir noch nicht angesehen. 
Es soll in etwa genauso laufen wie Tasterentprellung. Vom Umfang her 
schon etwas grösser
Ansonsten bin ich am testen mit einer Zeitverzögerung, wirklich nur am 
probieren, nicht vorzeigbar.
Hast du eine Lösung? (Frage nach Hilfe)

von Heiner (Gast)


Lesenswert?

Scheint heute Dein Glückstag zu sein 😉

Wegen dem Tastenprellen - was willst Du denn machen?

von Veit D. (devil-elec)


Lesenswert?

Hallo,

du könntest dich noch etwas tiefer mit den PCINT befassen. Weil das sind 
"nur" einfache Pin Change Interrupts. Man kann einzelne Bits maskieren 
und damit aktivieren, muss aber wissen das der Interrupt Vector 
allgemein gültig ist. Also der reagiert wenn sich an einem Pin, egal 
welchen der aktiven irgendwas tut. Dann muss man im Interrupt filtern 
und selbst herausfinden welcher Eingang das nun war der ausgelöst hat.

Enprellung. Wenn es nur rein um Taster geht, kannste einen Timer 
programmieren der dir aller 20-30ms ein Flag setzt. Darauf pollst du im 
Hauptprogramm und fragst immer dann den Taster ab.

Oder für allgemeine Aufgaben einen 1ms Timer mit verschiedenen Zählern 
für verschiedene Aufgaben. Aber dann würde ich die Arduino Methode 
bevorzugen. Der Timer zählt aller 1ms einen Zähler sturr hoch. Man 
wertet nur noch Zeitdifferenzen aus für seine verschiedenste Zwecke.

Dafür gibts die unterschiedlichsten Ansätze.

von Heiner (Gast)


Lesenswert?

Wegen Tasterentprellen - das kannst Du auch per HW machen (RC-Glied), 
ist evt einfacher als per Timer (den per HW entprellten Taster kannst Du 
dann auch per INT0 einlesen- mache ich z.B.)

von Veit D. (devil-elec)


Lesenswert?

Hallo,

RC Glied kann man machen, muss man aber nicht. Wofür hat man einen 
programmierbaren µC. Das macht man alles per Software. Zudem man damit 
jederzeit Änderungen vornehmen kann ohne zu löten. Auch wenn ich mich 
wiederhole. Taster liest man in der Regel nicht per Interrupt ein. Hier 
nur zur Testzwecken damit man es prellen sieht. Zudem der Finger so 
langsam ist im Vergleich wie oft der µC durch die Hauptschleife rauscht, 
da kann man guten Gewissens pollen.

von Henry (Gast)


Lesenswert?

RC-Glied nicht möglich, da die Hardware fertig ist.

Veit D. schrieb:
> du könntest dich noch etwas tiefer mit den PCINT befassen. Weil das sind
> "nur" einfache Pin Change Interrupts.

Das klingt gut, ist wahrscheinlich zu hoch für mich. Das mit dem Zähler 
gefällt mir schon mehr.
Mache erst mal ein Suche im Netz was so alles möglich ist, Aufwand und 
Nutzen.
Werde mir die Sache von Peter genau ansehen, vielleicht versteh ich es.

von Jobst M. (jobstens-de)


Lesenswert?

Henry schrieb:
> Laut DB muss das Bit 7 (I) gesetzt werden damit Interrupt funktionieren.
> Bei einigen Tuts und Beispielen stand, das es nicht unbedingt notwendig
> wenn man sei() verwendet.

Auch in Assembler benutzt man SEI.
Und es ist die Abkürzung für "SEt I" - also Setze das I-Bit.

Wenn man sich den Befehl genauer anschaut, stellt man ebenfalls fest, 
dass SEI identisch mit BSET 7 ist. Setze Bit 7 in SREG.

Wenn also irgendwo steht, dass man das I-Bit nicht setzen muss und nur 
sei() benutzen muss, dann ist das Bullshit, denn mit dem Kommando tut 
man genau das.

Also: Um das I-Bit zu setzen ist sei() genau das richtige Kommando. 
Nicht eine Alternative.


Gruß
Jobst

von Henry (Gast)


Lesenswert?

Danke Jobst für deine Info

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.