Hallo

Ich habs mit PS2 schonmal geschafft.
Weil jede USB maus hat einen PS2 Modus. Mit dem richtigen code kann man dann eine software ps2 schnittstelle nachbilden und die ps2 maus auslesen.

mein code hier kann gleich 2 mäuse gleichzeitig ansprechen. praktisch weil eine einzige maus allein keine drehung messen kann und somit die position auch nicht berechenbar ist.

ich weis leider nicht den originalen autor. ich hab den code von einem freund bekommen und etwas erweitert aber mehr nicht. die pin belegung sollte aus den #define angaben herausfindbar sein.

ps2.h
Code:
/***************************************************************************
 *   Copyright (C) 2008 by Thomas Gruebler and CRCT                        *
 *   thomas  a t  gruebler     d o t    at                                 *
 *   www.crct-robots.eu                                                    *
 *
 *   Belegung Stecker in der Maus
 *   Gruen | Weis | Rot | 2x Schwarz
 *   Clock   Data   VCC    GND
 ***************************************************************************/

#ifndef PS2_H
#define PS2_H

#include "global.h"

#include "main.h"

#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
	unsigned char head;
	char rwheel;
	char lwheel;
} ps2_movement_type;

// #define PS2_CLCK_IS_HI          (PINC & (1<<PC1))
// #define PS2_DATA_IS_HI          (PINC & (1<<PC0))
// #define PS2_CLCK_LO             DDRC |= (1<<PC1)
// #define PS2_CLCK_HI             DDRC &= ~(1<<PC1)
// #define PS2_DATA_LO             DDRC |= (1<<PC0)
// #define PS2_DATA_HI             DDRC &= ~(1<<PC0)

#define PS2_CLCK_IS_HI          (PINC & (1<<clkpin))
#define PS2_DATA_IS_HI          (PINC & (1<<datapin))
#define PS2_CLCK_LO             DDRC |= (1<<clkpin)
#define PS2_CLCK_HI             DDRC &= ~(1<<clkpin)
#define PS2_DATA_LO             DDRC |= (1<<datapin)
#define PS2_DATA_HI             DDRC &= ~(1<<datapin)

#define MOUSE1 PC1, PC0
#define MOUSE2 PC3, PC2
#define MOUSE clkpin, datapin

unsigned char ps2_wait_long_for_clck_lo (unsigned char clkpin);
unsigned char ps2_wait_for_clck_lo (unsigned char clkpin);
unsigned char ps2_wait_for_clck_hi (unsigned char clkpin);
unsigned char ps2_send (unsigned char val, unsigned char clkpin, unsigned char datapin);
unsigned char ps2_read (unsigned char * buffer, unsigned char len, unsigned char bytes_read, unsigned char clkpin, unsigned char datapin);
void fatal_error (unsigned char errcode, unsigned int addinfo);

void maus_init(unsigned char clkpin, unsigned char datapin);

#endif
ps2.c
Code:
/***************************************************************************
 *   Copyright (C) 2008 by Thomas Gruebler and CRCT                        *
 *   thomas  a t  gruebler     d o t    at                                 *
 *   www.crct-robots.eu                                                    *
 ***************************************************************************/

#include "ps2.h"

unsigned char ps2_wait_long_for_clck_lo (unsigned char clkpin) // PS/2: Bis zu 10ms auf CLCK=LO warten
{
	unsigned int ms = 1100;
	while ((ms--)!=0)
	{                                                      // wenn der Timer läuft
		if (!PS2_CLCK_IS_HI) return 0x00;                  // und CLCK geht auf LO -> Return OK
		_delay_ms(0.01);
	}
	return (0xFF);                                         // Timer abgelaufen -> Return Timeout
}


unsigned char ps2_wait_for_clck_lo (unsigned char clkpin) // PS/2: Bis zu 50µs auf CLCK=LO warten
{
	unsigned int us = 50000;                                           // Timer 0 Preload  50µs
	while ((us--)!=0)
	{                                                      // wenn der Timer läuft
		if (!PS2_CLCK_IS_HI) return 0x00;                  // und CLCK geht auf LO -> Return OK
		_delay_us(.001);
	}
	return (0xFF);                                         // Timer abgelaufen -> Return Timeout
}

unsigned char ps2_wait_for_clck_hi (unsigned char clkpin)                      // PS/2: Bis zu 50µs auf CLCK=HI warten
{
	unsigned int us = 50000;                                         // Timer 0 Preload  50µs
	while ((us--)!=0)
	{                                                    // wenn der Timer läuft
		if (PS2_CLCK_IS_HI) return 0x00;                 // und CLCK geht auf LO -> Return OK
		_delay_us(.001);
	}
	return (0xFF);                                       // Timer abgelaufen -> Return Timeout
}

