Daten von TWI-Port-Expander an LabView weiter geben

Bobbybau91

Neues Mitglied
15. Nov. 2013
31
0
0
33
Ayl, Germany
Sprachen
  1. ANSI C
Hallo Zusammen,

für ein Projekt in der Schule muss ich mit meinem Microcontroller
(MyAVR-Board MK2 mit Atmgea8) einen Schaltverlauf eines Hilfsschalters
mit 16 Kontakten nach Labview ausgeben und auswerten.

Leider bin ich ein absoluter Neuling in C-Programmierung und nun habe
ich auch noch gesehen, dass der Port-Expander, den ich mir mangels
Eingängen bestellt habe, über BUS angesteuert wird. Den Programmcode für
die Übergabe an LabView hätte ich ohne BUS noch anpassen können, aber
das sprengt jetzt leider mein Wissen.

Könnte mir jemand einen Anstoß geben, wie ich die Eingänge vom Port
Expander abfragen und weitergeben kann?

Die normalen Eingänge werden so abgefragt und weiter gegeben:

Code:
// Eingänge zusammenstellen
// Eingänge mit '0' initialisieren

  Eingaenge[0] = '0';
  Eingaenge[1] = '0';
  Eingaenge[2] = '0';
  Eingaenge[3] = '0';
  Eingaenge[4] = '0';
  Eingaenge[5] = '0';

// Eingangs-PINs liegen an PULL-UP-Widerstand und werden bei Beschaltung auf Masse gezogen

  if(bit_is_clear(PIND,2))     // Wenn Eingang PIND,2 = 0, dann
  {
  _delay_ms(23);        // Entprellzeit    
  if(bit_is_clear(PIND,2))     // Wenn Eingang PIND,2 nach Entprellung = 0, dann
      {
        Eingaenge[0]='1';   // binärer Wert an LabVIEW
      }
    }

  if(bit_is_clear(PIND,3))     // Wenn Eingang PIND,3 = 0, dann
  {
  _delay_ms(23);        // Entprellzeit  
  if(bit_is_clear(PIND,3))     // Wenn Eingang PIND,3 nach Entprellung = 0, dann
      {
        Eingaenge[1]='1';   // binärer Wert an LabVIEW
      }
    }

...

Eingaenge[10] = '\0';      // Ausgabestring beenden mit \0

// gesamten Eingangs-String an PC senden
    
  print (Eingaenge);
       }
}

Danke im Vorraus, würde mir sehr helfen
 
Hallo und Willkommen im AVR-Praxis-Forum!

Welche "Port-Expander"-Lösung setzt du denn ein? Das müsste man wissen, um weiterhelfen zu können :)

Dirk :ciao:


EDIT:

Bezüglich TWI: Vielleicht kannst du hier etwas aus einem meiner Projekte verwenden ...
Blog: Atmel Studio C Library für Seven Segment LED Backpack

Schau dir dort mal TWI_Master.c an.
 
Hi,

Erstens: Wieviel Zeit hast Du noch?
Zweitens: Sollenn wir jetzt bezüglich des Schalters/Transponders hellsehen? Datenblatt?
Drittens: Du kannst einen ganzen (8bit)Port auch als ganzes lesen.
Viertens: zum TWI liest Du Dir erstmal das Datenblatt des Expanders und das des Mega8 (Stichwort TWI) durch
Fünftens: Willkommen im Forum
(Auch, wenns wahrscheinlich nur für kurz ist...)
 
Oh Sorry, ich wusste doch das da was fehlt :D Ich verwende diesen Expander:
http://shop.myavr.de/index.php?sp=article.sp.php&artID=200000#

Habe jetzt auch das Datenblatt gefunden http://shop.myavr.de/index.php?ws=download_file.ws.php&dlid=163&filename=produkte/mytwi/techb_mytwi-portexpander_de_en.pdf, dort steht das Beispiel für eine Tasterabfrage. Muss ich diesen kompletten Quelltext in meinen vorhandenen Einfügen, damit der Expander funktioniert oder reichen Teile davon?


