Hallo
Eine Servoansteuerung mit dem PCF8574 habe ich auch noch nicht gesehen. Ich habe aber auch noch nicht danach gesucht. Das könnte aber grundsätzlich funktionieren.
Das Zittern könnte möglicherweise von der Sleep() /Watchdog()-Ansteuerung kommen. Hast du die Servos mal direkt an einem RP6-Ausgang angeschlossen und mit den selben Impulsen getestet?
Wenn man die Funktion I2CTWI_transmitByte() in der Datei RP6I2CmasterTWI.c betrachetet fallen gleich zu Beginn der Funktion zwei Hindernisse auf:
Code:
/*****************************************************************************/
// Transmission functions
/**
* Transmits a single byte to a slave device. It waits until the last
* TWI operation is finished (it blocks the normal program flow!) but
* it does NOT wait until this transmission is finished!
* This allows you to perform other things while the transmission is
* in progress!
*/
void I2CTWI_transmitByte(uint8_t targetAdr, uint8_t data)
{
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
I2CTWI_delay();
TWI_msgSize = 2;
I2CTWI_buf[0] = targetAdr;
I2CTWI_buf[1] = data;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
}
Da die letzte TWI-Übertragung mindestens vor servopos (0,5-2ms?) stattgefunden hat, würde ich diese Zeile erstmal ausblenden:
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
Ebenso sollte man dann wohl diese Zeile auskommentieren:
I2CTWI_delay();
Besser als Auskommentieren wäre vielleicht das:
Code:
while(true)
{
if(getStopwatch1() >= 20){ // Alle 20 ms Impuls senden
setStopwatch1(0);
TWI_msgSize = 2;
I2CTWI_buf[0] = PCF8574_Schreiben;
I2CTWI_buf[1] = 0b00001000;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
//task_I2CTWI();
sleep(grad); // Signaldauer
TWI_msgSize = 2;
I2CTWI_buf[0] = PCF8574_Schreiben;
I2CTWI_buf[1] = 0b00000000;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
//task_I2CTWI();
}
}
return 0;
(Ungetestet und nicht kompiliert)
Wenn das überhaupt nicht funktionieren sollte, fehlt vermutlich task_I2CTWI(); Das solltest du aber meiden, weil das Tasksystem unkontrollierbare Zeitverzögerungen erzeugt. Hier bliebe dann nur noch die direkte Ansteuerung der TWI-Funktionen des Mega32 ohne das Tasksystem des RP6.
Gruß
mic
Lesezeichen