Hallo Leute,

ich bin am verzeweifeln. Ich schaffe es einfach nicht vernünftig einen Drehimpulsgeber auszuwerten. Ich habe mir dafür jetzt einen extra guten (und teuren) Geber mit optischer Auswertung gekauft, um das Problem mit dem Prellen einigermassen in den Griff zu bekommen. Der Geber hat 32 Rastungen pro Umdrehung und ich würde gerne einen Impuls pro Rastung nach links oder rechts erhalten.

Ich habe dafür sogar extra einen Atmel Tiny 2313 verbaut, der nichts anderes zu tun hat wie den Encoder auszuwerten. Leider springt der Wert trotzdem oft in die falsche Richtung, wenn ich drehe. Egal bei welcher Geschwindigkeit.

Hier mal mein Code bis jetzt:

Code:
#define AVRGCC

#include <avr/io.h>
#include <compiler.h>

/**
PD2	Spur A
PD3 Spur B

PB0	links
PB1	rechts

	1	2	3	4
A	0	1	1	0
B	0	0	1	1
**/

#define Links1							PORTB = (PORTB | (1<<PB0))
#define Links0							PORTB = ~(~PORTB | (1<<PB0))

#define Rechts1							PORTB = (PORTB | (1<<PB1))
#define Rechts0							PORTB = ~(~PORTB | (1<<PB1))

#define SpurA							((PIND & 0b00000100) == 0)
#define SpurB							((PIND & 0b00001000) == 0)

bool lastDir = TRUE;

U8 read (void)
{
	if (SpurA)
	{
		if (SpurB)
			return (3);
		else
			return (2);
	}
	else
	{
		if (SpurB)
			return (4);
		else
			return (1);
	}
}

void links (void)
{
	U8 i1;
	
	Links0;
	for (i1 = 0; i1 < 0xFF; i1++)
		asm volatile ("NOP");
	Links1;
	lastDir = FALSE;
}

void rechts(void)
{
	U8 i1;
	
	Rechts0;
	for (i1 = 0; i1 < 0xFF; i1++)
		asm volatile ("NOP");
	Rechts1;
	lastDir = TRUE;
}

int main (void)
{
	U8 AlterStatus;
	U8 NeuerStatus;	
	U8 i1;

	DDRB = 0b00000011;
	PORTB = 0b00000011;

	DDRD = 0b00000000;
	PORTD = 0b00001100;

	for (i1 = 0; i1 < 0xFF; i1++)
		asm volatile ("NOP");

	AlterStatus = read ();

	while (1)
	{
		NeuerStatus = read ();

		if (AlterStatus != NeuerStatus)
		{
			switch (AlterStatus)
			{
				case 1:	{	switch (NeuerStatus)
							{
								case 2:	{ rechts (); break; }
								case 3:	{ if (lastDir)
											rechts ();
										  else
										  	links ();
										  break;
										}		
								case 4: { links ();  break; }
							}
							break;
						}
				case 2:	{	switch (NeuerStatus)
							{
								case 1: { links ();  break; }
								case 3: { rechts (); break; }
								case 4:	{ if (lastDir)
											rechts ();
										  else
										  	links ();
										  break;
										}		
							}
							break;
						}
				case 3:	{	switch (NeuerStatus)
							{
								case 1:	{ if (lastDir)
											rechts ();
										  else
										  	links ();
										  break;
										}
								case 2: { links ();  break; }
								case 4: { rechts (); break; }
							}
							break;
						}
				case 4:	{	switch (NeuerStatus)
							{
								case 1: { rechts (); break; }
								case 2:	{ if (lastDir)
											rechts ();
										  else
										  	links ();
										  break;
										}		
								case 3: { links ();  break; }
							}
							break;
						}
			}

			AlterStatus = NeuerStatus;
		}
	}
	
	return (0);
}
Wer kann mir sagen wo es hängt, oder einen Code schicken, der auch funktioniert. Der Tiny arbeitet mit dne Werkseinstellungen der Fuses und ohne Quarz mit der internen Takterzeugung..

Viele Grüße
Andreas