Code:
//---------------------------------------------------------------------- 
// Titel : Beispielprogramm Portexpander 
//---------------------------------------------------------------------- 
// Funktion : Ansteuerung einer LED via Tastereingabe 
// Schaltung : ... 
//---------------------------------------------------------------------- 
// Prozessor : ATmega8 
// Takt : 3.6864 MHz 
// Sprache : C 
// Datum : 24.09.09 
// Version : 1.0 
// Autor : Christian Müller 
//---------------------------------------------------------------------- 
#define F_CPU 3686400 
#include <avr\io.h> 
#define BAUD 9600 
//--------------------------------------------------------------------------------- 
// TWI-Funktionssammlung 
#ifndef TWI_CLOCK 
#define TWI_CLOCK 100000 // Geschwindigkeit des TWI-Busses 
#endif 
// TWCR - Control-Register-Bits 
#define _TWINT 0b10000000 
#define _TWEA 0b01000000 
#define _TWSTA 0b00100000 
#define _TWSTO 0b00010000 
#define _TWWC 0b00001000 
#define _TWEN 0b00000100 
#define _TWIE 0b00000001 
 
void twiInitMaster(uint8_t twiAdr); 
void twiStart(); 
void twiStop(); 
void twiWriteByte(uint8_t data, uint8_t ackn); 
uint8_t twiReadByte(uint8_t ackn); 
void twiInitPCA(); 
void outPorts(uint8_t portNr, uint8_t data); 
uint8_t readPorts(uint8_t portNr);

//------------------------------------------------------------------------ 
// main 
//------------------------------------------------------------------------ 
int main () 
{ 
 uint8_t data; 
 twiInitMaster(0x40); 
 twiInitPCA(); 
 do 
 { 
 data=readPorts(0); // Abfrage Pins an PortA 
 if(data == 0xFE) // Taster gedrückt 
 { 
 outPorts(1,0xFF); // alle Pins an PortB geschalten 
 } 
 else 
 { 
 outPorts(1,0x00); // kein Pin an PortB geschalten 
 } 
 waitMs(100); // Warte 100ms 
 } 
 while (true); 
} 
 
//------------------------------------------------------------------------ 
// twiInitMaster 
//------------------------------------------------------------------------ 
void twiInitMaster(uint8_t twiAdr) 
{ 
 // Clock 
 TWBR=((F_CPU/TWI_CLOCK)-16)*2; 
 // TWI-Status-Register (Vorteiler) 
 TWSR=0; 
 // Bus-Addr 
 // TWAR=twiAdr; 
 // Enable 
 TWCR=_TWINT|_TWEN; 
} 
//------------------------------------------------------------------------ 
// Start TWI (ohne Interrupt) 
//------------------------------------------------------------------------ 
void twiStart() 
{ 
 uint8_t x = TWCR; 
 x &= _TWEN|_TWIE; // nur Beibehalten von Enable und InterruptJ/N 
 TWCR = x|_TWINT|_TWSTA; 
 // warten bis fertig 
 while( !(TWCR & _TWINT)) 
 {} 
} 
//------------------------------------------------------------------------ 
// Stopp TWI (ohne Interrupt) 
//------------------------------------------------------------------------ 
void twiStop() 
{ 
 uint8_t x=TWCR; 
 x &= _TWEN|_TWIE; // nur Beibehalten von Enable und InterruptJ/N 
 TWCR = x|_TWINT|_TWSTO; 
} 
 
//------------------------------------------------------------------------ 
// Write Byte per TWI (ohne Interrupt) 
// PE: data = zu sendende Daten 
// ackn = wenn !=0 wird Acknowledge (=TWEA) gesetzt 
//------------------------------------------------------------------------

