Forum: Mikrocontroller und Digitale Elektronik I2C_Routine für SD21


von Dominik (Gast)


Lesenswert?

hallo, hätte eine frage zu einem simplen i2c programm.

hab mir ein SD21 Servocontroller bestellt 
(www.robotikhardware.de/download/sd21.pdf)
den man über I2C ansteuert.

habe einen P89LPC936 für die Programmierung.

vorerst sieht meine Routine so aus:
1
void  i2c_init()
2
{
3
  //SDA und SCL auf Open Drain => beide auf 1
4
  //SCL P1.2
5
  //SDA P1.3
6
7
  P1M1 |= 0x0C;
8
  P1M2 |= 0x0C;
9
10
     //Takt erzeugen von internem SCL Generator
11
  //Reloadwert setzen
12
  
13
  I2SCLH = 5;
14
  I2SCLL = 5;
15
  //369 kBit/s
16
17
  //I2C Hardware aktivieren (STOP, STA, SI = 0)
18
  I2CON = 0x44;
19
  //I2C Interrupt freigeben
20
  //EI2C = 1;
21
  //EA = 1;
22
  
23
  //Slave Adresse setzen
24
  SlaveAdr = 0xC2; //Adresse des SD21 Servo Controllers      
25
}
1
void write_byte_I2C(unsigned char data_out1, unsigned char data_out2)
2
{
3
  STA = 1;  //Startbedingung setzen
4
5
  while(!SI); //warten bis Startbedingung gesendet wurde
6
7
  //Nun auf richtige Rückmeldung abfragen
8
  if(I2STAT == 0x08) //1. Status: "START transmitted"
9
  {      
10
    I2DAT = SlaveAdr;
11
    I2CON = 0x44;  //STO, STA, SI = 0, ACK = 1)
12
  }
13
14
  //Nachdem das Startbit gesendet wurde, wird jetzt
15
  //der Write-Befehl an den Slave gesendet, damit
16
  //der Bus vom Master beschrieben werden kann
17
  while(!SI);
18
  if(I2STAT == 0x18)  //2. Status: "SLA+W transmitted; ACK received"
19
  {
20
    I2DAT = data_out1; //Datenbyte senden. Unser uC verschiebt das Byte automatisch
21
    I2CON = 0x44;  //STO, STA, SI = 0, ACK = 1) 
22
    //I2CStatus = ACK_RECEIVED;
23
  }
24
25
  while(!SI);
26
  if(I2STAT == 0x28)  //3. Status: Databyte transmitted; ACK received"
27
  {
28
    I2DAT = data_out2; //Datenbyte senden. Unser uC verschiebt das Byte automatisch
29
    I2CON = 0x44;  //STO, STA, SI = 0, ACK = 1) 
30
    //I2CStatus = ACK_RECEIVED;
31
  }
32
  
33
  //Nachdem das Datenbyte gesendet wurde, müssen wir
34
  //wieder den Bus freigeben anhand einer Stopbedingung
35
  while(!SI);
36
  if(I2STAT == 0x28)  //3. Status: "Datenbyte received; ACK received"  
37
  {
38
    I2CON = 0x54; //Stopbedingung senden / Bus freigeben / SI = 0;    
39
  }
40
}

wollte nun fragen, ob das so stimmen kann?
hab mal ein testprogramm geschrieben
1
void Interrupt_Button (void) interrupt 2
2
{
3
  int i;
4
5
    set_speed_I2C(1,100); //set servo 1, speed 100% 
6
    set_position_I2C(1,1500); //set servo 1, nullstellung
7
8
    set_speed_I2C(3,50);
9
    set_position_I2C(3,1500);
10
11
    set_position_I2C(1,1000); //set servo 1, nullstellung
12
    set_position_I2C(3,2000);
13
}

kann das so funktionieren?

1) ich muss eh nichts extra anbringen für den sd21 (extern pullup oder 
so beim bus), also ich hab jedenfalls nichts gesehen im datenblatt ?!

2) ich hab schon versucht das programm zu simulieren mit Keil uVision4, 
nur da passt irgendetwas nicht und der Slave gibt mir immer ein "Not 
Acknowledge" (is aber auch logisch, denn müsste irgendwie manuell den 
Slave simulieren).
Ich weiß, dass ich TROTZDEM senden kann, obwohl kein Acknowledge bit 
herkommt, aber funktioniert das auch?


Stimmt meine Denkweise? oder ist daran etwas falsch? Ab nächster Woche 
werd ich den SD21 bekommen und dann kann ich das mal genauer austesten

Danke im Voraus!!!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.