Forum: Mikrocontroller und Digitale Elektronik SRF02 an einem AT89C51


von Max (Gast)


Lesenswert?

Tag allerseits,

ich habe ein scheinbar unlösbares Problem mit meinem SRF02 und bin 
mittlerweile einfach nur noch ratlos, ich hoffe mir kann hier noch einer 
weiter helfen.

Also, erstmal vorweg:
Ich habe ein Board mit einem AT89C51CC03 drauf, der funktioniert 
einwandfrei, auch seine Ports.
Des weiteren habe ich ein DogXL das an einem Port angeschlossen ist, das 
betreibe ich mittels selbst implementiertem I2C (ist ja nicht sonderlich 
schwer), dieses Display benutze ich um mir (zwischen)werte anzuschauen, 
also nicht wundern woher ich die habe.

Nun zu meinem Problem, ich habe mir 2 SRF02 bestellt um sie an besagtem 
Mikrocontroller zu betreiben, der Verwendungszweck für die 2 Sensoren 
sei mal so dahin gestellt.

Nach ein wenig rumprobieren, konnte ich die zwei Sensoren auch 
ansprechen und mit eigenen Adressen versehen. Soweit so gut. Als 
nächstes versuchte ich natürlich, wie zu erwarten war, Distanzen zu 
ermitteln.
Also einen Timer genommen, und ihn alle 100 ms Rangen lassen (Beide 
Sensoren abwechselnd damit sie sich nicht stören, falls das möglich 
ist).
Anschließend hab ich mir die Werte dann aus Register 2 und 3 geholt, und 
verrechnet (HighByte * 256 + LowByte).

Nun kommt das Problem, die Werte die ich zurück bekomme, sind zwar nicht 
willkürlich und auch reproduzierbar, aber nicht korrekt.
Ich habe die Sache natürlich gründlich untersucht, und auch zum Test mal 
die Software Revision aus Register 0 ausgelesen.

Was mir dabei nun auffiel, war das scheinbar das MSB tut was es will:
Ich habe eine Distanz von 150 cm gemesen, und auch diesen Wert bekommen, 
dann bin ich langsam mit dem Sensor näher an das Objekt herran und auch 
die Zahl ist linear und realistisch nach unten gesunken, bis zu 128, ab 
da macht die Zahl einen Sprung zu 255.
Meine Vermutung also: bei 128cm ist das MSB high, also passt es noch, 
bei 127 jedoch ist es Low und die nachfolgenden Bits alle High, wenn nun 
aber, obwohl das MSB Low sein sollte, umkippt, komm ich auf besagte 255.

Auch die Software Revision gibt mir 133 als Wert zurück, anstatt 5 wie 
man oft im Internet liest.
Wenn man mal kurz drüber nach denkt, ist es logisch: Denn wenn bei der 5 
das MSB kippt, bekomme ich 133 zurück.

Ich habe meinen Code mittlerweile immer und immer wieder auf Fehler 
untersucht / untersucht lassen, habe aber keinen Fehler gefunden, ich 
habe es mit den internen Pullups für SDA und SCK ausprobiert, mit 
externen (4,7k) an P0 (dieser hat ja keinen internen) und beides 
zusammen.
Ich habe sogar schon getestet ob ein stärkeres Stromkabel in der nähe 
bits um wirft, ich finde den Fehler einfach nicht, ich hab auch schon 
Stunden lang gegoogelt - erfolglos.

Es ist auch bei beiden SRF02 das selbe, und auch ein anderer 89C51 
bringt die selben Ergebnisse, defekte Hardware schließe ich hiermit 
eigentlich aus.