void twiWriteByte(uint8_t data, uint8_t ackn) 
{ 
 TWDR=data; // Daten bereitlegen 
 // Befehl zusammenstellen 
 uint8_t x=TWCR; 
 x&=_TWEN|_TWIE; // nur Beibehalten von Enable und InterruptJ/N 
 x|=_TWINT; 
 if(ackn) 
 x|=_TWEA; // evt. TWEA setzen, für Datenanforderung 
 TWCR=x; // senden 
 // warten bis fertig 
 while( !(TWCR & _TWINT)) 
 {} 
} 
//------------------------------------------------------------------------ 
// Read Byte per TWI (ohne Interrupt) 
// PE: ackn = wenn !=0 wird Acknowledge (=TWEA) gesetzt 
// PA: Data 
//------------------------------------------------------------------------ 
uint8_t twiReadByte(uint8_t ackn) 
{ 
 // Befehl zusammenstellen 
 uint8_t x=TWCR; 
 x&=_TWEN|_TWIE; // nur Beibehalten von Enable und InterruptJ/N 
 x|=_TWINT; 
 if(ackn) 
 x|=_TWEA; // evt. TWEA setzen, für Datenanforderung 
 TWCR=x; // senden 
 // warten bis fertig 
 while( !(TWCR & _TWINT)) 
 {} 
 return TWDR; 
} 
//----------------------------------------------------------------------- 
// Funktionen für Portexpander 
//------------------------------------------------------------------------ 
// twiInitPCA 
//------------------------------------------------------------------------ 
void twiInitPCA() 
{ 
 // I/O Definition (A Eingang, B Ausgang) 
 twiStart(); 
 twiWriteByte(0x40,0); // TWI-Adresse 
 twiWriteByte(0x06,0); // Adressierung des Kommandoregister = Config 0 
 twiWriteByte(0xFF,0); // ConfigDaten A = Ausgang 
 twiWriteByte(0x00,0); // ConfigDaten B = Ausgang 
 twiStop(); 
} 
//------------------------------------------------------------------------ 
// readPorts 
//------------------------------------------------------------------------ 
uint8_t readPorts(uint8_t port) 
{ 
 twiStart(); 
 twiWriteByte(0x40,1); // TWI-Adresse 
 twiWriteByte(port,1); // Kommandoregister 0/1 -> Input P0/P1 
 twiStart(); 
 twiWriteByte(0x41,1); // TWI-Adresse und Read 
 return twiReadByte(0); 
} 
//------------------------------------------------------------------------ 
// outPorts 
//------------------------------------------------------------------------ 
void outPorts(uint8_t port, uint8_t data) 
{ 
 twiStart(); 
 twiWriteByte(0x40,1); // TWI-Adresse 
 twiWriteByte(0x02+port,1); // Kommandoregister 2/3 -> Output P0/P1 
 twiWriteByte(data,0); // 
} 
//------------------------------------------------------------------------
 
Muss ich diesen kompletten Quelltext in meinen vorhandenen Einfügen, damit der Expander funktioniert oder reichen Teile davon?

Mit den MySeitePlatinchen kenne ich mich nicht aus, da kann ich leider nicht helfen. Vielleicht hat da jemand anderes ja eine Idee.

Wenn du den ganzen Code zu deinem Projekt hinzufügst, hast du zweimal main(). Das geht so nicht.
 
Den Teil mit der Zustandsabfrage müsste ich ja wahrscheinlich ungefähr so in der main-Schleife einfügen.
Nur dann wird die Kommunikation mit dem Expander wohl noch nicht funktionieren. Vielleicht hat da ja noch jemand eine Idee bzw. Erfahrungen, was ich dafür alles benötige :)

Code:
//------------------------------------------------------------------------ 
// main 
//------------------------------------------------------------------------ 
int main () 
    { 
     uint8_t data; 
     twiInitMaster(0x40); 
     twiInitPCA(); 
     do 
         { 
         data=readPorts(0); // Abfrage Pins an PortA 
         if(data == 0xFE) // Schaltkontakt geschlossen 
             { 
                 Eingaenge[11]='1'; 
             } 
             waitMs(100); // Warte 100ms 
         } 
}
 
Hi,

tja mit C kenne ich mich leider nicht aus :eek:

Oh Sorry, ich wusste doch das da was fehlt :D Ich verwende diesen Expander:
http://shop.myavr.de/index.php?sp=article.sp.php&artID=200000#

Habe jetzt auch das Datenblatt gefunden http://shop.myavr.de/index.php?ws=download_file.ws.php&dlid=163&filename=produkte/mytwi/techb_mytwi-portexpander_de_en.pdf, dort steht das Beispiel für eine Tasterabfrage. Muss ich diesen kompletten Quelltext in meinen vorhandenen Einfügen, damit der Expander funktioniert oder reichen Teile davon?

