- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Rtc ds3231

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    09.08.2012
    Beiträge
    6

    Rtc ds3231

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo ich bin absoluter programmier anfänger und wollte nun mir auf LCD die Uhrzeit anzeigen lassen.I2C Bus.
    Ich benutze einen atmega1284 und das RTC DS3231.
    ich habe mein LCD an den Ports PC4-PC7 und den RTC SCL an PC0(SCL) und SDA an PC1(SDA)
    allerdings weiß ich gar nicht wie ich überhaupt anfangen soll.

    ICh habe mir jetzt schon seit tagen durch viele code beispiele gelesen, aber ich verstehe es einfach nicht.

    LG
    Simone

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    36
    Beiträge
    5.056
    Wilkommen im Forum,
    hast du schon einfache Ein/Ausgabe versucht? Ich würde als Anfänger mit der einfachen Ein/Ausgabe beginnen (wie die Meisten die anfangen), Signale verknüpfen,....

    Erst wenn du weißt wie es geht würde ich mich an einen Bus wagen.

    Wenn du externe ICs verwendest brauchst du immer die Datenblätter. Dort steht die Ansteuerung drinnen, was es zu beachten gibt,...

    Nach diesem kann man ein Programm erstellen. Wenn du irgendwo Probleme hast kannst du den Code posten und es wird dir geholfen.

    MfG Hannes

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    09.08.2012
    Beiträge
    6
    Hallo
    also ich habe jetzt den code von Peter Fleury angewendet "I2C Master Interface" und mit einerm oszilloskop an PC1 geptüft ob daten gesendet werden.
    Das klappt auch, aber ich kann leider keine daten an PD6 (INT/SQW) empfangen/messen.
    ich versuche mal den code hier zu posten.
    Vielleicht sieht ja einer von euch den Fehler, ich finde ihn leider nicht.

    * TWI_Test.c
    #define F_CPU 20000000UL
    /* I2C clock in Hz */
    #define SCL_CLOCK 100000L



    #include <avr/io.h>
    #include <util/twi.h>

    /************************************************** ***********************
    Initialization of the I2C bus interface. Need to be called only once
    ************************************************** ***********************/
    void i2c_init(void)
    {
    /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */

    TWSR = 0; /* no prescaler */
    TWBR = ((F_CPU/SCL_CLOCK)-16)/2; /* must be > 10 for stable operation */

    }/* i2c_init */

    /************************************************** ***********************
    Issues a start condition and sends address and transfer direction.
    return 0 = device accessible, 1= failed to access device
    ************************************************** ***********************/
    unsigned char i2c_start(unsigned char address)
    {
    uint8_t twst;

    // send START condition
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

    // wait until transmission completed
    while(!(TWCR & (1<<TWINT)));

    // check value of TWI Status Register. Mask prescaler bits.
    twst = TW_STATUS & 0xF8;
    if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;

    // send device address
    TWDR = address;
    TWCR = (1<<TWINT) | (1<<TWEN);

    // wail until transmission completed and ACK/NACK has been received
    while(!(TWCR & (1<<TWINT)));

    // check value of TWI Status Register. Mask prescaler bits.
    twst = TW_STATUS & 0xF8;
    if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;

    return 0;

    }/* i2c_start */


    /************************************************** ***********************
    Issues a start condition and sends address and transfer direction.
    If device is busy, use ack polling to wait until device is ready

    Input: address and transfer direction of I2C device
    ************************************************** ***********************/
    void i2c_start_wait(unsigned char address)
    {
    uint8_t twst;


    while ( 1 )
    {
    // send START condition
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

    // wait until transmission completed
    while(!(TWCR & (1<<TWINT)));

    // check value of TWI Status Register. Mask prescaler bits.
    twst = TW_STATUS & 0xF8;
    if ( (twst != TW_START) && (twst != TW_REP_START)) continue;

    // send device address
    TWDR = address;
    TWCR = (1<<TWINT) | (1<<TWEN);

    // wail until transmission completed
    while(!(TWCR & (1<<TWINT)));

    // check value of TWI Status Register. Mask prescaler bits.
    twst = TW_STATUS & 0xF8;
    if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
    {
    /* device busy, send stop condition to terminate write operation */
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

    // wait until stop condition is executed and bus released
    while(TWCR & (1<<TWSTO));

    continue;
    }
    //if( twst != TW_MT_SLA_ACK) return 1;
    break;
    }

    }/* i2c_start_wait */


    /************************************************** ***********************
    Terminates the data transfer and releases the I2C bus
    ************************************************** ***********************/
    void i2c_stop(void)
    {
    /* send stop condition */
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

    // wait until stop condition is executed and bus released
    while(TWCR & (1<<TWSTO));

    }/* i2c_stop */


    /************************************************** ***********************
    Send one byte to I2C device

    Input: byte to be transfered
    Return: 0 write successful
    1 write failed
    ************************************************** ***********************/
    unsigned char i2c_write( unsigned char data )
    {
    uint8_t twst;

    // send data to the previously addressed device
    TWDR = data;
    TWCR = (1<<TWINT) | (1<<TWEN);

    // wait until transmission completed
    while(!(TWCR & (1<<TWINT)));

    // check value of TWI Status Register. Mask prescaler bits
    twst = TW_STATUS & 0xF8;
    if( twst != TW_MT_DATA_ACK) return 1;
    return 0;

    }/* i2c_write */


    int main(void)
    { DDRC = (1<<PC0)|(1<<PC1);
    PORTC = (1<<PC0)|(1<<PC1);
    DDRD= (1<<PD6);
    PORTD=(1<<PD6);
    i2c_init();
    // write 0x75 to EEPROM address 5 (Byte Write)
    //i2c_start_wait(0xAA); // set device address and write mode
    i2c_start(0x6;
    i2c_write(0x0E); // write address = 5
    i2c_write(0b00000000); // write value 0x75 to EEPROM
    i2c_stop();

    i2c_start(0x6;
    i2c_write(0x0F); // write address = 5
    i2c_write(0b00000100); // write value 0x75 to EEPROM
    i2c_stop();
    //TODO:: Please write your application code
    while(1)
    {



    }
    }

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    36
    Beiträge
    5.056
    Du solltest die Code Tags verwenden, damit du den Code direkt in den Post integrierst. Wenn du auf Antorten gehst und dann auf Erweitert siehst du ein Raute Symbol. Damit kannst du den Code integrieren.

    Jetzt zu deinem Problem. Du solltest dich in die Bustopologie genau einlesen. Ich weiß zwar nicht wie du es angeschlossen hast, bei einem I2C hast du aber 2Leitungen (eigentlich min. 4 da du noch VCC und GND brauchst). Die anderen Leitungen sind der Takt und die Daten. Der Takt wird mit SCL (Serial Clock) und die Daten werden mit SDA (Serial Data) bezeichnet.

    Da du TWSR, TBSR,... Register verwendest, verwendest du Hardware I2C. Das bedeutet das du SCL des IC (dein RTC, könnte aber auch ein anderer sein) mit SCL von deinem µC (PC0). Das gleiche ist mit PC1 (das wäre SDA). Der Bus ist bidirektional. Es geht vom µC die Daten an den I2C-Teilnehmer über die SDA Leitung, aber auch vom I2C Teilnehmer zum µC. Der Clock wird immer vom Master erzeugt. Ich schreibe absichtlich nicht µC, da man den auch als Slave konfigurieren kann.

    Es gibt auch einen TWI-Interrupt, falls du die Übertragung Interrupt gesteuert haben willst.

    MfG Hannes

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    09.08.2012
    Beiträge
    6
    Hallo Hannes.
    Danke für deine Antwort.
    Ich habe nun einen anderen code verwendet (Peter fleury) da er für mich einfacher zu verstehen war. Unten ein kleiner auzug davon. Es klappt auch alles, habe es mit einem osziloskop nach geprüft. Nun wollte ich aber den INT/SQW am ausgang aktivieren (auskommentierter Teil) leider funktioniert das nicht.
    Was mache ich falsch?
    HIer ein auszug aus dem Datenblatt des DS3231
    Alarm1 can be set by writing to register 07h- to 0Ah. The alarm can be programmed to activate the INT/SQW output on an alarm match condition.
    Bit 7 of each of the time of day alarm registers are make bits.


    int main(void)
    { DDRC = (1<<PC0)|(1<<PC1);
    PORTC = (1<<PC0)|(1<<PC1);
    DDRD= (1<<PD6);
    PORTD=(1<<PD6);
    i2c_init();



    //i2c_start(0xD0);
    //i2c_write(0x07);
    //i2c_write(0x80);
    //i2c_write(0x80);
    //i2c_write(0x80);
    //i2c_write(0x80);
    //i2c_stop();
    //
    //i2c_start(0xD0);
    //i2c_write(0x0E);
    //i2c_write(0x05);
    //i2c_stop();



    while(1)
    {

    _delay_ms(1);

    i2c_start(0xD1);
    i2c_write(0x00); // write address = 5
    i2c_stop();

    _delay_ms(100);

    i2c_start(0xD0);
    i2c_write(0x0B);
    i2c_write(0x05);
    i2c_stop();


    }
    }

    LG simone

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.08.2006
    Ort
    Würzburg, Germany
    Beiträge
    716
    Hallo,

    funktioniert dein LCD schon? Wenn nicht würde ich erst mal daran gehen, um die Funktionsweise des Controllers besser zu verstehen. Und wenn das LCD läuft kann man seinen Code auch leichter debuggen, da man Statuswerte einfach anzeigen kann.

    Wie ist denn die Verdrahtung deines I2C-Busses? Hast du die Pull-Up-Widerstände richtig platziert? Vielleicht wäre es sinnvoll mal einen Schaltplan deiner Schaltung zu zeigen, damit wir hier eventuell Fehler erkennen können.

    Viele Grüße
    Andreas

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    09.08.2012
    Beiträge
    6
    Hallo Andreas,
    um mein LCD kümmere ich mich erst später wollte erst mal mein bauteil richtig ansteuern können.
    Der schaltplan ist im anhang. Da sind aber die 2 pull up widerstände noch nicht mit eingezeichnet, da ich sie nachträglich eingelötet habe.
    Zum debuggen brächte ich einen JATG, den ich aber leider nicht habe.

    LG
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken ds3231.jpg  

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.08.2006
    Ort
    Würzburg, Germany
    Beiträge
    716
    Hallo,

    Zitat Zitat von simonelein Beitrag anzeigen
    Zum debuggen brächte ich einen JATG, den ich aber leider nicht habe.
    Genau deshalb solltest du das LCD erst mal zum laufen bekommen. Wenn du dann mit den Ports des Controllers einigermassen vertraut bist würde ich erst mal testen, ob die ganzen Pins richtig geschaltet werden. Beim I2C ist das etwas tricky, da der Pin entweder als Eingang verwendet wird, oder als Ausgang um die Leitung auf Low zu ziehen. Das würde ich als nächstes mithilfe eines Meßgerätes und des LCD überprüfen. Mit dem Meßgerät messen, ob der Controller die Leitung korrekt auf Low zieht und dann auf dem LCD ausgeben, wie der Status der Leitung ist und diese dann mal mit einer Brücke auf Low ziehen.

    Wenn alle IOs funktionieren und das Problem immer noch besteht kann man sich mal den Code anschauen. Aber da er ja kopiert ist sollte dieser funktionieren, zumindest wenn er durch das kopieren nicht verändert wurde.

    Viele Grüße
    Andreas

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    09.08.2012
    Beiträge
    6
    hallo andreas,
    mit einem messgerät (oszilloskop) habe ich es schon überprüft. Wie gesagt das klappt alles. Nur den alarm kann ich nicht aktivieren.
    die 0x80 ist ein Datenbyte was in die RTC geschrieben werden soll. 0x80 bedeutet in binär 10000000. also eine 1 an die stelle wo die Alarmbits stehen.

    Datenblatt RTC Seite 11. Register adresse 0x07 bis 0x0A. Da sollen mit der 0x80 die bits A1M1 bis A1M4 gesetzt werden.

    ..und genau das funktioniert nicht. Das lässt sich ja ebenfalls mit dem oszilloskop nach messen.

    LG

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    09.08.2012
    Beiträge
    6
    hab meinen Fehler soeben selber gefunden.
    Trotzdem vielen Dank an alle

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress