Forum: Mikrocontroller und Digitale Elektronik I2C und Bascom


von Norbert S. (norberts)


Lesenswert?

Hi,

ich habe hier einen ATMega8, 16MHz Resonator, programmiert mit bewährtem 
Script für AVR-Dude.
LED, serielle Verbindung über Max202 an PC, alles funzt.
Nun will ich mit einem Gyro per I2C sprechen und mein erster Gehversuch 
mit I2C geht voll daneben.
Der Gyro ist ein Modul MinIMU-9 (L3G4200D and LSM303DLH Carrier) von 
Pololu.

Im Programm ist sonst kein Timer oder Interrupt aktiv.

Es geht alles bis in die Gosub write_byte, "i2c start" wird noch 
gesendet und dann ist schluss. Die LED bleibt an und "slaveadr" kommt 
nicht.
Klemme ich den Gyro ab (also SCL und SDA offen am Mega8) läuft es durch.
Was zum Teufel kann man da so dermassen falsch machen?
Ich mein, von mir aus stimmt was mit der Adresse nicht aber daß der 
Mega8 dann dort hängenbleibt?
1
$regfile = "M8DEF.DAT"
2
3
$hwstack = 200
4
$swstack = 32
5
$framesize = 64
6
7
$lib "i2c.lib"
8
9
$crystal = 16000000
10
11
Config Scl = Portb.4                                        'AtMega8 PDip Pin27
12
Config Sda = Portb.5                                        'AtMega8 PDip Pin28
13
I2cinit
14
15
$baud = 19200                                               'RX Pin2, TX Pin3
16
17
Ddrb.0 = 1
18
Led Alias Portb.0
19
20
Const Ctrl_reg1 = &H20
21
Const Ctrl_reg4 = &H23
22
Const Gyroadress = &HD2                                     'Gyro slave adress for write
23
24
Dim Slaveadress As Byte                                     'Adress of the slave to read or write
25
Dim Subadress As Byte                                       'the register to read or write
26
Dim Databyte As Byte                                        'Byte to read or write
27
28
'###############################################
29
Print "Gyro-test"
30
Led = 1
31
Wait 1
32
Led = 0
33
34
Waitms 100
35
Gosub Init_gyro
36
37
End
38
39
Init_gyro:
40
   Print "init-G-start"
41
   Slaveadress = Gyroadress
42
   Subadress = Ctrl_reg1
43
   Databyte = &B10001111                                    'Enable all, ODR 400kHz, LPF1 cut off 78Hz
44
   Gosub Write_byte
45
   Print "init-G-first"
46
   Slaveadress = Gyroadress
47
   Subadress = Ctrl_reg4
48
   Databyte = &B10000000                                    'Block Data Update, LSB low, Scale 250 dps
49
   Gosub Write_byte
50
   Print "init-G-finish"
51
Return
52
53
Write_byte:
54
   Print "start write"                                      'needs Slaveadress, Subadress and Databyte
55
   Led = 1
56
   Shift Slaveadress , Left                                 '8-Bit with LSB = 0, write
57
   I2cstart
58
   Print "i2c start"
59
   I2cwbyte Slaveadress
60
   Led = 0
61
   Print "slaveadr"
62
   I2cwbyte Subadress
63
    Print "subadr"
64
   I2cwbyte Databyte
65
   I2cstop
66
Return

Für sachdienliche Hinweise wäre ich dankbar.

Gruß,
Norbert

von Norbert S. (norberts)


Lesenswert?

Hi,

also was ich oben schrieb:
"Klemme ich den Gyro ab (also SCL und SDA offen am Mega8) läuft es 
durch."
kann ich jetzt nicht mehr reproduzieren.

Doch ein Hardwareproblem?

Gruß,
Norbert

von MWS (Gast)


Lesenswert?

Norbert S. schrieb:
> Config Scl = Portb.4                                        'AtMega8 PDip Pin27
> Config Sda = Portb.5                                        'AtMega8 PDip Pin28

Da kollidiert die Beschreibung mit der Realität. An Pin 27/28 liegt 
PC4/5 und die HW-I2C Schnittstelle. PB4/5 geht für SW-I2C, auch die 
eingebundene Lib deutet darauf hin. Über Config I2CDelay sollte dann die 
Geschwindigkeit der Soft-I2C eingestellt werden. Es müssen externe 
Pullup-Widerstände dran, Soft-I2C geht nicht mit den internen Pullups 
des µCs.

von Norbert S. (norberts)


Lesenswert?

Hi,

yeah, das wars! Danke!
Daß der Mega8 sich dann aufhängt finde ich zwar immer noch komisch aber 
nun rennt es.
Naja, fast.
Die Daten sind Müll aber da habe ich sicher noch irgendwas mit den 
Adressen falsch.

Gruß,
Norbert

von Manfred S. (Firma: Manfred) (xfred343)


Lesenswert?

Hallo,

wieso nutzt du nicht einfach die Bibliothek für die Steuerung der 
Hardware-I2C von Bascom, einfach einbinden mit:

$lib "i2c_twi.lbx"

von Christian (Gast)


Lesenswert?

Hallo

ich bin in Sachen I2C Anfänger...
Wie kann ich die Daten die mir der Gyro und Beschleunigungssensor 
liefert an die Serielle Ausgeben?


Danke!

von Norbert S. (norberts)


Lesenswert?

Hi,

ich bin angeschrieben worden ob ich den Code zum Lesen der Sensoren 
rausrücken würde - hier ist er:
1
'##### 7- Bit Adresses Gyro ########
2
Const Who_am_i = &H0F
3
Const Ctrl_reg1 = &H20
4
Const Ctrl_reg2 = &H21
5
Const Ctrl_reg3 = &H22
6
Const Ctrl_reg4 = &H23
7
Const Ctrl_reg5 = &H24
8
Const Out_temp = &H26
9
Const Status_reg = &H27
10
Const Out_x_l = &H28
11
Const Out_x_h = &H29
12
Const Out_y_l = &H2A
13
Const Out_y_h = &H2B
14
Const Out_z_l = &H2C
15
Const Out_z_h = &H2D
16
'##### 7-Bit Adresses Acc ########
17
Const Ctrl_reg1_a = &H20
18
Const Ctrl_reg2_a = &H21
19
Const Ctrl_reg3_a = &H22
20
Const Ctrl_reg4_a = &H23
21
Const Ctrl_reg5_a = &H24
22
Const Status_reg_a = &H27
23
Const Out_x_l_a = &H28
24
Const Out_x_h_a = &H29
25
Const Out_y_l_a = &H2A
26
Const Out_y_h_a = &H2B
27
Const Out_z_l_a = &H2C
28
Const Out_z_h_a = &H2D
29
'##### 7-Bit Adresses Mag ########
30
Const Cra_reg_m = &H00
31
Const Crb_reg_m = &H01
32
Const Mr_reg_m = &H02
33
Const Out_x_h_m = &H03
34
35
Const Gyroadress = &HD2                                     'Gyro slave adress for write
36
Const Accadress = &H30                                      'Acc slave adress for write
37
Const Magadress = &H3C                                      'Mag slave adress for write
38
39
Get_g_a_data:
40
   Slaveadress = Gyroadress
41
   Subadress = Out_x_l
42
   Gosub Read_6
43
44
   Xgyro = Dataarray(2)
45
   Shift Xgyro , Left , 8
46
   Xgyro = Xgyro + Dataarray(1)
47
48
   Ygyro = Dataarray(4)
49
   Shift Ygyro , Left , 8
50
   Ygyro = Ygyro + Dataarray(3)
51
52
   Zgyro = Dataarray(6)
53
   Shift Zgyro , Left , 8
54
   Zgyro = Zgyro + Dataarray(5)
55
56
   Slaveadress = Accadress
57
   Subadress = Out_x_l_a
58
   Gosub Read_6
59
60
   Xacc = Dataarray(2)
61
   Shift Xacc , Left , 8
62
   Xacc = Xacc + Dataarray(1)
63
64
   Yacc = Dataarray(4)
65
   Shift Yacc , Left , 8
66
   Yacc = Yacc + Dataarray(3)
67
68
   Zacc = Dataarray(6)
69
   Shift Zacc , Left , 8
70
   Zacc = Zacc + Dataarray(5)
71
72
   Xgyro = Xgyro - Xgyrooff
73
   Ygyro = Ygyro - Ygyrooff
74
   Zgyro = Zgyro - Zgyrooff
75
   Xacc = Xacc - Xaccoff
76
   Yacc = Yacc - Yaccoff
77
   Zacc = Zacc - Zaccoff
78
Return
79
80
Get_mag_data:
81
   Slaveadress = Magadress
82
   Subadress = Out_x_h_m
83
   Gosub Read_6_mag
84
85
   Xmag = Dataarray(1)
86
   Shift Xmag , Left , 8
87
   Xmag = Xmag + Dataarray(2)
