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 | }
|