Hi
ich hab mir eine Software TWI zusammengebastelt da ich zurzeit mit dem
ATmega162 arbeite. Es sollen mehrere Geräte angesteuert werden, darunter
eine LM75 und ein externer EEPROM.
Eigentlich hab ich gedacht das alles funktioniert aber nun habe ich das
Board gewechselt und schon geht garnichts mehr. Das das Board
funktioniert ist schon geprüft, also da gibt es keine Probleme. Es liegt
also an der Software.
Ich hab hier mal ein kleines Beispiel zusammengestellt von einem
einfachen LM75 Lesevorgang.
1 | Master Start:
|
2 |
|
3 | DDRE &=~(1<<PE1); // SCL High
|
4 | _delay_loop_1(1);
|
5 | DDRE|=(1<<PE0); // SDA Low
|
6 | _delay_us(3);
|
7 | DDRE |=(1<<PE1); // SCL Low
|
8 | _delay_loop_1(1);
|
9 |
|
10 | Master write(byte=Adresse des LM75 + BIT 0 =1):
|
11 |
|
12 | char i=0;
|
13 | for(i=0;i<8;i++)
|
14 | {
|
15 | if(byte & 0x80)
|
16 | {
|
17 | DDRE&=~(1<<PE0); // SDA High
|
18 | }
|
19 | else
|
20 | {
|
21 | DDRE|=(1<<PE0); // SDA Low
|
22 | }
|
23 | byte=byte<<1;
|
24 | _delay_us(1);
|
25 |
|
26 | //SCL h->low .. Bit senden
|
27 | DDRE&=~(1<<PE1);
|
28 | _delay_loop_1(2);
|
29 | DDRE|=(1<<PE1);
|
30 | _delay_loop_1(1);
|
31 | }
|
32 | // ACK Prüfung
|
33 | DDRE&=~(1<<PE0); // SDA High
|
34 | DDRE&=~(1<<PE1); // SCL High
|
35 | _delay_loop_1(1);
|
36 |
|
37 | if(PINE & (1<<PE0)) // SDA auf high oder low prüfen
|
38 | {
|
39 | _delay_loop_1(1);
|
40 | DDRE|=(1<<PE1); // SCL low
|
41 | return 0;
|
42 | }
|
43 | else
|
44 | {
|
45 | _delay_loop_1(1);
|
46 | DDRE|=(1<<PE1); // SCL low
|
47 | return 1;
|
48 | }
|
49 |
|
50 | Master read(ack = 0, nack = 1)(das ganze zweimal wegen low und high byte):
|
51 |
|
52 | char i;
|
53 | char byte;
|
54 |
|
55 | DDRE&=~(1<<PE0);
|
56 |
|
57 | for(i=0;i<8;i++)
|
58 | {
|
59 | byte=byte<<1;
|
60 | if(PORTE & (1<<PINE)) byte|=1;
|
61 | //SCL h->low .. Bit empfangen
|
62 | DDRE&=~(1<<PE1);
|
63 | _delay_loop_1(2);
|
64 | DDRE|=(1<<PE1);
|
65 | _delay_loop_1(1);
|
66 | }
|
67 | if (ack=0)
|
68 | {
|
69 | DDRE|=(1<<PE0); //SDA low
|
70 | }
|
71 | else
|
72 | {
|
73 | DDRE&=~(1<<PE0); //SDA high
|
74 | }
|
75 | //SCL h->low .. Bit senden
|
76 | DDRE&=~(1<<PE1);
|
77 | _delay_loop_1(2);
|
78 | DDRE|=(1<<PE1);
|
79 | _delay_loop_1(1);
|
80 |
|
81 | return byte;
|
82 |
|
83 |
|
84 | Master Stop:
|
85 |
|
86 | DDRE|=(1<<PE0); // SDA vorsichtshalber auf low
|
87 | _delay_loop_1(1);
|
88 | DDRE&=~(1<<PE1); // SCL high
|
89 | _delay_loop_1(1);
|
90 | DDRE&=~(1<<PE0); // SDA high;
|
91 | _delay_loop_1(1);
|
So sieht jemand irgendwo einen Fehler im Aufbau/Ablauf?
Klar sind das keine vollständigen Funktionen, das ist ja auch nur ein
Beispiel.
Ein Problem hat die ACK Prüfung dargestellt, sieht da jemand vielleicht
etwas?
Hat jemand vielleicht einen eigenen C Code geschrieben wo ich mal
vergleichen kann?
Also wenn ich das am LM75 prüfe dann erhalte ich laut Software ein ACK
aber das auslesen ist dann immer 0.
Wo liegt das Problem?
Gruss