Forum: Mikrocontroller und Digitale Elektronik Problem: SPI Kommunikation zu DS1306


von Dan (Gast)


Lesenswert?

Hallo,

ich bin gerade dabei mir einen Wecker mit einem Atmega32 zu bauen. Die 
Zeitberechnung soll ein RTC übernehmen (JA!, ich weiss der Atmel könnte 
das selbst, aber ich möchte das aus bestimmten Gründen nicht). 
Genauergesagt ist der RTC der DS1306 von Maxim IC.

Datenblatt DS 1306: http://datasheets.maxim-ic.com/en/ds/DS1306.pdf

Die Kommunikation soll über SPI ablaufen. Ich habe nun ein kleines 
Programm geschrieben, mit dem ich einfach ein Register beschreiben und 
dann wieder auslesen will, um ein Gefühl dafür zu bekommen.

Nachdem ich allerdings das Register beschrieben habe bekomme ich beim 
Auslesen trotzdem immer nur 0x00 zurück. Genau das gleiche kommt auch 
zurück, wenn die Drähte nicht angeschlossen sind.

Ich weiss nicht ob ich da ein schwerwiegendes Softwareproblem habe oder 
ob einfach etwas defekt ist ?!?
Der Bereich im Code wo ich leichte Zweifel habe, ist die Funktion 
rtc_recieve. Denn nachdem ich die Adresse geschickt habe, muss ich die 
Daten empfangen, und dies tue ich doch indem ich einfach Dummydaten 
sende?

Da ich schon fast eine Woche an dieser Sache rumpuhle und die 
Datenblätter zig mal durchforstet habe, wäre es toll wenn ihr mir helfen 
könntet.

Hier die Codes:

SPI Funktionen:
1
#include <avr/io.h>
2
#include <inttypes.h>
3
#include <util/delay.h>
4
5
#define MOSI  5
6
#define MISO  6
7
#define SCLK  7
8
#define CE    4
9
10
void spi_init (void)
11
{
12
//Ausgangsports auf Output
13
DDRB |= (1<<MOSI) | (1<<SCLK) | (1<<CE);
14
//Eingangsport auf Input
15
DDRB &= ~(1<<MISO);
16
//Register : Spi Aktiv, Master Mode Aktiv, Mode 1, 2mhz
17
SPCR |= (1<<CPHA) | (1<<SPR1) | (1<<SPR0);
18
SPCR |= (1<<MSTR);
19
SPCR |= (1<<SPE);
20
//CE aus, da RTC High-Active
21
PORTB &= ~(1<<CE);
22
}
23
24
void rtc_send (uint8_t w_address, uint8_t data)
25
{
26
//Chip Enable an
27
PORTB |= (1<<CE);
28
//Kurz Warten
29
_delay_us(50);
30
//Daten für Adresse ins Senderegister
31
SPDR = w_address;
32
//Adresse Senden
33
while(!(SPSR & (1<<SPIF)));
34
//Daten für Daten ins Senderegister
35
SPDR = data;
36
//Daten Senden
37
while(!(SPSR & (1<<SPIF)));
38
//Chip Enable aus
39
PORTB &= ~(1<<CE);
40
}
41
42
uint8_t rtc_recieve (uint8_t r_address)
43
{
44
static uint8_t temp=0;
45
//Chip Enable an
46
PORTB |= (1<<CE);
47
//Kurz Warten
48
_delay_us(50);
49
//Adresse ins Senderegister
50
SPDR = r_address;
51
//Adresse Senden
52
while(!(SPSR & (1<<SPIF)));
53
//Dummydaten ins Senderegister
54
SPDR = 0x01;
55
//Dummydaten Senden
56
while(!(SPSR & (1<<SPIF)));
57
//Empfangene Daten in Temp
58
temp = SPDR;
59
//Chip Enable aus
60
PORTB &= ~(1<<CE);
61
//Wert zurückgeben
62
return temp;
63
}

Und schliesslich noch mein kleines Testprogramm:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <inttypes.h>
4
5
uint8_t second;
6
7
int main(void){
8
9
lcd_init();
10
spi_init();
11
12
//Test Register schreiben
13
rtc_send(0x8F,0b01000100);
14
15
lcd_string("Gesendet: ");
16
lcd_data(0b01000100);
17
18
set_cursor(0,2);
19
20
//Test Register auslesen
21
second = rtc_recieve(0x0F);
22
lcd_data(second);
23
24
25
while(1);
26
return 0;
27
}

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mit welcher Spannung versorgst du die RTC?
DB:  CLK Frequency  2V  max. 600kHz
                    5V  max. 2MHz
> 2mhz
Fahr das Ding doch mal langsamer an, du bist an der oberen Grenze.
Der Kommentar stimmt nicht mehr? Denn zusammen mit
> (1<<SPR1) | (1<<SPR0);
müsstest du sonst den AVR mit 256 MHz takten.
Also gut, die Geschwindigkeit ist es nicht...


Dann evtl. die Schieberichtung?
Bit 0 kommt beim DS1306 zuerst. Also: Data Order LSB first
1
SPCR |= (1<<DORD);  // das fehlt.

BTW:
Was passiert mit SPI-Mode 3?
(CPHA=1 und CPOL=1)
Sollte die RTC auch können.

von Dan (Gast)


Lesenswert?

Hallo,

der Kommentar ist selbstverständlich nicht mehr Aktuell.

Das Problem ist alerdings bereits gelöst, denn:

WER LESEN KANN IST KLAR IM VORTEIL!

Ich habe Tagelang nicht bemerkt, dass die RTC noch einen Separaten VCCIF 
(Speisespannung SPI Modul) hat...

Danke trotzdem.

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.