DS1302 nur alle 2s gültiges Signal?

Gast #2061246
Lesenswert?

Hallo zusammen,

ich habe keine Ideen mehr. Vielleicht könnt ihr mir helfen? Ich möchte 
einfach nur mit einem Mega32 die Sekunden aus dem DS1302 auslesen. Das 
gelingt mir allerdings nur alle 2s korrekt. Was mache ich falsch? Bin 
dankbar für jede Antwort!

Gruß

enhape

Anbei der Code, gefolgt von der ds1302.h (dankend aus dem Forum bezogen)

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

#include "ds1302.h"


#ifndef F_CPU
#define F_CPU 1000000
#endif




// Prototypen
uint8_t Read_DS1302(uint8_t);




int main()
{

  //Ports initialisieren:
    DDRC = 0xFF; // Port C auf Ausgang

  uint8_t temp2;


  //RTC initialisieren
   RTC_Init();


    while (1)
    {
    _delay_ms(1);
    temp2 = Read_DS1302(0x81);
    PORTC = ~temp2;
  }
}


//**************************************
// Write
//**************************************
void Write( char cmd )
{

  uint8_t n;

  RTC_DATA_LINE_IS_OUTPUT();
  _delay_ms(1);
  for (n = 0; n < 8; n++)
  {
    if (CheckBit(cmd,n))
    {
    RTC_DATA_HIGH();
    }
  else
  {
      RTC_DATA_LOW();
    }
  _delay_ms(1);
  RTC_CLK_HIGH();
    _delay_ms(1);
  RTC_CLK_LOW();
  _delay_ms(1);
  }
  RTC_DATA_LINE_IS_INPUT();
}

//**************************************
// Write_DS1302
//**************************************
void Write_DS1302( uint8_t cmd, uint8_t data )
{
  RTC_RESET_HIGH();
  Write(cmd);
  Write(data);
  RTC_RESET_LOW();
}

//***************************************
// Read
//***************************************
uint8_t Read( void )
{

   uint8_t n, d, data;
   data = 0x00;


   for(n = 0; n < 8; n++)
   {
     d = CHECK_RTC_DATA();
     data = (data >> 1);
     if (d)
   {
       data |= 0x80;
   }
   _delay_ms(1);
     RTC_CLK_HIGH();
     _delay_ms(1);
     RTC_CLK_LOW();
     _delay_ms(1);
   }
   return data;
}

//***************************************
// Read_DS1302
//***************************************
uint8_t Read_DS1302(uint8_t cmd)
{
  uint8_t data;
  RTC_RESET_HIGH();
  _delay_ms(1);
  Write(cmd);
  _delay_ms(1);
  data = Read();
  _delay_ms(1);;
  RTC_RESET_LOW();
  _delay_ms(1);;
  return data;
}




//*************************
// RTC_Init         (called from Main-Init)
//*************************
void RTC_Init(void )
{ uint8_t data;

  RTC_RESET_LOW();

  RTC_DATA_LINE_IS_INPUT();
  NOP();
  NOP();
  RTC_CLK_LOW();
  NOP();
  NOP();

  Write_DS1302(CONTROL_REGISTER, UNPROTECT);
  data = Read_DS1302( 0x81);
  if (CheckBit(data,7))               // if bit 7 is high, Clock is 
stopped
  {  Write_DS1302( 0x80, 0x00);
  }
  Write_DS1302(CONTROL_REGISTER, PROTECT);

}



////////////////////////////////////////////////////////////////////////
//ds1302.h:


#ifndef  _RTC_H
#define  _RTC_H 1

#define BYTE  unsigned char
#define TRUE                 (BYTE)1
#define FALSE                (BYTE)0
#define NOP()      asm("nop")

#define SetBit(ADRESS,B)         ((ADRESS) |=  (1<<(B)))
#define ClearBit(ADRESS,B)       ((ADRESS) &= ~(1<<(B)))
#define CheckBit(ADRESS,B)       (BYTE)((ADRESS) &   (1<<(B)))
#define ToggleBit(ADDRESS,BIT)   ((ADDRESS) ^= (1<<BIT))

//=================================================
// je nachdem, an welchem Port DS1302 haengt,
// muessen diese Werte angepasst werden
#define RTC_CLK             0
#define RTC_DATA            1
#define RTC_RES             2

#define RTC_CLK_LOW()             ClearBit(PORTA,RTC_CLK)
#define RTC_CLK_HIGH()            SetBit(PORTA,RTC_CLK)
#define RTC_DATA_LOW()            ClearBit(PORTA,RTC_DATA)
#define RTC_DATA_HIGH()           SetBit(PORTA,RTC_DATA)
#define CHECK_RTC_DATA()          CheckBit(PINA,RTC_DATA)
#define RTC_RESET_LOW()           ClearBit(PORTA,RTC_RES)
#define RTC_RESET_HIGH()          SetBit(PORTA,RTC_RES)
#define RTC_DATA_LINE_IS_OUTPUT() SetBit(DDRA,   RTC_DATA)
#define RTC_DATA_LINE_IS_INPUT()  ClearBit(DDRA, RTC_DATA)
// Ende der Anpassung
//=================================================

#define RTC_RAM   1
#define RTC_CLOCK 0

#define RTC_SEC   0
#define RTC_MIN   1
#define RTC_HRS   2
#define RTC_DAY   3
#define RTC_MONTH 4
#define RTC_DOW   5          // day of week (1 = Mon)
#define RTC_YEAR  6


#define CONTROL_REGISTER 0x8E
#define PROTECT   0x80
#define UNPROTECT 0x00

void RTC_Init(void );
void RTC_SetTime( void );
void RTC_GetTime( void );
void RTC_Unprotect( void );
void RTC_Protect( void );
BYTE RTC_Ctrl( void );
#endif
#2061325
Lesenswert?

Kleiner Tipp:

"Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang"

Das könnte unter Umständen zu besseren Antworten führen. Ein 
hochgeladener Quelltext kann auch mit Syntax-Hervorhebung angezeigt 
werden.

Zu kontruktiven Behebung des Problems kann ich dir aber aufgrund meiner 
Unkenntnis des DS1302 leider keine weitere Auskunft geben. - Ein 
RTC-Chip steht aber schon fast ganz oben auf meiner "To-Learn"-Liste ;)

Gruß, Marcel
Gast #2061373
Lesenswert?

Hallo Sascha, hallo Marcel,

danke für die Antworten,

habe gedacht, wenn Code gleich mit im Text steht wäre es 
"verführerischer" ihn anzuschauen...

zum 2 Sekunden-Problem. Der µController schickt an den DS1302 den 
Steuerbefehl 0x81. Ohne Burst-Mode. Ich wollte klein anfangen und erst 
einmal nur die Sekunden auslesen. Als Ausgabe dienen 8 Dioden an Port C. 
Egal, ob ich 300ms zw. den Abfragen warte oder nur 30, ich bekomme immer 
nur ein "sinnvolles" Ergebnis in den Sekunden 1, 3, 5, 7 usw. In den 
dazwischen liegenden Zeiten bekomme ich kein Ergebnis. Habe keine Ahnung 
was das sein kann.

Sascha, vielleicht kannst du mir ein Code-Beispiel von dir zusenden, 
welches bei dir 100%ig funktioniert?

viele Grüße
enhape
Gast #2061503
Lesenswert?

Hallo Sascha,

danke für den code. In Assembler habe ich leider überhaupt keine Ahnung.


Hat jemand eventuell ein funktionierendes Beispiel in c? Oder konnte 
jemand einen ähnlichen "2s-Effekt" beobachten? Bin über jede Antwort 
äußerst dankbar.

viele Grüße
enhape

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren