Moin,
ich habe an meinen Atmega1284p das HMC6352 Breakout Board von Watterott
angeschlossen, und möchte bei dem die Gradzahlen über I2C abfragen. Das
scheint aber nicht zu funktionieren. Ich benutzte diese Funktionslib:
Beitrag "AVR TWI Master und Slave Funtionen in C"
1
#include<stdio.h>
2
3
#include<avr/io.h>
4
#include"defines.h"
5
#include<util/delay.h>
6
#include"uart.h"
7
#include"TWI_Master.h"
8
9
#define compass 0x42
10
11
voiddelay_ms(inta)
12
{
13
for(inti=0;i<a;i++)
14
{
15
_delay_ms(1);
16
}
17
}
18
19
intmain(void)
20
{
21
DDRD|=(1<<7);
22
PORTD|=(1<<7);
23
24
sei();
25
uart_init();
26
uart_puts("Uart Init\n");
27
28
delay_ms(250);
29
30
if(!TWIM_Init(100000UL))
31
{
32
TWIM_Stop();
33
uart_puts("TWIM_Init Failed\n");
34
}
35
36
while(1)
37
{
38
if(!TWIM_Start(compass,TWIM_WRITE))
39
{
40
TWIM_Stop();
41
uart_puts("Start for write Failed\n");
42
}else{
43
if(!TWIM_Write(0x41))
44
{
45
uart_puts("Write Failed\n");
46
}else{
47
uart_puts("Byte send\n");
48
}
49
TWIM_Stop();
50
51
_delay_us(600);
52
53
if(!TWIM_Start(compass,TWIM_READ))
54
{
55
TWIM_Stop();
56
uart_puts("Start for read Failed\n");
57
}else{
58
59
intinCompass;
60
inCompass=TWIM_ReadAck();
61
inCompass=inCompass<<8;
62
inCompass+=TWIM_ReadNack();
63
inCompass/=10;
64
65
charout[20];
66
intn=sprintf(out," Compass: %d \n",inCompass);
67
68
uart_puts(out);
69
TWIM_Stop();
70
}
71
}
72
73
delay_ms(1000);
74
75
}
76
}
Das Programm scheiter schon in Zeile 31 bei:
1
(!TWIM_Start(compass,TWIM_WRITE))
Hier gibt mir die Serille Schnittstelle immer "Start for write Failed".
Habt ihr ne Idee, was falsch sein könnte?
Die MC und Kompass werden mit 4,99V vom Spannungsregler gespeist. Auf
dem Breakoutboard sind bereits die 10k Widerstände für die SCL/SDA
Leitungen drauf.
Die SCL/SDA Leitungen sind richtig verlötet, und mit einem Multimeter
mit dem Durchgangsmesser getestet.
Die Strecke zwischen dem MC und Kompass sind ca. 25cm, (früher hats
damit geklappt) wenn ich den Kompass direkt an das MC Board anschliese,
mit ca. 5 cm zwischen den beiden, gehts auch nicht.
Habt ihr ne Idee, was falsch sein könnte?
MfG
Philipp
Fakt ist auf jeden Fall das der AVR kein ACK vom Slave bekommt. Damit
ergeben sich 3 Möglichkeiten:
- entweder stimmt die Adresse nicht (und der Slave antwortet nicht)
- SCL und/oder SDA sind unterbrochen oder kurzgschlossen
- die Pullups fehlen oder SDA/SCL wird auf GND gezogen.
Messe doch mit dem Multimeter das Potential der SDA und SCL-Leitung. Es
sollte im Ruhezustand 5V (high) sein.
Peter Fleury's Lib verschiebt aber die Adresse nicht nach rechts wenn
ich mich nicht irre.
Wenn du die Möglichkeit hast, benutze einen Logikanalyzer oder Oszi,
dann siehst du genau was auf dem Bus passiert. I2C ist ja schön einfach
zu debuggen :)
Moin,
also die Leitungen habe ich nochmal genaustens geprüft. An beiden liegt
5V an.
Ich habe eine Schleife geschrieben, die alle Adressen einmal
durchprobiert. Mit manueller Verschiebung, und ohne, da das eigentlich
die Funktion macht.
Als ergebnis habe ich dir Adresse 0x7F bekommen. Ich probiere die jetzt
mal, vielleicht gehts ja, obwohl ich mir nicht erklären kann warum die
Adresse anders als im Datenblatt ist.
MfG
Philipp
1
if(!TWIM_Init(100000UL))
2
{
3
uart_puts("TWI nicht init\n");
4
}
5
6
7
for(unsignedchari=0;i<=255;i++)
8
{
9
if(TWIM_Start(i,TWIM_WRITE))
10
{
11
uart_puts("Fetig: Normal: ");
12
uart_putc(i);
13
}
14
delay_ms(10);
15
if(TWIM_Start(i>>1,TWIM_WRITE))
16
{
17
uart_puts("Fetig: Verschoben: ");
18
uart_putc(i);
19
}
20
delay_ms(10);
21
}
22
23
uart_puts("Durchgelaufen\n");
Habe gerade mit 0x7F probiert. Start geht jetzt, aber Schreiben geht
immer noch nicht.
Laut Datenblatt vom HMC6352 hat der die (7-Bit) Adresse 0x21. Daraus
wird in TWIM_Start durch Shift Left das Adressbyte 0x42 erzeugt.
/*
** Send device address
*/
TWDR = (Address<<1) + TWIM_Type;
Der Aufruf mit
#define compass 0x42
...
if(!TWIM_Start(compass,TWIM_WRITE))
muß also schief gehen.
Mfg
Es gehen weder 0x42 noch 0x21. Ich hatte bisher immer noch mit dieser
anderen Lib gearbeitet, die in der Start Funktion die Adresse
verschiebt.
Weil ich einen Kondesator vergessen hatte, lag vorhin am Kompass 5.5V
an. Laut Datenblatt verträgt wer maximal 5.2V. Vielleicht habe ich ihn
zerschossen. Ich habe mir einen neuen bestellt, da ich sowieso noch
einen anderen brauchte. Ich melde mich wieder wenn der da ist, und geht,
oder nicht geht.
MfG
Philipp
0x7F (um 1 nach rechts geschoben also alles Einsen) ist die
Broadcast-Adresse von I2C. Normalerweise reagieren alle Geräte auf diese
Adresse (bei manchen kann man es konfigurieren).
Ich schließe mich meinem Vorposter an, Adresse 0x21 mit deiner Library
sollte gehen (mit Peter Fleurys aber 0x42!). Allerdings hätte das Device
auch in der Schleife darauf reagieren sollen. Probier es doch nochmal
gezielt aus.
Moin,
ich habe alles noch mal probiert, aber es geht nicht. Morgen kommt der
neue Kompass, der sollte gehen.
Ich habe dazu heute noch einen Mega8 probiert, und mit dem geht alles
ohne Probleme.
Bei meiner Lib muss ich die 8bit Adresse eingeben, die wird in der
Startfunktion um 1 nach rechts verschoben, also müsste es beim Kompass
0x42 sein, aber auch 0x21 geht nicht.
MfG
Philipp
Philipp Maricek schrieb:> Bei meiner Lib muss ich die 8bit Adresse eingeben, die wird in der> Startfunktion um 1 nach rechts verschoben, also müsste es beim Kompass> 0x42 sein, aber auch 0x21 geht nicht.
In der in TWI_Master.c enthaltenen TWIM_Start wird die übergebene
Adresse nach links verschoben, d.h. der Routine muß man die 7-Bit
Adresse 0x21 übergeben, damit der Kompaß-Chip angesprochen werden kann.
Verwendest du eine andere Lib, als die in deinem ersten Post verlinkte?