www.mikrocontroller.net

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


Autor: Dan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>

#define MOSI  5
#define MISO  6
#define SCLK  7
#define CE    4

void spi_init (void)
{
//Ausgangsports auf Output
DDRB |= (1<<MOSI) | (1<<SCLK) | (1<<CE);
//Eingangsport auf Input
DDRB &= ~(1<<MISO);
//Register : Spi Aktiv, Master Mode Aktiv, Mode 1, 2mhz
SPCR |= (1<<CPHA) | (1<<SPR1) | (1<<SPR0);
SPCR |= (1<<MSTR);
SPCR |= (1<<SPE);
//CE aus, da RTC High-Active
PORTB &= ~(1<<CE);
}

void rtc_send (uint8_t w_address, uint8_t data)
{
//Chip Enable an
PORTB |= (1<<CE);
//Kurz Warten
_delay_us(50);
//Daten für Adresse ins Senderegister
SPDR = w_address;
//Adresse Senden
while(!(SPSR & (1<<SPIF)));
//Daten für Daten ins Senderegister
SPDR = data;
//Daten Senden
while(!(SPSR & (1<<SPIF)));
//Chip Enable aus
PORTB &= ~(1<<CE);
}

uint8_t rtc_recieve (uint8_t r_address)
{
static uint8_t temp=0;
//Chip Enable an
PORTB |= (1<<CE);
//Kurz Warten
_delay_us(50);
//Adresse ins Senderegister
SPDR = r_address;
//Adresse Senden
while(!(SPSR & (1<<SPIF)));
//Dummydaten ins Senderegister
SPDR = 0x01;
//Dummydaten Senden
while(!(SPSR & (1<<SPIF)));
//Empfangene Daten in Temp
temp = SPDR;
//Chip Enable aus
PORTB &= ~(1<<CE);
//Wert zurückgeben
return temp;
}

Und schliesslich noch mein kleines Testprogramm:
#include <avr/io.h>
#include <util/delay.h>
#include <inttypes.h>

uint8_t second;

int main(void){

lcd_init();
spi_init();

//Test Register schreiben
rtc_send(0x8F,0b01000100);

lcd_string("Gesendet: ");
lcd_data(0b01000100);

set_cursor(0,2);

//Test Register auslesen
second = rtc_recieve(0x0F);
lcd_data(second);


while(1);
return 0;
}

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
SPCR |= (1<<DORD);  // das fehlt.

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

Autor: Dan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.