I2C mit DS3132 - Peter Fleury I2C implementierung

Gast #5064058
Lesenswert?

Hi,


habe bereits das DS1307 erfolgreich mit dem Library von Fleury 
angesprochen jetzt weigert sich der DS3131 aber Daten auszugeben.

Die Schaltung funktioniert mit diesem Arduino Sketch:
http://tronixstuff.com/2014/12/01/tutorial-using-ds1307-and-ds3231-real-time-clock-modules-with-arduino/

-> Hardware richtig verdrahtet.



Mein eigener Code hängt allerdings bei Zeile 165 (// this line is never 
reached), der LED Aufruf danach wird nicht mehr ausgeführt.
Hier der Code als Kopie auf bpaste.net mit Zeilennummern:
https://bpaste.net/show/019dacb8221c



Da die Fleury Funktion einen Rückgabewert liefert der entweder Aussagt 
das eine Verbindung zustande kam oder nicht verstehe ich nicht warum er 
dabei hängt?
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <i2cmaster.h> 
4

5

6
#define BAUD 9600
7
#define MYUBRR ((uint16_t) ((F_CPU / ((BAUD) * 16.0)) + .5) - 1)
8

9
#define rtc_clock 0x68
10

11
// contains what the bluetooth module received
12
uint8_t data;
13

14
void USART_Init(unsigned int ubrr) {
15
    // set baud rate
16
    UBRR0H = (unsigned char)(ubrr>>8);
17
    UBRR0L = (unsigned char)(ubrr);
18
    // enable receiver, transmitter and interrupts for rx/tx
19
    UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (1<< TXCIE0);
20
}
21

22

23

24
void USART_transmit(char c) {
25
    while ( !(UCSR0A & (1<<UDRE0)) ) {}
26
    UDR0 = c;
27
}
28

29

30

31
void transmit_char(char c) {
32
    USART_transmit(c);
33
    USART_transmit('\r');
34
    USART_transmit('\n');
35
}
36

37

38

39
void send_string(char s[]) {
40
    int i =0;
41

42
    while (s[i] != 0x00) {
43
        USART_transmit(s[i]);
44
        i++;
45
    }
46
    USART_transmit('\r');
47
    USART_transmit('\n');
48

49
}
50

51

52
// code for two status leds, to signal error and ok states
53
// please dont look to closely....needs rewriting
54

55
#define ERROR_LED_2 PB1
56
#define ERROR_LED PB0
57
#define OK_LED PB2
58

59
#define ERROR_LED_2_PORT PORTB
60
#define ERROR_LED_PORT PORTB
61
#define OK_LED_PORT PORTB
62

63

64
// turn the error led on and keep it on
65
void error_led_on() {
66
    ERROR_LED_PORT |= (1 << ERROR_LED);
67
}
68

69
// turn it off
70
void error_led_off() {
71
    ERROR_LED_PORT &= ~(1 << ERROR_LED);
72
}
73

74

75
void error_led2_on() {
76
    ERROR_LED_2_PORT |= (1 << ERROR_LED_2);
77
}
78

79
// turn it off
80
void error_led2_off() {
81
    ERROR_LED_2_PORT &= ~(1 << ERROR_LED_2);
82
}
83

84

85
// flash the error led, fast
86
void flash_fast(uint8_t count) {
87
    for (int n=1; n<=count; n++) {
88
        error_led_on();
89
        _delay_ms(300);
90
        error_led_off();
91
        _delay_ms(300);
92
    }
93
}
94

95
// ...normal
96
void flash_normal(uint8_t count) {
97
    for (int n=1; n<=count; n++) {
98
        error_led_on();
99
        _delay_ms(1000);
100
        error_led_off();
101
        _delay_ms(1000);
102
    }
103
}
104

105
// second led to have more indicator for where we are stuck in the code
106
void flash_normal_error_led_2(uint8_t count) {
107
    for (int n=1; n<=count; n++) {
108
        error_led2_on();
109
        _delay_ms(1000);
110
        error_led2_off();
111
        _delay_ms(1000);
112
    }
113
}
114
// ...slow
115
void flash_slow(uint8_t count) {
116
    for (int n=1; n<=count; n++) {
117
        error_led_on();
118
        _delay_ms(3000);
119
        error_led_off();
120
        _delay_ms(3000);
121
    }
122
}
123

