C INT0 deaktivieren ?!

Ich habe das Gefühl das es mit dem INT0_Disable zu tun hat... Kann mir halt nur noch nicht erklären wieso & wie ich es beheben kann :confused:
 
Ich habe es gerade noch mal im "IDLE" Mode probiert, da klappt es !
Hmm...
 
Logisch, siehe Tabelle mit den WakeUpSources und Deine gewählten Interrupt Sense Control Bits (MCUCR)
 
Default sind sie doch auf "Low Level" passt doch ?!
Das Problem liegt glaube ich an meiner Entprellung mit dem Timer ? Kann es sein das ich zu früh in den Schlaf Modus gehe & vorher den Interrupt nicht freigebe ?!
Dann kann ich ihn ja auch nicht "auf Wecken" ?!
 
Code:
...
int main(void)
{
    OCR0A   = 77;							// Legt den Wert ZUM Überlaufes fest ( ca. jede 10 ms.)
	TCCR0A |= (1<<WGM01);					// Compare Match (Normal Mode) keine Funktion am PIN &&    TIFR |= 0x01;			// Clear Interrupt Flag ( Wird nur für Polling benötigt! Nicht für Interrupt )
    TIMSK  |= (1<<OCIE0A);					// Compare Match Interrupt enable
    TCCR0B |= ((1<<CS02) | (1<<CS00));		// Prescaler auf 1024 setzen (F_CPU/1024)
	
	OCR1A   = HELLIGKEIT;					// Legt den Wert des Überlaufes fest
	TCCR1A |= 0x00;							// Compare Match (Normal Mode) keine Funktion am PIN
	TIFR   |= 0x01;							// Clear Interrupt Flag ( Wird nur für Polling benötigt! Nicht für Interrupt )
	TIMSK  |= ((1<<OCIE1A) | (1<<TOIE1));							// Compare Match Interrupt enable
	TCCR1B |= (1<<CS10);					// Prescaler auf 0 setzen (F_CPU)
	
	GIMSK  |= ((1<<INT0) | (1<<INT1));		// Interrupt "INT0 & INT1" aktivieren

[B][COLOR="#FF0000"]	MCUCR  &= ~((1<<ISC01) | (1<<ISC00));
[/COLOR][/B]
    sei();									// Interrupts global aktivieren
		
//	set_sleep_mode(SLEEP_MODE_PWR_DOWN);	// µC sagen in welchen sleep_mode er gehen soll (POWER_DOWN) ca. 20 µA (0,000020 A)
//	sleep_mode();							// Setzt den µC (nach Batteriewechsel) in den sleep_mode 
	
	Auto_Off = ABSCHALTZEIT;
	
	OCR1A = 800;
	
	set_sleep_mode(SLEEP_MODE_PWR_DOWN);		// µC sagen in welchen sleep_mode er gehen soll (POWER_DOWN) ca. 20 µA (0,000020 A)

		
...
Hir werden die beiden ISC-Bits gelöscht? (C-Syntax) dann paßt es eigentlich
 
auch wenn ich es weg lasse... Nichts im MCUCR Register schreibe... Genau das selbe..
Ich habe das Problem nur wenn ich TCCR1B abfrage... Lasse ich es weg & wecke ihm aus dem Sleep Mode... von der Funktion "Auto_Off" auf... klappt es ja...

Mir ist es so, dass ich ein Problem mit dem Tastenentprellen habe... Wenn ich INT0 deaktiviere und den TIMER1 ausschalte... Fängt meine "while" Schleife ja den Status vom TCCR1B ab... (CS10)... & da hapert es...
 
Ich sehe bei Deinem Code in C und auf dem Mobile nicht wirklich durch - wann schickst Du den Controller denn schlafen?
In meinem Vorschlag war die Ereigniskette im wesentlichen so vorgesehen:
  • INT0 getriggert->INT0 deaktiviert und Entprelltimer gestartet
  • Timerüberlauf im main-loop gepollt-> Entprelltimer gestoppt, Flag gelöscht, INT0 reaktiviert, sleep
Allerdings wollte ich den ja wegen HW-PWM auch bei LEDs-An schlafen schicken (und entsprechend in der INT0-ISR den Modus umschalten - Du mußt also irgendwo entscheiden, ob geschlafen werden soll oder nicht).
 
Okay... mal abgesehen davon...
Wieso gibt meine Abfrage (in der while) wenn sie wahr ist (was auch passiert, sonst würde Auto_Off nicht funktionien) meinen INT0 nicht frei ?

Code:
while(1)
{
	
	if ((Auto_Off == ABSCHALTZEIT) || (TCCR1B & (1<<CS10)))			// Ist Auto_Off = ABSCHALTZEIT, dann schlafen!
	{	
[COLOR="#FF0000"][B]                INT0_ENABLE;[/B][/COLOR]
		Auto_Off=0;
		TIMER1_STOP;
		XPE_1_AUS; XPE_2_AUS; XPE_3_AUS; XPE_4_AUS;								
		set_sleep_mode(SLEEP_MODE_PWR_DOWN);		// µC sagen in welchen sleep_mode er gehen soll (POWER_DOWN) ca. 20 µA (0,000020 A)
		sleep_mode();								// Schlafen aktivieren!
	}


    
	}// Ende While
 
keiner ne Idee ?!
 
keiner ne Idee ?!

also ich hab mir jetzt nicht alles durchgelesen....

aber ich habe in nem vorherigem Posting gesehen:

#define INT0_ENABLE GIMSK |= (1<<INT0);


das kann nicht gehen ? bekommst du keine Warnung oder Fehlermeldung???

Das Semikolon gehört am Ende weg ! (das ist übrigens bei mehreren Makros bei dir so.....)


und ich würde es vorsichtshalber in Klammern setzen

also so:


#define INT0_ENABLE (GIMSK |= (1<<INT0))



P.S.
Ich weiß schon, wieso ich kein Freund von Makros bin :D
 
Hallo avr_newbie,
#define INT0_ENABLE GIMSK |= (1<<INT0);


das kann nicht gehen ? bekommst du keine Warnung oder Fehlermeldung???

Das Semikolon gehört am Ende weg ! (das ist übrigens bei mehreren Makros bei dir so.....)

das sollte eigentlich funktionieren, ich sehe hier keinen Fehler.

Es gibt dann einen Fehler, wenn man zB bei einem logischen Ausdruck für eine if-Anweisung ein Semikolon verwendet, dort muss man auch ggf. Klammern setzen.


Nochmal zum Problem:
Möglicherweise geht wird der Mikrocontroller sofort weider in den SleepMode versetzt, so dass man den Eindruck hat, dass er nicht durch EXT0 "aufgeweckt" wird. Hier kann man sich aber eigentlich ganz einfach mal über Pausen (_delay_ms()) und Ausgabe an Portpins (LED Blinken zB) bei geeigneten Stellen im Programmcode den Status anzeigen lassen, also debuggen.

Dirk :ciao:
 
Ich habe echt tagelang an diesen Code rum "gewerkelt", aufeinmal geht es....

Code:
	if ((Auto_Off == ABSCHALTZEIT) || (!(TCCR1B & (1<<CS10))))			// Ist Auto_Off = ABSCHALTZEIT, dann schlafen!
	{	
		Auto_Off=0;
		TIMER1_STOP;
		XPE_1_AUS; XPE_2_AUS; XPE_3_AUS; XPE_4_AUS;
[COLOR="#FF0000"][B]		_delay_ms(200);		[/B][/COLOR]				
		set_sleep_mode(SLEEP_MODE_PWR_DOWN);
		sleep_mode();							// Setzt den µC (nach Batteriewechsel) in den sleep_mode
	}

hat er vill. nicht schnell genug meinen INT0 wieder freigegeben ?

Danke Dirk!
 
Ich denke immer noch, daß Du vorher ein Problem mit dem Prellen hattest, das ganze hast Du dann mehr oder weniger erfolgreich durch irgendwelche herumdoktorei mit irgendwelchen bedingten Abfragen irgendwelcher Statusvariablen etwas in den Griff bekommen - allerdings dadurch neue Probleme bekommen.

Was ist jetzt, wenn zB Timer1 ein Compare-Event erreicht, während Du gerade in der INT0-ISR gelandet bist? Also Die INT0 hält den Timer an, deaktiviert INT0 und setzt Deinen Auto-Zähler auf Abschaltzeit. Dann verläßt Du irgendwann die ISR, woraufhin das Flag des Compare-IRQ wirksam wird. Dort wird jetzt AutoOff inkrementiert, ist also nicht mehr Abschaltzeit. Da der Taster noch gedrückt ist, wird INT0 nicht wieder freigegeben, Du verläßt die Compare-ISR also mit stehendem Timer, inaktivem INT0 und AutoOff ungleich Abschaltzeit.

Damit hängt das Programm in der Endlosschleife fest.

Zum Delay stellt sich jetzt die Frage, ob die automatische Abschaltung noch korrekt arbeitet. AutoOff wird ja alle 10 oder 20 ms (widersprüchliche Zahlen) inkrementiert, Du pollst aber nur alle 200+x ms...

Siehst Du eigentlich selbst bei Deinem Konzept noch durch? Ich tu's nämlich nicht. Du solltest ja eigentlich mal'n Programmablaufplan als Diskussionsbasis erstellen.
 
Hallo avr_newbie,


das sollte eigentlich funktionieren, ich sehe hier keinen Fehler.

Es gibt dann einen Fehler, wenn man zB bei einem logischen Ausdruck für eine if-Anweisung ein Semikolon verwendet, dort muss man auch ggf. Klammern setzen.

Dirk :ciao:

also ich habe bis jetzt noch nie ein Makro mit nem Semikolon am Ende gesehn..... schon allein, dass ein Makro ja mit #define anfängt finde ich das ganze eher untypisch, da noch das Semikolon hinten dran zu hängen....

aber wenns trotzdem geht ... wegen mir .... ;)
 
also ich habe bis jetzt noch nie ein Makro mit nem Semikolon am Ende gesehn..... schon allein, dass ein Makro ja mit #define anfängt finde ich das ganze eher untypisch, da noch das Semikolon hinten dran zu hängen....

Der Präprozessor ersetzt einfach nur die über #define definierten Macros. An der Zeile mit dem Semikolon finde ich nichts ungewöhnliches. Würde man hier ohne Semikolon abschließen, muss man das Semikolon unbedingt nach Aufruf des Macros setzen. Im oberen Fall ist halt zweimal ein Semikolon vorhanden, wenn der Präprozessor ersetzt hat, das merkt man nicht und der Compiler meckert hierbei nicht. Also ich finde, alles ganz normal und üblich.

Dirk :ciao:
 
...Siehst Du eigentlich selbst bei Deinem Konzept noch durch? Ich tu's nämlich nicht. Du solltest ja eigentlich mal'n Programmablaufplan als Diskussionsbasis erstellen.
Via PN hattest Du geantwortet, daß Du's (mehr oder weniger) noch tust, und gefragt was Du ändern müßtest...

ICH sehe wie gesagt in Deinem Code nicht wirklich durch (wegen C, und weil mir das angestrebte Konzept nicht wirklich klar ist). Entweder Du kommst mit den bisherigen knappen Antworten klar, oder Du gehst das nochmal von vorn an, stellst also erstmal ein Konzept/Programmablaufplan zur Diskussion (und eine Übersicht aller Ziele, außerdem den Schaltplan (auch, wenn der möglicherweise schon feststeht), mit angestrebten Timings).

