Wie man den CY8C9540A mittels I2C hacken kann, um die Frequenzen und Tastgrade auf dem Intel Galileo-Mainboard zu verändern

Dieser Beitrag ist zwar kurz und einfach, aber ich entschied mich dennoch, ihn zu schreiben, da er meiner Meinung nach für einige Entwickler nützlich sein wird.
Das Intel Galileo-Mainboard hat einen GPIO-Expander namens CY8C9540A, der im 5-V-Bereich arbeitet und für die PWM verantwortlich ist. 

Wenn Sie sich die Servo-Bibliotheks-API anschauen, werden Sie feststellen, dass die implementierten Methoden mit denen für Atmel-Mikrocontroller übereinstimmen; allerdings haben wir zwei Methoden hinzugefügt, mit denen wir beim Servoantrieb zwischen 48 Hz und 188 Hz wählen können.

Wie setzt die Servo-Bibliothek dies um? Der Servoantrieb kommunizierte mittels I2C mit dem CY8C9540A. Die I2C-Kommunikation kann über die Wire API erfolgen.

Wenn Sie einen Blick in das CY8C9540A-Datenblatt werfen, werden Sie feststellen, dass sich die Frequenz mittels 0x2C und der Tastgrad über das Register 0x2B verändern lässt. Die CY8C9540A-Adresse im I2C-Bus lautet 0×20.

Diese Methode ist unglaublich einfach. Sie können mit analogWrite() den Port für die PWM wählen und anschließend die Befehle an den CY8C9540A senden, um die gewünschten Einstellungen für die Frequenz und den Tastgrad festzulegen.

Der Code ist überaus simpel. Werfen Sie einen Blick in die prepare_pin()-Methode unserer Servo-Bibliothek unten:

	void Servo::prepare_pin(uint8_t pin)
{
 
 extern TwoWire Wire;
 
Wire.begin();
 
// Diese Funktion wird nur für die Auswahl des Bit-Ports verwendet.
// Das Datenblatt ist in diesem Punkt etwas verwirrend.
 
analogWrite(pin, 1);
 
// Programmierbare PWM-CLK-Quelle mit 367,7 Hz wählen
 Wire.beginTransmission(CYPRESS_I2C_ADDRESS);
 Wire.write(0x29);
 Wire.write(0x04);
 Wire.endTransmission();
 
 // Register – steigende Flanke
 Wire.beginTransmission(CYPRESS_I2C_ADDRESS);
 Wire.write(0x2a);
 Wire.write(0xff);
 Wire.endTransmission();
 
 // Grenzwert für Frequenz 47,4 Hz festlegen
 Wire.beginTransmission(CYPRESS_I2C_ADDRESS);
 Wire.write(0x2C);
 
if (this->is188hz)
 Wire.write(0x02);   //188hz
 else
 Wire.write(0x09);   //47hz
 
Wire.endTransmission();
 
}
 
byte Servo::transform_cypress_duty_cycle_byte(int microsecs)
{
 
 /* Der Maximalgrenzwert für 23 ms (100 % Tastgrad) beträgt
 255 Einheiten (Bytes 0 bis 255 gemäß Registern 0x2B).
 
 Für 2 ms liegt der Wert der Maximaleinheiten daher bei 22,17.
 
Das Prinzip wird für 188 Hz verwendet, was
 einer Zeitspanne von 5,319 ms entspricht.
 
Daher gilt für die maximale Anzahl verfügbarer Bytes für unterschiedliche Frequenzen
der Maximalzeitspanne von 2 ms oder 2,4 ms bei einer 8-bit-Auflösung die folgende
Formel:
 
= max_duty/1000 * (1/freq)/255
 = max_duty*255/(1000/freq)
 
 */
 
 int freq = (this->is188hz) ? 188:43.4;
 int max_byte = MAX_PULSE_WIDTH*255*freq/1000000L;
 
if(this->min=1000) Serial.println(max_byte);
 
byte b_duty = map(microsecs, 0, MAX_PULSE_WIDTH, 0, max_byte);
 
 return b_duty;
}
void Servo::writeMicroseconds(int microsecs)
{
 
 int byteDuty = transform_cypress_duty_cycle_byte(microsecs);
 
if (this->lastByteInDuty == byteDuty)
 return;
 
this->lastByteInDuty = byteDuty;
 
 prepare_pin(this->pin);
 
// Grenzwerte überprüfen
 if (microsecs < this->min) microsecs = this->min;
 if (microsecs > this->max) microsecs = this->max;
 
// Tastgrad festlegen
 Wire.beginTransmission(CYPRESS_I2C_ADDRESS);
 Wire.write(0x2b);
 Wire.write(byteDuty);
 Wire.endTransmission();
 
// Aktualisierung zuletzt verstrichener Mikrosekunden
 this->usecs = microsecs;
 
}

Basierend auf dem Code oben und dem Datenblatt können Sie den Cypress hacken und die Frequenz und den Tastgrad nach Bedarf festlegen. Denken Sie daran: CYPRESS_I2C_ADDRESS lautet 0×20.

Dieser Beitrag ist eine Übersetzung des Artikels How to “hack” CY8C9540A using I2C to set different freqs and duty cycles on Intel Galileo Board, der zuerst auf der privaten Webseite des Intel Mitarbeiters Manoel  Ramon veröffentlicht wurde: http://bytesthink.com/blog/?p=277

Einzelheiten zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.