Nein das ist nicht das Datenblatt sondern nur ne Beschreibung von der Platine.
Das ist das Datenblatt ... Datenblatt PCA9555 rechts direkt neben dem Bild der Platine.

Dieses myAVRsonstwas ist so als wenn ich zu meiner Kaffemaschine mySchwarzeSuppeMaker sage :p
Warum nennen die diese Platine nicht einfach PCA9555-Evaluationboard oder ähnlich.
Warum muß man das immer mit so komischen Namen verdrehen :p :stupid: Na egal.
Wenn dann einer helfen will muß man den ganzen Krams erstmal wieder entschlüsseln.

Gruß
Dino
 
Wie schon gesagt: Mit den Datenblättern vom Expander (also dem IC), und dem vom Mega8 sollte (vielleicht noch mit etwas Wiki etc zum Thema TWI) ein ganz guter Überblick über den Bus zu bekommen sein. Im Mega-Datenblatt sind immer auch Code-Schnipsel in ASM und C drin.

Vielleicht solltest Du mal den User im mikrocontroller-Forum kontaktieren, der vor einem ähnlichen Problem zu stehen scheint...:p

Warum eigentlich den Expander?
Der Mega8 verfügt über 23 I/Os. Eine davon ist Reset, 2 werden möglicherweise für den Quarz (externer Takt) verwendet, ne volle serielle Anbindung an den PC via UART/RS232/USB wären nochmal 2 Pins. Bleiben 18 für Deine Taster/Schalter.

Wenn man den AVR mit internem Takt laufen läßt (kA, ob das mit dem Board geht), wäre sogar der komplette B-Port frei. Dann könnte man den als Eingang festlegen. die Schalter in'ner 2x8Matrix anordnen, und mit 2 weiteren I/Os (die zwischen tristate und pullup toggeln) die 2 Schalter-Spalten multiplexen. Müßte man sich mal sauber aufmalen, vielleicht werden da noch Dioden an den Schaltern fällig - hmm... LEDs vielleicht, dann aber mit externen Vorwiderständen statt der internen Pullups).

Was Sinn Deiner Hausaufgabe ist, mußt Du wissen - wir wissen nicht, welcher Stoff Dir zur Lösung Deines Problemes vermittelt worden ist. Wie also die Lösung eigentlich aussehen soll. Vielleicht halst Du Dir mit dem TWI (jetzt schon) viel zu viel auf.

Klar könnten wir (konkreter einer von den C-Profis hier) Dir 'ne fertige Lösung anbieten, aber das bringt Dich beim lernen auch nicht wirklich weiter, oder?
 
Fast geschafft...

Ich habe es nun tatsächlich geschafft, dass die Belegung von einzeln Betätigter Ports in LabView angezeigt wird. Jetzt habe ich aber noch ein Problem.

Wie hier dargestellt, frage ich im Moment die Ports ab. Nun werden aber ja nur die kompletten Bytes abgefragt, also funktioniert dies nicht, wenn ich jetzt ein Signal auf 2 Eingänge gleichzeitig anlege.
Wie kann ich denn in diesem Fall nur die Zustände einzelner Bits abfragen?

Code:
uint8_t data;
twiInitMaster(0x40);
twiInitPCA();
	data=readPorts(0); // Abfrage Pins an PortA
	if(data == 0xFE) // Taster gedrückt
	{
		Eingaenge[0]='1'; 	//Weitergabe an LabView	
	}
	
	if(data == 0xFD) // Taster gedrückt
	{
		Eingaenge[1]='1';       //Weitergabe an LabView
	}


Danke für die bisherige Hilfe, hat mir ein paar gute Denkanstöße gegeben :)
 
Hallo,
I

Danke für die bisherige Hilfe, hat mir ein paar gute Denkanstöße gegeben :)

möchtest du auf logisch low abfragen, dann kannst du das zum Beispiel so machen ...
Code:
#define BITPOS0 0
#define BITPOS1 1
// ...
if (!(data & (1<<BITPOS0)))
{
  // ...
}


Dirk :ciao:
 
Habe es nun so gemacht:

Code:
if((data & 0x04) == 0) // Taster gedrückt
	{
		Eingaenge[2]='1';
	}


Herzlichsten Dank, jetzt bin ich wunschlos glücklich ;)
 

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