Dann kann man Tipps für die Umsetzung geben, die einzelnen Teile angehen (->Du), und ggf dort auftauchende Probleme angehen...
Aber wir drehen uns im Kreis...

Hier mal ein "proof of concept" zu meinen Vorschlägen:
entprellung.png
erste Zeile= Taster-Pin
zweite=PWM-Ausgabe
dritte=Verweilzeit in der INT0-ISR
vierte=Entprell-Timer läuft, INT0 unterdrückt

hier mal ins Prellen beim "Drücken" gezoomt:
entprellung2.png
jetzt erkennt man schon etwas von der INT0-ISR.

Das Konzept hatte ich ja bisher oft genug breitgeredet - in Software kannst Du das in etwa ähnlich angehen.
Sleep ist noch nicht drin, insgesamt ist das natürlich noch optimierungsfähig - aber es geht schon mal.

Achso, ist ein Tiny2313A (dieweil der SOIC lag hier noch rum) @ 1MHz. Das ganze mal flink mittels Jagwires und einem Nullkraftsockel mit dem Logic8, dem AVRISP MKII und einem Breadboard zusammengesteckt.

Hier der Assembler-
Code:
/*
 *    ATtiny2313A @ 1MHz
 *  PWM-Ausgabe an OC0A (Timer0, fix 50%, 61Hz)
 *    Int0 schaltet PWM an/aus
 *  Entprellung über Timer1 (CTC, 250ms)
 *  für den LA wird OC0A beim abschalten auf Gnd gehalten (statt tristate)
 *                    B3 während des INT0 High
 *                    B4 während T1 läuft High
 */ 
.equ PWM_aus = (1<<wgm01)|(1<<wgm00)
.equ PWM_an  = (1<<com0a1)|(1<<com0a0)|(1<<wgm01)|(1<<wgm00)
.equ startTIM1 = (1<<wgm12)|(1<<cs11)
.equ stopTIM1 = (1<<wgm12)
.equ int0_LED = PB3
.equ T1_LED = PB4
.equ T0comp=127 ;50%
.equ T1comp=31249 ;250ms
.org 0x00
    rjmp start
.org INT0addr
    rjmp tasterErkannt

start:
;***Beinchen*** einstellen
;INT0-Bein via internem Pullup hochziehen
sbi portd, portd2
;PWM-Ausgabe und Stausausgabe-Beinchen auf Ausgang schalten
ldi r16, (1<<PB2)|(1<<int0_LED)|(1<<T1_LED)
out DDRB, r16
;***Timer0*** PWM-Ausgabe Kanal A, 50%, ca 61Hz
ldi r16, PWM_aus
out tccr0a, r16            ;FastPWM KanalA (aus)
ldi r16, T0comp
out ocr0a, r16            ;50% 
ldi r16, (1<<cs01)|(1<<cs00)
out tccr0b, r16            ;Prescaler=64 -> 61Hz
;***Timer1*** "Entprellung" ca 250ms (CTC bis OC1A=31249, Prescaler=8)
;TCCR1A bleibt default, TCCR1B wird in den IRQs geschrieben, TCCR1C ist ungenutzt
ldi r16, high(T1comp)
out OCR1AH, r16
ldi r16, low(T1comp)
out OCR1AL, r16        ;Reichweite festlegen (CTC)
;***INT0*** low-Level ist default
ldi r16, (1<<int0)
out gimsk, r16        ;IRQ scharf
sei
loop:
    in r16, tifr
    andi r16, (1<<ocf1a)    ;Z=0 bei Flag=1
    breq loop        ;Sprung bei Z=1, also FLag=0
    ldi r16, (1<<ocf1a)
    out tifr, r16        ;flag gelöscht
    ldi r16, stopTIM1
    out tccr1b, r16        ;Entprelltimer steht
    cbi portb, T1_LED
    ldi r16, (1<<INT0)
    out gimsk, r16        ;INT0 reaktiviert

    ;sleep?    
    rjmp loop

tasterErkannt:
    sbi portb, int0_LED
    push r16
    in r16, sreg
    push r16
    ldi r16, 0
    out gimsk, r16    ;INT0 deaktiviert Cave!! alle anderen auch
    ldi r16, startTIM1
    out tccr1b, r16    ;Entprelltimer läuft
    sbi portb, T1_LED
    in r16, tccr0a
    subi r16, (1<<com0a1)|(com0a0)
    brcc compModeSchreiben
    ldi r16, (1<<com0a1)|(1<<com0a0)|(1<<wgm01)|(1<<wgm00)
compModeSchreiben:
    out tccr0a, r16        ;compareMode invertiert
    pop r16
    out sreg, r16
    pop r16
    cbi portb, int0_LED
    reti
Timer0 (also der PWM-Timer) läuft durch, und könnte im OC0B und/oder TOV0 'ne Zeitbasis generieren (wobei der im Tiefschlaf automatisch angehalten werden sollte)

Anfrage an Dino bzw andere MODs: Wie bekomme ich die Anzeige der Bilder erzwungen - also auf einem größeren Maß?

P.S.: Hab mir bei der Logic8-Software 'n Ast gesucht, wie das mit dem Screenshoot geht - warum ist der "Options-Button" unsichtbar?!
 
Anfrage an Dino bzw andere MODs: Wie bekomme ich die Anzeige der Bilder erzwungen - also auf einem größeren Maß?

Auch wenn ich weder Dino noch Mod bin, du musst in den WYSIWYG Editor wechseln (das erste Symbol im Editor) und denn doppelt auf das Bild klicken, dann öffnet sich ein Menü worin du die Größe festlegen kannst :)
(ich musste auch erst nachfragen damals. Ist so ein bisschen wie "du musst doch nur den Nippel durch die Lasche zieh'n".)
 
Hi,

Auch wenn ich weder Dino noch Mod bin, du musst in den WYSIWYG Editor wechseln (das erste Symbol im Editor) und denn doppelt auf das Bild klicken, dann öffnet sich ein Menü worin du die Größe festlegen kannst :)
stimmt. So gehts.
Der WYSIWYG-Editor ist der linke obere Button im Editor. Wenn man mit der Maus drübergeht (ohne klicken) dann erscheint ne Info "Zum WYSIWYG-Editor wechseln".
Die Info wie das geht hab ich mal von Dirk bekommen ;)

Gruß
Dino
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)