unsigned char ps2_send (unsigned char val, unsigned char clkpin, unsigned char datapin)
{
	unsigned char i = -1;
	unsigned char pb = 0;
 
	PS2_CLCK_LO;                                             // setze CLCK LO
	delay_us(100);								               // warte 100µs
	PS2_DATA_LO;                                             // setze CLCK LO, DATA LO
	delay_us(25); 								                // warte 25µs
	PS2_CLCK_HI;                                             // setze CLCK HI, DATA LO

	if (ps2_wait_long_for_clck_lo(clkpin)) goto ps2_send_error;    // 10ms auf fallende Flanke (CLCK) warten

	for (i=0; i<8; i++)
	{                                                        // Datenbits LSB->MSB
		if (val & 0x01)
		{                                                   // Bit ist 1
			pb++;                                           // Parityzähler erhöhen
			PS2_DATA_HI;                                    // Datenleitung HI sezen
		}
		else
		{                                                   // Bit ist 0
			PS2_DATA_LO;                                    // Datenleitung LO setzen
		}
		if (ps2_wait_for_clck_hi(clkpin)) goto ps2_send_error;    // 50µs auf steigende Flanke (CLCK) warten
		if (ps2_wait_for_clck_lo(clkpin)) goto ps2_send_error;    // 50µs auf fallende Flanke (CLCK) warten
		val = val >> 1;
	}
 
	if (pb & 0x01)                                       // PB ungerade?
		PS2_DATA_LO;                                     // -> kein Parity Bit
	else                                                 // PB gerade?
		PS2_DATA_HI;                                     // -> Parity Bit
	if (ps2_wait_for_clck_hi(clkpin)) goto ps2_send_error;     // 50µs auf steigende Flanke (CLCK) warten
	if (ps2_wait_for_clck_lo(clkpin)) goto ps2_send_error;     // 50µs auf fallende Flanke (CLCK) warten
 
	i++;
	PS2_DATA_HI;                                        // CLCK und DATA freigeben
	PS2_CLCK_HI;                                        // CLCK und DATA freigeben
	if (ps2_wait_for_clck_hi(clkpin)) goto ps2_send_error;    // 50µs auf steigende Flanke (CLCK) warten
	if (ps2_wait_for_clck_lo(clkpin)) goto ps2_send_error;    // 50µs auf fallende Flanke (CLCK) warten

	PS2_CLCK_LO;                                        // CLCK LO setzen (Bus blockieren)
	return (0);                                         // Fehlerfrei

	ps2_send_error:                                     // Fehlerhandling
			PS2_CLCK_LO;                                // CLCK LO setzen (Bus blockieren)
	return (i);                                         // Fehlernummer zurückgeben

}

unsigned char ps2_read (unsigned char * buffer, unsigned char len, unsigned char bytes_read, unsigned char clkpin, unsigned char datapin)
{
	unsigned char i;
	bytes_read = 0;                                    // Anzahl gelesener Zeichen
	PS2_CLCK_HI;                                       // CLCK freigeben

	while (bytes_read < len)
	{
		buffer[bytes_read] = 0;
		for (i=1; i<=11; i++)
		{
			if (i==1)                                                   //beim Startbit
			{ if (ps2_wait_long_for_clck_lo(clkpin)) goto ps2_read_error; }   //10ms auf fallende Flanke (CLCK) warten
			else                                                        //sonst
			{ if (ps2_wait_for_clck_lo(clkpin)) goto ps2_read_error; }        //50µs auf fallende Flanke (CLCK) warten

			if (i>=2 && i<=9)
			{                                                           // wenn Datenbit
				if (PS2_DATA_IS_HI)                                     // HI
					buffer[bytes_read] = (buffer[bytes_read]>>1) | 0x80;
				else                                                     // LO
					buffer[bytes_read] = (buffer[bytes_read]>>1) | 0x00;
			}
			if (ps2_wait_for_clck_hi(clkpin)) goto ps2_read_error;           // 50µs auf steigende Flanke (CLCK) warten   
		}
		bytes_read++;                                       // Bytezähler erhöhen
	}

	PS2_CLCK_LO;                                            // CLCK LO setzen (Bus blockieren)
	return (0);                                             // Fehlerfrei

	ps2_read_error:                                         // Fehlerhandling
			PS2_CLCK_LO;                                    // CLCK LO setzen (Bus blockieren)
	return (i);                                             // Fehlernummer zurückgeben
}

void fatal_error (unsigned char errcode, unsigned int addinfo)
{
    // Fehlerbehandlung hier rein....
	LEDP ^= (1<<LED3);		//Led3 toggeln

// 	while (1) {}
}