124
// a third led, can be used to signal ok states
125
void flash_ok_led(uint8_t count) {
126
    for (uint8_t n=1; n <= count; n++) {
127
        OK_LED_PORT |= (1 << OK_LED);
128
        _delay_ms(1000);
129
        OK_LED_PORT &= ~(1 << OK_LED);
130
        _delay_ms(1000);
131
    }
132
}
133

134
// ---------------------------------- led code end
135

136

137

138

139

140

141

142
uint8_t decToBcd(uint8_t val)
143
{
144
  return( (val/10*16) + (val%10) );
145
}
146
// Convert binary coded decimal to normal decimal numbers
147
uint8_t bcdToDec(uint8_t val)
148
{
149
  return( (val/16*10) + (val%16) );
150
}
151

152

153

154

155
void setTime(uint8_t second, uint8_t minute, uint8_t hour, uint8_t dayOfWeek, 
156
        uint8_t dayOfMonth, uint8_t month, uint8_t year) {
157

158
    flash_normal(1);
159
    // initialize, taken from peter fleurys i2c example (he wrote the i2c code)
160
    i2c_init();
161
    // connect to the device and tell it that we want to write to it
162
    
163
    uint8_t ret;
164
    //ret = i2c_start(rtc_clock+I2C_WRITE);  // set device address and write mode
165
    ret = i2c_start(rtc_clock);
166
    // this line is never reached
167
    flash_normal(1);
168

169
    if ( ret ) {
170
        flash_normal(3);
171
        /* failed to issue start condition, possibly no device found */
172
        i2c_stop();
173
        // we can issue an error message here if the device failed to respond
174

175
     } else {
176
        flash_ok_led(3);
177
        // tell the device where we want to write to (address in ram)
178
        i2c_write(0x00);
179

180
        // set time
181
        i2c_write(decToBcd(second)); // set seconds
182
        i2c_write(decToBcd(minute)); // set minutes
183
        i2c_write(decToBcd(hour)); // set hours
184
        i2c_write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
185
        i2c_write(decToBcd(dayOfMonth)); // set date (1 to 31)
186
        i2c_write(decToBcd(month)); // set month
187
        i2c_write(decToBcd(year)); // set year (0 to 99)    
188
        i2c_stop();     
189
    }                    
190
}
191
 
192

193

194
uint8_t result;
195

196
typedef struct {
197
    uint8_t sec;
198
    uint8_t min;
199
    uint8_t hour;
200
    uint8_t weekDay;
201
    uint8_t date;
202
    uint8_t month;
203
    uint8_t year;  
204
} rtc_t;
205

206

207

208
rtc_t rtc;
209

210
void getTime(void) {
211
    // receive 1 byte (seconds)
212
    flash_normal(3);
213

214
    uint8_t ret;
215
    ret = i2c_start(rtc_clock+I2C_WRITE);  // set device address and write mode
216
    if ( ret ) {
217
        flash_normal(3);
218
        /* failed to issue start condition, possibly no device found */
219
        i2c_stop();
220
        // we can issue an error message here if the device failed to respond
221

222
     } else {
223
        flash_ok_led(1);
224
        /* issuing start condition ok, device accessible 
225
        we can now use i2c_write() to talk to the device*/
226
          
227

228

229
        // request second ram adress (tell the chip at what adress we want to start reading)
230
        // 0x00 = 
231
        i2c_write(0x00);
232
        i2c_stop();
233

234
        // _rep_start or _start? whats the difference?
235
        i2c_rep_start(rtc_clock);
236
        result = i2c_readAck();
237
        rtc.sec = i2c_readAck();                // read second and return Positive ACK
238
        rtc.min = i2c_readAck();                 // read minute and return Positive ACK
239
        rtc.hour= i2c_readAck();               // read hour and return Negative/No ACK
240
        rtc.weekDay = i2c_readAck();           // read weekDay and return Positive ACK
241
        rtc.date= i2c_readAck();              // read Date and return Positive ACK
242
        rtc.month=i2c_readAck();            // read Month and return Positive ACK
243
        rtc.year =i2c_readNak();             // read Year and return Negative/No ACK
244
        i2c_stop();
245
    }
246
}
247

