PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : peter fleury i2c lib, TRINAMIC TMC222 ansteuerung [gelöst]



Christoph2
21.02.2009, 14:22
Hallo!

Ich will den Schrittmotor Controller TMC222 per I2C ansteuern.

Dazu muss ich laut datenblatt erstmal das Kommando GetFullStatus senden, dann sendet er mir seinen status zurück. außerdem wird er dadurch aktiviert.

Also schreibe ich...


i2c_start_wait(stepperadresse +I2C_WRITE); // startsignal senden, usw...
i2c_write(GetFullStatus1); // GetFullStatus1 senden
i2c_stop();
Definitionen im headerfile:
// I2C Adresse:

#define stepperadresse 0b11000010

// Befehle:

#define GetFullStatus1 0x81 // Returns complete status of the chip
#define GetFullStatus2 0xFC // Returns actual, target and secure position
#define GetOTPParam 0x82 // Returns OTP parameter
#define GotoSecurePosition 0x84 // Drives motor to secure position
#define HardStop 0x85 // Immediate full stop
#define ResetPosition 0x86 // Sets actual position to zero
#define ResetToDefault 0x87 // Overwrites the chip RAM with OTP contents
#define RunInit 0x88 // Reference Search
#define SetMotorParam 0x89 // Sets motor parameter
#define SetOTP 0x90 // Zaps the OTP memory
#define SetPosition 0x8B // Programmers a target and secure position
#define SoftStop 0x8F // Motor stopping with deceleration phase

Wie lese ich jetzt das ein, was er mir zurückschickt?
Muss ich mich auch um die ACKs kümmern?

Bei der peter fleury lib ist zwar auch ein anwendungsbeispiel drinnen, aber das ist nur mit einem eeprom, der von selbst nichts schickt.
Den muss man mit dem read befehl auslesen, nachdem man die Adresse reingeschrieben hat.
Aber wie mache ich das wenn ich nichts auslesen muss sondern wenn der das selber sendet?


Das Programmbeispiel mit dem eeprom schaut so aus:

#include <i2cmaster.h>


#define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet

int main(void)
{
unsigned char ret;

i2c_init(); // initialize I2C library

// write 0x75 to EEPROM address 5 (Byte Write)
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x05); // write address = 5
i2c_write(0x75); // write value 0x75 to EEPROM
i2c_stop(); // set stop conditon = release bus


// read previously written value back from EEPROM address 5
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode

i2c_write(0x05); // write address = 5
i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode

ret = i2c_readNak(); // read one byte from EEPROM
i2c_stop();

for(;;);
}


lg christoph


EDIT: Mein avr geht glaube ich in eine endlosschleife, wenn er i2c_start_wait(stepperadresse +I2C_WRITE); ausführt.
er wartet nämlich auf ein ack aber bekommt keins, weil irgendwas nicht funktioniert. ich habe auch schon i2c_start (ohne _wait) probiert, aber das funktinoiert auch nicht...

Christoph2
21.02.2009, 21:08
hi!

Mein erster Fehler war, dass ich eine slave-adresse mit 8 bit eingegeben habe, anstatt mit 7 bit.

Jetzt habe ich folgendes Programm geschrieben:


if(PINA & (1<<7)) // Wenn Taster gedrückt...
{ _delay_ms(50); // entprellen
PORTA|=(1<<2); // LED ein


i2c_start(stepperadresse + I2C_WRITE); // Auf die adresse des steppermotors schreiben


i2c_write(GetFullStatus1); // Befehl GetFullStatus senden

i2c_rep_start(stepperadresse + I2C_READ); // Lesemodus
fs1b0=i2c_readAck(); // Die sieben bit die der TMC222
fs1b1=i2c_readAck(); // zurückschickt, abspeichern
fs1b2=i2c_readAck();
fs1b3=i2c_readAck();
fs1b4=i2c_readAck();
fs1b5=i2c_readAck();
fs1b6=i2c_readAck();
fs1b7=i2c_readAck();
fs1b8=i2c_readNak();

i2c_stop(); // i2c-übertragung beenden

_delay_ms(1000); // 1 Sekkunde warten
}


else
{ PORTA|=(1<<2); // LED aus
}

wenn ich den Taster drücke, leuchtet die led, und sie geht NICHT MEHR aus wenn ich den Taster loslasse. der AVR ist also in einer endlosschleife.

also habe ich es mit einer etwas kürzeren variante probiert, um das problem einzugrenzen:


if(PINA & (1<<7)) // Wenn Taster gedrückt...
{ _delay_ms(50); // entprellen
PORTA|=(1<<2); // LED ein


i2c_start(stepperadresse + I2C_WRITE); // Auf die adresse des steppermotors schreiben
i2c_stop(); // i2c-übertragung beenden

_delay_ms(1000); // 1 Sekkunde warten
}


else
{ PORTA|=(1<<2); // LED aus
}

Dieses Programm funktioniert. wenn ich den taster drücke, leuchtet die led, und erlischt automatisch nach 1 sekunde (wegen _delay_ms(1000)).

Das Problem liegt also am Senden des GetFullStatus - Befehles.

Weiß jemand woran das liegen könnte?

lg christoph


EDIT: ok ich habs gelöst. der Motorcontroller hat nicht auf die slave adresse reagiert, ka warum...
jetzt hab ich die broadcastadresse 0b0000000 verwendet, mit der funktioniert er!