Wie dem auch sei, mehr weiß ich leider nicht mehr, und mit meinem Latein 
bin ich am Ende. :(

Nachfolgend ist noch mein C-Code der den SRF02 ansteuern soll.
Ich wäre sehr, sehr dankbar für jegliche Hilfe!

Mit freundlichen Grüßen, Max
1
 
2
 void I2C_SRF02_Connect(bit WR, byte Adress)
3
 {          
4
   byte adress = Adress; 
5
  SRF02_Clock = 1;
6
   SRF02_Data = 1;
7
   SRF02_Data = 0;
8
  SRF02_Clock = 0;
9
  if (WR)
10
    adress = (Adress | 0x01);
11
  I2C_SRF02_SendByte(adress);
12
 }
13
14
 void I2C_SRF02_Disconnect()
15
 {
16
  SRF02_Data = 0;
17
  SRF02_Clock = 1;
18
  SRF02_Data = 1;
19
 }
20
21
 void I2C_SRF02_SendByte(byte Value)
22
 {
23
   byte i;
24
  byte shifter = 0x80;
25
  for (i = 0; i < 8; i++)
26
  {           
27
    if ((Value & shifter) == 0)
28
      SRF02_Data = 0;
29
    else
30
      SRF02_Data = 1;
31
    SRF02_Clock = 1;
32
    SRF02_Clock = 0;
33
    shifter = (shifter >> 1);  
34
  }
35
  SRF02_Clock = 1;
36
  SRF02_Clock = 0; 
37
 }
38
39
 byte I2C_SRF02_ReadByte()
40
 { 
41
   byte i;
42
  byte value = 0x0;
43
  for (i = 0; i < 8; i++)
44
  {       
45
    value <<= 1;
46
    value |= SRF02_Data;
47
    SRF02_Clock = 1;
48
    SRF02_Clock = 0;
49
  }    
50
  SRF02_Clock = 1;
51
  SRF02_Clock = 0; 
52
  return value;
53
 }
54
55
 void SRF02_ChangeAdress(byte CurrentAdress, byte NewAdress)
56
 {
57
   I2C_SRF02_Connect(0, CurrentAdress);
58
  I2C_SRF02_SendByte(0);
59
  I2C_SRF02_SendByte(0xA0);
60
   I2C_SRF02_Connect(0, CurrentAdress);
61
  I2C_SRF02_SendByte(0);
62
  I2C_SRF02_SendByte(0xAA);  
63
   I2C_SRF02_Connect(0, CurrentAdress);
64
  I2C_SRF02_SendByte(0);
65
  I2C_SRF02_SendByte(0xA5);  
66
   I2C_SRF02_Connect(0, CurrentAdress);
67
  I2C_SRF02_SendByte(0);
68
  I2C_SRF02_SendByte(NewAdress);
69
  I2C_SRF02_Disconnect();   
70
 }
71
72
 void SRF02_StartRanging(byte Adress)
73
 {            
74
   I2C_SRF02_Connect(0, Adress);
75
  I2C_SRF02_SendByte(0x00);
76
  I2C_SRF02_SendByte(0x51);
77
  I2C_SRF02_Disconnect();
78
 }
79
80
 unsigned int SRF02_ReadRange(byte Adress)
81
 {    
82
   byte high = 0;
83
  byte low = 0;
84
   I2C_SRF02_Connect(0, Adress);
85
  I2C_SRF02_SendByte(3);
86
  I2C_SRF02_Connect(1, Adress);
87
  low = I2C_SRF02_ReadByte();
88
  I2C_SRF02_Connect(0, Adress);
89
  I2C_SRF02_SendByte(2);
90
  I2C_SRF02_Connect(1, Adress);
91
  high = I2C_SRF02_ReadByte();
92
  I2C_SRF02_Disconnect();    
93
  return (int)high * (int)256 + (int)low;
94
 }

von Stefan (Gast)


Lesenswert?

Hallo,

ich hab deinen Code mal kurz überflogen, und mich wundert dass das 
überhaupt funktioniert.

Du achtest zwar fein säuberlich auf die einzelnen Pegel (Clock /Data) 
aber von "Timing" seh ich weit und breit nichts !!!

An ein eventuelles "clock-stretching" hast du nicht mal ansatzweise 
gedacht.

> I2C (ist ja nicht sonderlich
> schwer)

Viele ????????????????????

von klaus (Gast)


Lesenswert?

Und was ist mit dem "ACK"-Bit, das gibts nicht ????

von Max Brand (Gast)


Lesenswert?

Ich geb zu es ist unsauber, aber Absicht.
Mein Display, für das ich die I2C Methoden programmiert habe kann mit 
bis zu 4 Mhz arbeiten, mein µC hat nur 1 Mhz, also sah ich min dazu nich 
gezwungen und der Code is minimal schneller.
Und das ack Bit, das ist immer der letzte clock in den Funktionen, hier 
is ebenfalls das selbe mit 4 und 1 Mhz.
Ich habe es dann bei den Sensoren einfach so übernommen und es ging. 
Also habe ich mich nicht weiter darum gekümmert.
Könnte das Problem darin liegen? Kanns mir irgendwie nicht ganz 
vorstellen um ehrlich zu sein

Mfg, Max

von R. W. (quakeman)


Lesenswert?

Du weisst schon, dass I2C Geräte nur mit Geschwindigkeiten von 
100kBit/s, 400kBit/s und 3,4MBit/s spezifiziert sind?

Also wenn im Datenblatt nicht explizit drin steht, welche Taktfrequenz 
du nehmen kannst, dann solltest du erst mal klein anfangen. Viele I2C 
Geräte sind heute noch bis maximal 400kBit/s spezifiziert.

In deinem Code verwendest du keinerlei Timing wodurch die tatsächliche 
Geschwindigkeit völlig undefiniert ist. Um deinen Fehler zu finden wäre 
es sinnvoll, den Sensor an einen Controller mit Hardware I2C 
Schnittstelle anzuschließen. Dann kannst du schnell rausfinden, ob deine 
Software-I2C Version das Problem ist oder nicht.

Alternativ kannst du mal auf der Seite www.c51.de unter [1] den Link 
"Buch_PraxisTeil2_Kap11.ZIP" herunterladen. Dort ist ebenfalls eine 
Software-I2C Implementierung für 8051er enthalten. Diese ist aber weit 
aus ausgereifter als deine Version.

Ciao,
     Rainer

[1] http://www.c51.de/c51.de/Dateien/c51_buecher.php

von Max (Gast)


Lesenswert?

Okay danke erstmal, wie gesagt, ich ging davon dass es geht und es ging 
ja scheinbar auch, ich werd mich um die Timings kümmern und hoffen dass 
es dann funktioniert :/

Das mit dem Ack-Bit hab ich mittlerweile schon ausgebessert, darauf wird 
nun gewartet.

Mfg, Max

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.