248

249

250

251
int main(void) {
252
    DDRB |= (1 << ERROR_LED);
253
    DDRB |= (1 << ERROR_LED_2);
254

255
    DDRB |= (1 << OK_LED);
256

257
    // test leds to see if they are connected and working
258

259
    flash_normal(1);
260
    flash_normal_error_led_2(1);
261
    flash_ok_led(1);    
262

263

264
    i2c_init();
265
    uint8_t count = 0;
266
    setTime(30,42,21,4,26,11,14);
267
    
268
    while (1) {
269
        
270
        
271
        _delay_ms(3000);
272
        
273
        getTime();
274
        // flash the led for the ammount of seconds
275
        for (uint8_t n=0; n <= rtc.sec; n++) {
276
            flash_ok_led(1);
277
        }
278
        flash_normal(2);
279
            
280
    }
281
}
#5064312
Lesenswert?

Hallo Julius,

Deine I2C Adresse ist um eine Stelle falsch

Im Datenblatt des DS3231 ist die Adresse als "1101000" angegeben, das 
sind nur 7 bits. Da fehlt das W/R Bit. Die angegebene Adresse muß für 
Peters Bibliothek entweder als "0xC0 für Writes ausgeben werden und als 
0xC1 zum Lesen.

Also 0b11010000 zum Schreiben und zum lesen 0b11010001

Ich verwende Peter Fleurys Bibliothek auch und sende die Slave Adresse 
für den DS3231 immer als 0xC0(schreiben) oder 0xC1(lesen)

Guck mal hier:

http://homepage.hispeed.ch/peterfleury/doxygen/avr-gcc-libraries/group__pfleury__ic2master.html


#define rtc_clock 0x0xC0

Und verwende es so wie in seinem Beispiel angegeben:

ret = i2c_start(rtc_clock+I2C_WRITE);  // set device address

Bei der Arduino Bibliothek mußt Du tatsächlich 0x68 verwenden.
Gast #5064866
Lesenswert?

Ist 1101000(2) nicht 0x68(16) ?

Dann wäre doch das als rtc_clock richtig und dann kombiniert mit 
I2C_READ was ja eine 1 mehr ist:

11010001 = D1

und Lesen:
11010000 = D0

Oder warum verwendest du C0 und C1?
#5064898
Lesenswert?

Julius schrieb:
> Ist 1101000(2) nicht 0x68(16) ?
Nein, da fehlt das LSB , 0x68 ist ja in Wirklichkeit nur 0b01101000

es muss 0b1101000(x) sein, wo x=0 -> Write, x=1 -> Read
>
> Dann wäre doch das als rtc_clock richtig und dann kombiniert mit
> I2C_READ was ja eine 1 mehr ist:
>
> 11010001 = D1
Lesen
>
> und Lesen: - Falsch
> 11010000 = D0
Schreiben
>
Das stimmt, aber 0x68 + 1 wäre 0x69 und nicht 0xD1

Beim Lesen wird 1 auf die 0xD0 addiert und es wird daraus 0xD1

> Oder warum verwendest du C0 und C1?

Oh, da habe ich mich verhaut. 0xD0/D1 ist natuerlich richtig. Danke für 
die Richtigstellung.
Gast #5065020
Lesenswert?

Habe jetzt mit D1 für lesen und D0 für Schreiben noch einmal getestet, 
leider wird die Zeile:
1
// ------------------------------this line is never reached