88
89
   Ymag = Dataarray(3)
90
   Shift Ymag , Left , 8
91
   Ymag = Ymag + Dataarray(4)
92
93
   Zmag = Dataarray(5)
94
   Shift Zmag , Left , 8
95
   Zmag = Zmag + Dataarray(6)
96
97
   Xmag = Xmag - Xmagoff
98
   Ymag = Ymag - Ymagoff
99
Return
100
101
Init_gyro:
102
   Slaveadress = Gyroadress
103
   Subadress = Ctrl_reg1
104
   Databyte = &B10001111                                    'Enable all, ODR 400kHz, LPF1 cut off 78Hz
105
   Gosub Write_byte
106
107
   Slaveadress = Gyroadress
108
   Subadress = Ctrl_reg4
109
   Databyte = &B10000000                                    'Block Data Update, LSB low, Scale 250 dps
110
   Gosub Write_byte
111
Return
112
113
Init_acc:
114
   Slaveadress = Accadress
115
   Subadress = Ctrl_reg1_a
116
   Databyte = &B00101111                                    'normal power, 100Hz, 74Hz LPF
117
   Gosub Write_byte
118
119
   Slaveadress = Accadress
120
   Subadress = Ctrl_reg4_a
121
   Databyte = &B10000000                                    'Block Data Update, LSB low, Scale +-2g
122
   Gosub Write_byte
123
Return
124
125
Init_mag:
126
   Slaveadress = Magadress
127
   Subadress = Cra_reg_m
128
   Databyte = &B00011000                                    '75Hz Output
129
   Gosub Write_byte
130
131
   Slaveadress = Magadress
132
   Subadress = Crb_reg_m
133
   Databyte = &B01000000                                    'range +-1.9Gauss
134
   Gosub Write_byte
135
136
   Slaveadress = Magadress
137
   Subadress = Mr_reg_m
138
   Databyte = &B00000000                                    'continious mode
139
   Gosub Write_byte
140
Return
141
142
Write_byte:                                                 'needs Slaveadress, Subadress and Databyte
143
   I2cstart
144
   I2cwbyte Slaveadress
145
   I2cwbyte Subadress
146
   I2cwbyte Databyte
147
   I2cstop
148
Return
149
150
Read_byte:                                                  'needs Slaveadress, Subadress and gives Databyte
151
   I2cstart
152
   I2cwbyte Slaveadress
153
   I2cwbyte Subadress
154
   Incr Slaveadress                                         'for reading LSB=1
155
   I2crepstart
156
   I2cwbyte Slaveadress
157
   I2crbyte Databyte , Nack
158
   I2cstop
159
Return
160
161
Read_6:
162
   Subadress.7 = 1                                          'Set MSB for multiple reading
163
   I2cstart
164
   I2cwbyte Slaveadress                                     'SAD+W
165
   I2cwbyte Subadress
166
   Incr Slaveadress                                         'for reading LSB=1
167
   I2crepstart
168
   I2cwbyte Slaveadress                                     'SAD+R
169
   For J = 1 To 5
170
      I2crbyte Dataarray(j) , Ack
171
   Next
172
   I2crbyte Dataarray(6) , Nack
173
   I2cstop
174
Return
175
176
Read_6_mag:
177
   I2cstart
178
   I2cwbyte Slaveadress                                     'SAD+W
179
   I2cwbyte Subadress
180
   Incr Slaveadress                                         'for reading LSB=1
181
   I2crepstart
182
   I2cwbyte Slaveadress                                     'SAD+R
183
   For J = 1 To 5
184
      I2crbyte Dataarray(j) , Ack
185
   Next
186
   I2crbyte Dataarray(6) , Nack
187
   I2cstop
188
Return

Gruß,
Norbert

von Timon Michel (Gast)


Lesenswert?

Hey, ich bin so eben auf den Beitrag hier gestoßen, und ich hätte ein 
paar Fragen: man muss vor dem code noch sdl und sca definieren oder? 
Kann man 2 verschiedene sensoren auslesen?

von Norbert S. (norberts)


Lesenswert?

Hi,

das hatte ich in dem kopierten Code vergessen.

$lib "i2c_twi.lbx"
Config Twi = 400000
Config Scl = Portc.0
Config Sda = Portc.1
I2cinit

Das sind die Hardware I2C Pins eines ATMega324, nicht wie oben noch ein 
Mega8.

Das oben sind drei verschiedene Sensoren, wobei zwei davon im gleichen 
Gehäuse sind.

Gruß,
Norbert

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.