hi
ich bin grade mit dem Versuch beschäftigt, für einen Atmega8 mit
Winavr/GCC eine Software i2c-routine zu schreiben. Dummerweise treibt
mich dabei aber eine kleine if-Abfrage so langsam aber sicher in den
Wahnsinn. Das Ding wehrt sich schon seit tagen:
1 | #define SCL_PORT PORTC
|
2 | #define SCL_DDR DDRC
|
3 | #define SCL_PINREG PINC
|
4 | #define SCL_PIN PC5
|
5 | #define SDA_PORT PORTC
|
6 | #define SDA_DDR DDRC
|
7 | #define SDA_PINREG PINC
|
8 | #define SDA_PIN PC4
|
9 |
|
10 | unsigned char i2c_readNak(void)
|
11 | {
|
12 | unsigned char data;
|
13 | unsigned char i = 1;
|
14 | // sicherstellen dass alle zustände auf richtigem ausgangspunkt sind
|
15 | SDA_DDR &= ~(1<<SDA_PIN); // SDA: Datenrichtung: in
|
16 | SDA_PORT &= ~(1<<SDA_PIN); // SDA: low
|
17 | SCL_DDR |= (1<<SCL_PIN); // SCL: Datenrichtung: out
|
18 | SCL_PORT &= ~(1<<SCL_PIN); // SCL: low
|
19 | // empfangen einleiten
|
20 | data = 0;
|
21 | i = 1;
|
22 | while( i <= 8)
|
23 | {
|
24 | i2c_wait_quaterpuls();
|
25 | SCL_DDR &= ~(1<<SCL_PIN); // SCL: Datenrichtung: in (clockstreching)
|
26 | SCL_PORT |= (1<<SCL_PIN); // SCL: high
|
27 | while( bit_is_clear(SCL_PINREG,SCL_PIN) )
|
28 | {
|
29 | asm volatile ("nop");
|
30 | }
|
31 | SCL_DDR |= (1<<SCL_PIN); // SCL: Datenrichtung: out
|
32 | i2c_wait_quaterpuls();
|
33 | if( bit_is_set(SDA_PINREG,SDA_PIN) )
|
34 | {
|
35 | data = ( (data<<1) | 0x01); // neue information einschreiben
|
36 | }
|
37 | else
|
38 | {
|
39 | data = ( (data<<1) | 0x00);
|
40 | }
|
41 | i2c_wait_quaterpuls();
|
42 | SCL_PORT &= ~(1<<SCL_PIN); // SCL: low
|
43 | i2c_wait_quaterpuls(); // lowpuls abwarten
|
44 | i = i + 1;
|
45 | }
|
46 | SDA_DDR |= (1<<SDA_PIN); // SDA: Datenrichtung: out
|
47 | SDA_PORT |= (1<<SDA_PIN); // SDA: high = NO ACK
|
48 | i2c_wait_quaterpuls(); // lowpuls fertig warten
|
49 | SCL_DDR &= ~(1<<SCL_PIN); // SCL: Datenrichtung: in (clockstreching)
|
50 | SCL_PORT |= (1<<SCL_PIN); // SCL: high
|
51 | while( bit_is_clear(SCL_PINREG,SCL_PIN) )
|
52 | {
|
53 | asm volatile ("nop");
|
54 | }
|
55 | SCL_DDR |= (1<<SCL_PIN); // SCL: Datenrichtung: out
|
56 | i2c_wait_quaterpuls(); // highpuls abwarten
|
57 | i2c_wait_quaterpuls();
|
58 | SCL_PORT &= ~(1<<SCL_PIN); // zurück auf "warten auf Aufgabe"
|
59 |
|
60 | return data; // Daten ausgeben
|
61 | }/* i2c_readNak */
|
die dabei spinnende Abfrage ist die Zeile:
if(bit_is_set(SDA_PINREG,SDA_PIN) )
die spricht immer an, egal ob der Pin gesetzt ist oder nicht, was zur
Folge hat, dass der Code immer 0xff als Ergebniss zurückgibt.
hat mir da irgendjemand eine idee, woran es liegen könnte?
gruß und Danke
Matthias