Technik > Tech-Talk Design & Konzepte
Entwicklung eines Midi-Switching-Systems auf Arduino-Basis
Dirk:
und ganz vergessen: versuch mal Hans direkt zu kontaktieren. Der macht einiges mit den µC und kann vielleicht etwas dazu sagen - falls er nicht hier mit liest.
Gruß, Dirk
PS: da fällt mir noch ein konntest Du das Dumpen der Bank/Preset-Daten vom und zum µC realisieren ?
Nils H.:
--- Zitat von: Dirk am 3.01.2014 23:21 ---Du programmierst in C ?
Stelle doch mal das Programm hier ein.
--- Ende Zitat ---
Kein Problem. Ist überschaubar ;D . Ich denke, an der markierten Stelle ("HIER HÄNGT'S") entstehen die 2 sekunden, hab's aber noch nicht genauer ausgeforscht. Mache ich aber noch. Mein Verdacht ist wie gesagt, dass der µC auf die erste Antwort des ersten Expanders wartet. Danach läuft alles wie Atze, will sagen: Für menschliche Wahrnehmung gehen dann alle Relais und LEDs gleichzeigig aus ;D .
main.c:
--- Code: ---
#include "i2c.h" // Routinen für I²C-Bus einbinden
int main( void )
{
i2c_init(); // I2C-Bus initialisieren
return 0;
}
--- Ende Code ---
i2c.c:
--- Code: ---void i2c_init (void)
{
/* Bus Geschwindigkeit einstellen
* Formel: F_CPU/(16+2*TWBR*Prescaler)
* Prescaler Default: 1
* TWBR = 0x48 = 73 ergibt 100 kHz bei 16 MHz CPU-Frequenz
*/
TWSR=(0<<TWPS1)|(0<<TWPS0);
TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
// Port Expander initialisieren
// ***** HIER HÄNGT'S? ***** //
PCF8574_set_outputs(0,0x00);
PCF8574_set_outputs(1,0x00);
PCF8574_set_outputs(2,0x00);
}
/*
* START senden, Adresse senden, RW senden
* Rückgabewert: 1 = gescheitert, 0 = ok
*/
uint8_t i2c_start (uint8_t typ, uint8_t adresse, uint8_t rw)
{
uint8_t twst;
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // START Condition senden
while (!(TWCR & (1<<TWINT)));
twst = TW_STATUS & 0xF8; // Statusregister überprüfen
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1; // Slave reagiert nicht
uint8_t adressByte = 0;
adressByte = adresse << 1;
adressByte |= rw; // R/W-Bit setzen
/* Basisadresse ergänzen
*
* PCF8574A: 0 1 1 1 A2 A1 A0 RW = 0x70
* EEPROM: 1 0 1 0 A2 A1 A0 RW = 0xA0
*
*/
switch (typ)
{
case IOEXPANDER:
{
adressByte |= 0x70;
break;
}
case EEPROM:
{
adressByte |= 0xA0;
break;
}
}
// Slave-Adresse senden
TWDR =adressByte; // Slave-Adresse senden
TWCR = (1<<TWINT) | (1<<TWEN);
// warten bis Übertragung beendet
while(!(TWCR & (1<<TWINT)));
// Statusregister überprüfen
twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
return 0;
}
/*
* START senden, Adresse senden, RW senden
* Wenn Slave beschäftigt, warten bis frei
*/
void i2c_start_wait( uint8_t typ, uint8_t adresse, uint8_t rw)
{
uint8_t twst;
while ( 1 )
{
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // START Condition senden
while(!(TWCR & (1<<TWINT))); // warten bis Übertragung beendet
twst = TW_STATUS & 0xF8; // Statusregister prüfen
if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
uint8_t adressByte = 0;
adressByte = adresse << 1;
adressByte |= rw; // R/W-Bit setzen
/* Basisadresse ergänzen
*
* PCF8574A: 0 1 1 1 A2 A1 A0 RW = 0x70
* EEPROM: 1 0 1 0 A2 A1 A0 RW = 0xA0
*
*/
switch (typ)
{
case IOEXPANDER:
{
adressByte |= 0x70;
break;
}
case EEPROM:
{
adressByte |= 0xA0;
break;
}
}
// Slave-Adresse senden
TWDR =adressByte;
TWCR = (1<<TWINT) | (1<<TWEN);
// warten bis Übertragung beendet
while(!(TWCR & (1<<TWINT)));
// Statusregister überprüfen
twst = TW_STATUS & 0xF8;
if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) ) // Slave beschäftigt, STOP senden
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
while(TWCR & (1<<TWSTO)); // warten bis Bus frei
continue;
}
break;
}
}
/*
* STOP senden
*/
void i2c_send_stop (void)
{
/*
* STOP Condition senden:
*
* TWINT durch setzen von 1 löschen
* TWSTA = TWI STOP Condition Bit
* TWEN = TWI Enable Bit
*
*/
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
while(!(TWCR & (1<<TWSTO))); // warten bis STOP gesendet
}
/*
* Datenbyte senden
* Rückgabewert: 1 = gescheitert, 0 = Byte übertragen
*/
uint8_t i2c_send_byte (uint8_t byte)
{
uint8_t twst;
TWDR = byte; // Datenbyte in TWI Datenregister schreiben
TWCR = (1<<TWINT) | (1<<TWEN); // Inhalt des Datenregisters senden
while (!(TWCR & (1<<TWINT))); // warten bis gesendet
twst = TW_STATUS & 0xF8; // Statusregister prüfen
if( twst != TW_MT_DATA_ACK) return 1;
return 0;
}
void PCF8574_set_outputs (uint8_t adresse, uint8_t byte)
{
i2c_start(IOEXPANDER,adresse,0);
i2c_send_byte (byte);
i2c_send_stop ();
}
--- Ende Code ---
Thisamplifierisloud:
Hossa,
warte mal 200-300ms, bevor Du den I2C-Bus und den PCF8574 initialisiert.
Der PCF8574 ist manchmal etwas ... störrisch.
Grüßle
Bernhard
Nils H.:
--- Zitat von: Dirk am 3.01.2014 23:23 ---und ganz vergessen: versuch mal Hans direkt zu kontaktieren. Der macht einiges mit den µC und kann vielleicht etwas dazu sagen - falls er nicht hier mit liest.
Gruß, Dirk
PS: da fällt mir noch ein konntest Du das Dumpen der Bank/Preset-Daten vom und zum µC realisieren ?
--- Ende Zitat ---
Wenn mir das richtig Sorge bereitet, mache ich das. Das prinzipielle Problem bleibt, die Expander sind nach demStartup High und somit schalten die ULN2803 durch, was die Relais anziehen lässt. Auch für 'ne halbe, viertel Sekunde oder weniger ist das doof, deswegen löte ich gerade eine kleine Einschaltverzügerung für die Relaisspannung zusammen.
Mit dem Thema EEPROM-Dumping hab ich mich beim Controller erst mal noch nicht weiter beschäftigt. Der grobe Fahrplan scheint zu sein, das mit geeigneter Software (MIDIOX oder selbst geschrieben) per Sysex zu machen. Umgesetzt habe ich da aber noch nix.
Nils H.:
--- Zitat von: Thisamplifierisloud am 3.01.2014 23:33 ---Hossa,
warte mal 200-300ms, bevor Du den I2C-Bus und den PCF8574 initialisiert.
Der PCF8574 ist manchmal etwas ... störrisch.
Grüßle
Bernhard
--- Ende Zitat ---
Danke für den Hinweis. Das Grundproblem bleibt aber, die sind nach dem Einschalten erst mal High. Ob das dann 300ms oder 2s dauert ist latte, ich darf die Relaisspannung erst nach dem initialisieren freischalten.
Navigation
[0] Themen-Index
[#] Nächste Seite
[*] Vorherige Sete
Zur normalen Ansicht wechseln