Hallo

Eher zufällig habe ich einen PCF8574A rumliegen, eine 4x4-Tastatur und 'nen RP6. Und ich wollte schon immer mal in die I2C-Technik einsteigen. Hier meine Umsetzung der Aufgabe:

Der PCF8574(A) kennt, anders als die AVRs, nur zwei Zustände an seinen Ausgängen. Eine "0" schaltet den Ausgang auf Low, eine "1" ist mit einem Eingang mit internem PullUp des AVRs vergleichbar. Die Spalten der Matrix sind mit den Bits 0 bis 3 des PCF8574 verbunden, die Zeilen mit den Bits 4 bis 7. Zur Abfrage schaltet man nacheinander die Bits 0 bis 3 auf Low und prüft dann jeweils, ob die High-Pegel der Bits 7-4 durch einen Tastenkontakt auf Low gezogen werden. Eigentlich sehr einfach, ich bin deshalb auch nicht der Erste, der das hinbekommen hat;)

Bild hier   Bild hier   Bild hier  

Bild hier  
http://www.youtube.com/watch?v=tMIc6e9dLnY

Das Programm auf Basis der RP6 I2C-Library:
Code:
// 4x4-Tastenmatrix an PCF8574A                                     5.11.2010 mic

// https://www.roboternetz.de/phpBB2/ze...ag.php?t=56693

#include "RP6RobotBaseLib.h"
#include "RP6I2CmasterTWI.h"

uint8_t c=0, leds=0;
uint16_t tasten;

uint16_t PollSwitch16(void)
{
	uint8_t i, j, x, temp;
	uint16_t mask=0;

	temp=I2CTWI_readByte(0b01110001);         // aktuelles Bitmuster sichern
	for(j=0; j<4; j++)
	{
		I2CTWI_transmitByte(0b01110000, ~(1<<j)); // Pin j (0 bis 3) auf Low
		sleep(2);           								// Warten auf Pegel
		x=(I2CTWI_readByte(0b01110001)>>4); 		// Eingang 7-4 wird zu Bit 3-0 in x
		for(i=0; i<4; i++)   							// Bits 0-3 überprüfen
			if(!(x & (1<<i))) 							// Wenn Eingang low ist wurde die Taste gedrückt
				mask += (1 << (i*4)) * (1<<j); 		// entsprechendes Bit in Maske setzen
	}
   I2CTWI_transmitByte(0b01110000, temp);       // gespeichertes Bitmuster ausgeben
	return(mask);
}
int main(void)
{
   initRobotBase();
 	I2CTWI_initMaster(100);
	startStopwatch1();
	startStopwatch2();
   while(1)
   {
		if(getStopwatch1() > 300)  // Lauflicht an Pin 0 bis 7 des PCF8574A
		{
			setStopwatch1(0);
			I2CTWI_transmitByte(0b01110000, ~(1<<c));
			c++;
			if(c>7) c=0;
   	}

		if(getStopwatch2() > 50) // Tastenabfrage
		{
			setStopwatch2(0);
			tasten=PollSwitch16();
			if(tasten)
			{
				writeInteger(tasten, 2); // Bitmuster des Keypads an Terminal ausgeben
				writeChar('\n');
				
				leds=0; // Spielerei mit den Leds
				if(tasten & (1<<0)) leds+=8; // Taste 1
				if(tasten & (1<<1)) leds+=1;
				if(tasten & (1<<2)) leds+=16;
				if(tasten & (1<<3)) leds+=2;
				if(tasten & (1<<4)) leds+=32;
				if(tasten & (1<<5)) leds+=4; // Taste 6
				setLEDs(leds);
			}
			else setLEDs(0); // Keine Taste gedrückt
   	}
	}
   return(0);
}
Gruß

mic