void maus_init(unsigned char clkpin, unsigned char datapin)
{
	
	unsigned char  c=0,i=0;                                               // Hilfsvariablen

	
	if (ps2_send(0xFF, MOUSE))   fatal_error(0x01,0x00);                     // PS/2 Cmd: Reset
	delay_ms(20);                                                       // 20ms warten

	if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x02,0x00);                     // auf Lesefehler von PS/2 prüfen
	if (c != 0xFA)        fatal_error(0x03,c);                        // auf Quittung (ACK/$FA) prüfen
	delay_ms(1000);                                                   // 1s warten (50*20ms)
	if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x04,0x00);                     // auf Lesefehler von PS/2 prüfen
	if (c != 0xAA)        fatal_error(0x05,c);                        // auf BAT-Quittung ($AA) prüfen
	if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x06,0x00);                     // auf Lesefehler von PS/2 prüfen (Device ID überspringen)


	delay_ms(1000);                                                   // 1s warten (50*20ms)
	if (ps2_send(0xF3, MOUSE))   fatal_error(0x17,0x00);                     // PS/2 Cmd: Set Sample Rate
	delay_ms(20);                                                     // 20ms warten
	if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x18,0x00);                     // auf Lesefehler von PS/2 prüfen
	if (c != 0xFA)        fatal_error(0x19,c);                        // auf Quittung (ACK/$FA) prüfen

	delay_ms(1000);                                                   // 1s warten (50*20ms)
	if (ps2_send(200, MOUSE))   fatal_error(0x1A,0x00);                  // 200 Samples per second
	delay_ms(20);                                                     // 20ms warten
	if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x1B,0x00);                     // auf Lesefehler von PS/2 prüfen
	if (c != 0xFA)        fatal_error(0x1C,c);                        // auf Quittung (ACK/$FA) prüfen


	delay_ms(1000);                                                   // 1s warten (50*20ms)
	if (ps2_send(0xE8,MOUSE))   fatal_error(0x07,0x00);                     // PS/2 Cmd: Set Resolution
	delay_ms(20);                                                     // 20ms warten
	if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x08,0x00);                     // auf Lesefehler von PS/2 prüfen
	if (c != 0xFA)        fatal_error(0x09,c);                        // auf Quittung (ACK/$FA) prüfen

	delay_ms(1000);                                                   // 1s warten (50*20ms)
	if (ps2_send(0x03, MOUSE))   fatal_error(0x0A,0x00);               // Resolution 2 = 4 counts/mm = 2 Impulse pro Zahn
	delay_ms(20);                                                     // 20ms warten
	if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x0B,0x00);                     // auf Lesefehler von PS/2 prüfen
	if (c != 0xFA)        fatal_error(0x0C,c);                        // auf Quittung (ACK/$FA) prüfen
	delay_ms(1000);                                                   // 1s warten (50*20ms)
	if (ps2_send(0xF0, MOUSE))   fatal_error(0x0D,0x00);                     // PS/2 Remote Mode einschalten
	delay_ms(20);                                                     // 20ms warten
	if (ps2_read(&c,1,i, MOUSE)) fatal_error(0x0E,0x00);                     // auf Lesefehler von PS/2 prüfen
	if (c != 0xFA)        fatal_error(0x0F,c);                        // auf Quittung (ACK/$FA) prüfen
	
}
ich hoffe halt du kannst C und verstehst es so ungefähr. das ist originalcode aus meinem robocupjunior robo ^^

das verwendete ich zum debuggen um die maussensorwerte am UART auszugeben:
Code:
void mouse_to_uart(void)
{
 
	int xl = 0;
	int yl = 0;
 
	int xr = 0;
	int yr = 0;
 
	unsigned char z = 0;
 
	unsigned char  c=0,i=0;                                               // Hilfsvariablen
	ps2_movement_type moved;                                          // Bewegungsmeldung
 
	uart_puts("\n---Maus_Debug---");
	uart_puts("\nx Maus1 y   -  x Maus2 y");
 
	while(1) {
 
		while ((z++)<10) {
			//PS/2 Daten auslesen++++++++++++++++++
 
			if (ps2_send(0xEB, MOUSE1))   fatal_error(0x0A,0x00);                     // READ DATA Command
			delay_ms(20);                                                    // 20ms warten
			if (ps2_read(&c,1,i, MOUSE1)) fatal_error(0x0B,0x00);                     // auf Lesefehler von PS/2 prüfen
			if (c != 0xFA)        fatal_error(0x0C,c);
 
			if (!ps2_read((unsigned char*)&moved,3,c, MOUSE1))
			{
				//Maus1 daten auslesen
				yl += (long)moved.lwheel;
				xl += (long)moved.rwheel;
			}
 
			if (ps2_send(0xEB, MOUSE2))   fatal_error(0x0A,0x00);                     // READ DATA Command
			delay_ms(20);                                                    // 20ms warten
			if (ps2_read(&c,1,i, MOUSE2)) fatal_error(0x0B,0x00);                     // auf Lesefehler von PS/2 prüfen
			if (c != 0xFA)        fatal_error(0x0C,c);
 
			if (!ps2_read((unsigned char*)&moved,3,c, MOUSE2))
			{
				//Maus2 daten auslesen
				yr += (long)moved.lwheel;
				xr += (long)moved.rwheel;
			}
// 			delay_ms(5);
		}
		z = 0;
 
		uart_puts("\nXL: "); uart_puti(xl/2);
		uart_puts("  YL: "); uart_puti(yl/2);
		uart_puts("  XR: "); uart_puti(xr/2);
		uart_puts("  YR: "); uart_puti(yr/2);
 
	}
}
Grüße
Thomas