C Increment / Decrement ?!

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Hallo,

Ich habe aktuell das Problem, dass meine 2´ te "if Abfrage" nicht klappt ?!
Wenn ich den "Drehencoder" in die Richtung "Aufwährts" drehe... klappt die Abfrage (if Counter >= 30)
Drehe ich den "Drehencoder" in die Richtung "Rückwährts"... und frage ab (if Counter <= 1) klappt dies nicht ?!

Was mache ich falsch ?

Die Abfrage von dem Encoder klappt (mit LED´s ausprobiert)

:confused:
 
Code:
/************************************************************************************************************
*								    	Drehimpulsgeber (Optisch)											*
*								   __________________________________										*
*																											*
*			    			- Auswerten eines Drehimpulsgeber´s (Drehencoder)								*
*																											*
* 																											*
*										MRL - 20 C	(ohne Taster)											*
*																											*
*											Beschreibung :													*
*				  Phase_A wird auf INT0 gelegt und INT0 wird auf "fallende Flanke"							*
*				  eingestellt. In der ISR von INT0 wird der aktuelle Status von "Phase_B"					*
				  ausgewertet! Die Drehrichtung wird in der Variable "Drehrichtung" gepeichert	*			*
************************************************************************************************************/

#define F_CPU 16000000

#define Phase_A ((PIND & (1<<PIND6))) // Phase A
#define Phase_B ((PIND & (1<<PIND4))) // Phase B

#define LINKS_AN PORTB |= (1<<PD0)
#define RECHTS_AN PORTB |= (1<<PD1)

#define HIGH_POWER_ROT_AN PORTD |= (1<<PD0)
#define HIGH_POWER_ROT_AUS PORTD &= ~(1<<PD0)

#define HIGH_POWER_GRUEN_AN PORTB |= (1<<PB6)
#define HIGH_POWER_GRUEN_AUS PORTB &= ~(1<<PB6)

#define HIGH_POWER_GRUEN_TOGGLE PORTB ^= (1<<PB6)

#define LINKS_AUS PORTB &= ~(1<<PD0)
#define RECHTS_AUS PORTB &= ~(1<<PD1)

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

volatile uint8_t Drehrichtung;
volatile uint8_t Counter;

int main(void)
{
	
	PORTD |= ((1<<PD4) | (1<<PD6)); // PullUp´s aktivieren
	DDRB  |= ((1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) | (1<<PB4) | (1<<PB5) | (1<<PB6) | (1<<PB7)); // Ausgänge für LED´s
	DDRD  |= (1<<PD0);
	
	MCUCR |= (1<<ISC01); // INT0 Sense auf fallende Flanke einstellen
	GICR  |= (1<<INT0);  // INT0 Interrupt Enable 
	
	sei();
	
    while(1)
    {
		
		switch (Drehrichtung)
		{
			case 1:
			{
				LINKS_AN;
				HIGH_POWER_GRUEN_AN;
				_delay_ms(100);
				LINKS_AUS;
				HIGH_POWER_GRUEN_AUS;
	
				Drehrichtung = 3;
			}
				break;
			
			case 2:
			{
				RECHTS_AN;
				HIGH_POWER_ROT_AN;
				_delay_ms(100);
				RECHTS_AUS;
				HIGH_POWER_ROT_AUS;
				
				Drehrichtung = 3;
			}
				break;
			
			
		} // Ende switch (Drehrichtung) 
			
			if (Counter >= 30)
			{
				HIGH_POWER_GRUEN_AN;
				HIGH_POWER_ROT_AUS;
			}
			
			if (Counter <= 1)
			{
				HIGH_POWER_ROT_AN;
				HIGH_POWER_GRUEN_AUS;
			}
			
			

    } // Ende while(1)
} // Ende Main


ISR (INT0_vect)

{
	
	
	if (Phase_B)
	{
		Drehrichtung = 1;
		Counter = Counter + 1;
	}

	if (Phase_A)
	{
		Drehrichtung = 2;
		Counter = Counter - 1;
	}

	
}
 
Phase A triggert mit 'ner fallenden Flanke den INT0?
Dann sollte in der ISR Phase A auch immer 0 liefern (ok, der Pegel könnte sich in den wenigen hundert Nanosekunden auch ändern), insofern macht der Test dort keinen Sinn, oder?
(Hat Dirk da nicht schon mal drauf hingewiesen??)
 
Genau.
Schau dir erst mal nur deine ISR an. Die If Abfrage des Signals, welches den EXT Int triggert entfernt du. Das zweite Signal fragst du in der ISR ab. Jetzt ueberlege dir mal, was passiert, wenn das Argument der Abfrage nicht WAHR ist ... Nichts. Du erkennt also nur eine Drehrichtung. Verwende hier einfach mal ein ELSE und setzte die Variable für die Drehrichtung richtig.

Dirk :ciao:
 
Es klappt ;)

Code:
ISR (INT0_vect)

{
	
	
	if (Phase_A)
	{
		Drehrichtung = 1;
		Counter++;
	}
		else
	{
		Drehrichtung = 2;
		Counter--;
	}


	
}
 
Also irgendwas stimmt hier nicht...

Wenn PhaseA als externer Interrupt die ISR mit 'ner fallenden Flanke triggert, ist in der ISR (prellfreies Signal und moderate Drehgeschwindigkeit vorrausgesetzt - ansonsten kannst Du den Algorithmus eh vergessen) PhaseA immer=0, somit wir immer nur der Else-Zweig ausgeführt, oder?

Hmm... PhaseA ist PD6, das soll jetzt auch INT0 sein? Welchen Controller verwendest Du? Mir fällt da grad keiner zu ein...
Hmm2... Dein Programm fragt nie(!) PhaseB=PD4 ab... Dein Encoder kommt mit einer Leitung aus:hmmmm:
der INT0 liegt mit PhaseB auf D4, oder?!?
 

Ü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)