
Zitat von
oderlachs
Im Posting 12 also genau vor Deiner Antwort ist ein Link zu dem Beispiel
Ich habe diesen Link nicht übersehen und bezog mich gerade darauf:
Wieso nimmst Du ein Beispiel, dass erklärtermaßen seitens des TE dort nicht funktioniert?
Zitat des verlinkten Threads:
When I am running this code on PROTEUS simulator I am not getting any output, but polling in the code working properly for applying delay.
1 Answer
I don't think you are generating the start condition correctly, among other things.
Was mich zu meiner Frage brachte, warum Du (als ein Lernender in I2C) einen Code nimmst, bei dem der TE selbst erklärt, dass der nicht geht, und bei dem zwar ein Teilnehmer Hilfestellung gab, dieser Thread jedoch weder geklärt, noch abgeschlossen wurde. Das war mir unverständlich, aber übersehen hab' ich nichts.
Genauso wie meine Aufforderung an Dich, den Bascom-Code zu zeigen, nicht aus dem Grund heraus entstand, dass ich nicht wüsste, wie's unter Bascom zu programmieren wäre, sondern deswegen, weil ich am funktionierenden Code genau die Einstellungen ablesen und dann Deinen C-Code beurteilen, bzw. verbessern kann.
- - - Aktualisiert - - -
Nur mal ein paar Sachen, die krumm sind, hier z.B. hast Du genau einen Fehler des TE's übernommen:
Code:
void rtc_stop()
{
TWCR=(1<<TWINT)|(TWSTO)|(1<<TWEN);
// warte bis fertig...
while(!(TWCR & (1<<TWINT)));
}
Das muss so lauten:
Code:
TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
Dieser Fehler hat zur Folge, dass die Funktion rtc_stop() nicht als Stop, sondern als Start ausgeführt wird.
Da wär' ich als DS1307 auch verwirrt 
Weiter, der Lesezyklus für die DS1307 geht so:
Code:
Start
Sende Schreibadresse (RW=0)
Sende Register der DS1307, welches adressiert werden soll
(Repeated) Start
Sende Leseadresse (RW=1)
Lese Sekunde mit ACK
...
Lese Jahr mit NACK
Stop
Jetzt schau' Dir mal den Zeugs an, den Du von dem verlinkten Thread des TE übernommen hast und vergleiche das:
Code:
rtc_start();
rtc_write(0b11010001); // 1101000=adress of ds1307 and bit 1= read
rtc_write(0x00); // pointing address location 00 i.e seconds
sec=rtc_read();
rtc_stop();
_delay_ms(50); // etwas warten
rtc_start();
rtc_write(0b11010001); // 1101000=adress of ds1307 and bit 1= read
rtc_write(0x01); // pointing address location 01 i.e minute
min=rtc_read();
rtc_stop();
_delay_ms(50); // etwas warten
rtc_start();
rtc_write(0b11010001); // 1101000=adress of ds1307 and bit 1= read
rtc_write(0x02); // pointing address location 02 i.e hours
hr=rtc_read();
rtc_stop();
_delay_ms(50); // etwas warten
Es wundert mich nicht, dass das nicht klappt, genauso wie ich verstehe, dass es frustriert, wenn man auf solchem Code aufbaut.
- - - Aktualisiert - - -
Versuch' das hier, ACK, NACK wird nicht berücksichtigt, da Du sowieso keine Behandlung der Status-Codes hast.
Code:
#define F_CPU 16000000UL
#include<avr/io.h>
#include<util/delay.h>
#define rtc_adr_w 0xD0
#define rtc_adr_r rtc_adr_w | 0x01
void rtc_init(void)
{
TWSR=0x00;
TWBR=0x98; // I2C Clock 50kHz@16MHz
}
void rtc_start(void)
{
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));
}
unsigned char rtc_read(void)
{
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
return(TWDR);
}
void rtc_write(unsigned char data)
{
TWDR=data;// sending address
TWCR=(1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));}
void rtc_stop()
{
TWCR=(1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
while(!(TWCR & (1<<TWINT)));
}
int main(void)
{
unsigned char sec;
unsigned char last_sec = 0;
DDRB=0xFF;
PORTB=0xFF;
rtc_init();
while(1)
{
rtc_start();
rtc_write(rtc_adr_w); // Sende Schreibadresse
rtc_write(0x00); // Sekunden Register Adresse
rtc_start(); // Repeated Start
rtc_write(rtc_adr_r); // Sende Leseadresse
sec = rtc_read(); // Wert Register 0 lesen = RTC Sekunde
rtc_stop();
if (sec != last_sec)
{
last_sec = sec;
PORTB ^= 0x01; // Toggle Bit 0
}
_delay_ms(100);
}
}
Mit was läuft eigentlich Dein ATM16? Tatsächlich mit 1,6MHz? Kann ich mir nicht vorstellen. Dann stimmt Dein delay_ms nicht.
Lesezeichen