nie erreicht :( Also die LED blinkt nicht.

Ideen?



Ausschnitt:
1
#define READ 0xD1
2
#define WRITE 0xD0
3

4

5
void setTime(uint8_t second, uint8_t minute, uint8_t hour, uint8_t dayOfWeek, 
6
        uint8_t dayOfMonth, uint8_t month, uint8_t year) {
7

8
    flash_normal(2);
9
    // initialize, taken from peter fleurys i2c example (he wrote the i2c code)
10
    i2c_init();
11
    // connect to the device and tell it that we want to write to it
12
    flash_ok_led(1);
13

14
    uint8_t ret;
15
    //ret = i2c_start(rtc_clock+I2C_WRITE);  // set device address and write mode
16
    ret = i2c_start(WRITE);
17

18
    // ------------------------------this line is never reached
19
    flash_ok_led(1);
20

21
    //ret = i2c_start(0xD0);
22
    
23
    
24
    if ( ret ) {
25
        flash_normal(3);
26
        /* failed to issue start condition, possibly no device found */
27
        i2c_stop();
28
        // we can issue an error message here if the device failed to respond
29

30
     } else {
31
        flash_ok_led(3);
32
        // tell the device where we want to write to (address in ram)
33
        i2c_write(0x00);
34

35
        // set time
36
        i2c_write(decToBcd(second)); // set seconds
37
        i2c_write(decToBcd(minute)); // set minutes
38
        i2c_write(decToBcd(hour)); // set hours
39
        i2c_write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
40
        i2c_write(decToBcd(dayOfMonth)); // set date (1 to 31)
41
        i2c_write(decToBcd(month)); // set month
42
        i2c_write(decToBcd(year)); // set year (0 to 99)    
43
        i2c_stop();     
44
    }                    
45
}
46

47
 
48

49

50
uint8_t result;
51

52
typedef struct {
53
    uint8_t sec;
54
    uint8_t min;
55
    uint8_t hour;
56
    uint8_t weekDay;
57
    uint8_t date;
58
    uint8_t month;
59
    uint8_t year;  
60
} rtc_t;
61

62

63

64

65
int main(void) {
66
    DDRB |= (1 << ERROR_LED);
67
    DDRB |= (1 << ERROR_LED_2);
68

69
    DDRB |= (1 << OK_LED);
70

71
    // test leds to see if they are connected and working
72

73
    flash_normal(1);
74
    flash_normal_error_led_2(1);
75
    flash_ok_led(1);    
76

77

78
    i2c_init();
79
    uint8_t count = 0;
80
    setTime(30,42,21,4,26,11,14);
81
    
82
    while (1) {
83
        
84
        count = count + 1;
85
        _delay_ms(3000);
86
        
87
        getTime();
88
        for (uint8_t n=0; n <= rtc.sec; n++) {
89
            flash_ok_led(1);
90
        }
91
        flash_normal(2);
92
            
93
    }
94
}
#5065054
Lesenswert?

Julius schrieb:
> Habe jetzt mit D1 für lesen und D0 für Schreiben noch einmal getestet,
> leider wird die Zeile:

Julius schrieb:
> Habe jetzt mit D1 für lesen und D0 für Schreiben noch einmal getestet,
> leider wird die Zeile:
> // --------------------

Ich kann Dir im Augenblick wegen Zeitmangel (Arbeit) nicht wirklich 
helfen. Wenn es vorher mit anderer Software funktioniert hat, schlage 
ich vor die dazugehörigen I2C_init() Einstellungen sorgfältig zu 
überprüfen. Dein I2C_Write hängt den uC. Das kann Hardware technisch 
bedingt sein oder falsche Einstellung der INIT Funktion. Wie gross sind 
die I2C Pullup Widerstände? ICh nehme standardmäßig immer 3.9KOhm bei 
5V.

Ich sehe, dass Deine LIB nicht die von mir versendete ist. Mit Deiner 
habe ich noch keine Erfahrung weil ich bis jetzt immer nur die 
I2CSoftMAster Bibl. verwendete. Vielleicht kennt sich jemand anders hier 
wirklich damit aus.

Im Anhang ist die Bibl. die ich bei mir verwende. Sie ist auch von 
Fleury und funktionierte bis jetzt immer einwandfrei.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren