Ds1307 synchronisieren mit Dcf77

Pontius Pilatus
 
Avatar
 
Subject:

Ds1307 synchronisieren mit Dcf77

 · 
Posted: 21.11.2013 - 16:11  ·  #1
Wir haben mit ein paar Kollegen der Wordclock aus der CTHacks nachgebaut. Ürsprunglich war da DCF vorgesehen, aber wegen Störungen von Multiplex-Ledmatrix ist das weggelassen. Auf das Board ist aber ein Anschluss vorhanden und wir wollten das jetzt gerne nutzen.

Jetzt das Problem: Laut Standard-Treiber-Handbuch kann mann ein externe Uhrenchip (in diesen Fall ein DS1307) mittels ein Callback-Prozedure synchronisieren. Kann das vielleicht mal jemand genau erkären? Ich studiere seit Tagen das Handbuch, aber komme einfach nicht weiter.
Wir mochten gerne wissen wo oder was noch fehlt in der Code:

Code
program wordclock;
// Wordclock-Version für c't Wordclock-Platine (Segor-Bausatz)
// Q&D Version basiert auf WordClock für PONG, aber verbesserte Buchstaben-Kodierung
// C. Meyer 7/2013

{$NOSHADOW}
{ $WG}                     {global Warnings off}

Device = mega8, VCC=5;
{ $BOOTRST $00C00}         {Reset Jump to $00C00}

Define_Fuses
//  Override_Fuses;
  NoteBook   = A;
  COMport    = USB;
  LockBits0 = [];
  FuseBits0  = [CKSEL0, CKSEL1, CKSEL3, SUT0, BODEN];
  FuseBits1  = [];
  ProgMode   = SPI;
  ProgFuses  = true;
  ProgLock   = false;
  ProgFlash  = true;
  ProgEEprom = false;

Import SysTick, TWImaster, RTClock, TickTimer;
 Import DCFclock;

From System Import LongWord, Random;


Define
  ProcClock      = 8000000;       {Hertz}
  SysTick        = 10;             {msec}
  StackSize      = $0032, iData;
  FrameSize      = $0032, iData;
  DCFclock       = iData;
  DCFport        = PinB, 2, positive; {Port, Pin#, Polarity}
  TWIpresc       = TWI_BR100;
  TickTimer      = Timer1;
  RTClock        = iData, Time;
  RTCsource      = SysTick;
  
Implementation

{$IDATA}

{--------------------------------------------------------------}
{ Type Declarations }

type


{--------------------------------------------------------------}
{ Const Declarations }
const
  sr_on: Boolean = false;
  sr_off: Boolean = true;
  rtc_adr: byte = $68;

// Buchstaben-Pattern, 12 Bit wie angezeigt, plus Zeile im obersten Nibble
  c_es_war: word   = $0000 or %110111000000;
  c_es_ist: word   = $0000 or %110000111000;
  c_gleich: word   = $1000 or %111111000000;
  c_genau: word    = $1000 or %000000011111;
  c_gerade: word   = $2000 or %111111000000;
  c_fuenfmin: word = $2000 or %000000011110;
  c_viertel: word  = $3000 or %000011111110;
  c_dreiviertel: word  = $3000 or %111111111110;
  c_zehnmin: word  = $4000 or %111100000000;
  c_zwanzig: word  = $4000 or %000001111111;
  c_nach: word     = $5000 or %111100000000;
  c_vor: word      = $5000 or %000011100000;
  c_halb: word     = $5000 or %000000001111;
  c_drei: word     = $6000 or %111100000000;
  c_ein: word      = $6000 or %001110000000;
  c_eins: word     = $6000 or %001111000000;
  c_sieben: word   = $6000 or %000001111110;
  c_elf: word      = $7000 or %111000000000;
  c_fuenf: word    = $7000 or %001111000000;
  c_zwoelf: word   = $7000 or %000000011111;
  c_vier: word     = $8000 or %111100000000;
  c_zwei: word     = $8000 or %000011110000;
  c_acht: word     = $8000 or %000000001111;
  c_neun: word     = $9000 or %011110000000;
  c_sechs: word    = $9000 or %000000111110;
  c_zehn: word     = $A000 or %111100000000;
  c_uhr: word      = $A000 or %000001110000;
  c_vor12: word    = $A000 or %000000000111;
  c_nach12: word   = $B000 or %111100000000;
  c_nachts: word   = $B000 or %111111000000;
  c_mittag: word   = $B000 or %000000111111;

{--------------------------------------------------------------}
{ Var Declarations }
var
{$PDATA}
  SR_CLK[@PortB,5]: Bit;
  SR_DATA[@PortB,3]: Bit;
  HOURBTN[@PinB,1]: Bit;
  MINUTEBTN[@PinB,0]: Bit;
  TESTPIN[@PortB,4]: Bit;


{$DATA}
  b, i, led_row, tenmillisec: byte;
  LED_word: word;

{$IDATA}
  TickSema, Blinkenlights,
  SecondSema, MinuteSema, LEDupdateRequest: Boolean;

  LED_word_array: Array[0..11] of word;
// Einzel-Zeilen, evt. einmal gebraucht
  LED_word_line0[@LED_word_array+0]: word;
  LED_word_line1[@LED_word_array+24]: word;
  LED_word_line2[@LED_word_array+48]: word;
  LED_word_line3[@LED_word_array+72]: word;
  LED_word_line4[@LED_word_array+96]: word;
  LED_word_line5[@LED_word_array+120]: word;
  LED_word_line6[@LED_word_array+144]: word;
  LED_word_line7[@LED_word_array+168]: word;
  LED_word_line8[@LED_word_array+192]: word;
  LED_word_line9[@LED_word_array+216]: word;
  LED_word_line10[@LED_word_array+240]: word;
  LED_word_line11[@LED_word_array+264]: word;

  UpdateTimer: SysTimer8;
  BlinkTimer, LED_select,
  hour, minute: Byte;

{--------------------------------------------------------------}
{ functions }

procedure onTickTimer;
begin
  TickSema:= true;
end;

procedure RTCtickMinute;
begin
  MinuteSema:= true;
end;

procedure RTCtickSecond;
begin
  SecondSema:= true;
end;

function DS1307getSecond: byte;
var my_byte: byte;
begin
  TWIout(rtc_adr,0); // Sekunden-Register
  TWIinp(rtc_adr,my_byte);
  return(BCDtoByte(my_byte));
end;

function DS1307getMinute: byte;
var my_byte: byte;
begin
  TWIout(rtc_adr,1); // Minuten-Register
  TWIinp(rtc_adr,my_byte);
  return(BCDtoByte(my_byte));
end;

function DS1307getHour: byte;
var my_byte: byte;
begin
  TWIout(rtc_adr,2); // Stunden-Register
  TWIinp(rtc_adr,my_byte);
  return(BCDtoByte(my_byte and $3F));
end;

procedure DS1307setSecond(my_second: byte);
var my_byte: byte;
begin
  my_Byte:= ByteToBCD(my_second) and $7F; // Clock HALT Bit immer löschen
  TWIout(rtc_adr,0,my_Byte); // Sekunden-Register
end;

procedure DS1307setMinute(my_minute: byte);
var my_byte: byte;
begin
  my_Byte:= ByteToBCD(my_Minute);
  TWIout(rtc_adr,1,my_Byte); // Minuten-Register
end;

procedure DS1307setHour(my_hour: byte);
var my_byte: byte;
begin
  my_Byte:= ByteToBCD(my_hour) and 31;
  TWIout(rtc_adr,2,my_Byte); // Stunden-Register
end;

//##############################################################################

procedure InitPorts;
begin
  PortB:= %00000111;
  DDRB:=  %00111000;
  
  PortC:= %00000000;
  DDRC:=  %00001111;

  PortD:= %00000000;
  DDRD:=  %11111111;
end InitPorts;

procedure LED_out;
begin
   PortC:=hi(LED_word) and $0F;
   PortD:=lo(LED_word);
end;

procedure LED_off;
begin
   PortC:=(PortC and $F0);
   PortD:=0;
end;


procedure LED_SR_next;
begin
  LED_off;
  if not inctolim(led_row, 11) then
    led_row:= 0;
    SR_DATA:= sr_on;
    SR_CLK:= true;
    nop; nop; nop;
    SR_CLK:= false;
    SR_DATA:= sr_off;
    LED_word:= LED_word_array[0];
  else
    SR_CLK:= true;
    nop; nop; nop;
    SR_CLK:= false;
  endif;
  LED_word:= LED_word_array[led_row];
  LED_out;
end;

//##############################################################################

procedure ptn2led(my_pattern: word);
var my_idx: byte;
begin
  my_idx:= hi(my_pattern) shr 4;    // Zeilennummer im obersten Nibble
  LED_word_array[my_idx]:= LED_word_array[my_idx] or my_pattern;
end;

procedure time_to_letters(my_hour, my_minute: byte; my_adjust: boolean);
var my_div, my_mod, my_addhour: byte; my_disp_uhr: Boolean;
begin
  for i:= 0 to 11 do
    LED_word_array[i]:= 0;
  endfor;

  my_disp_uhr:= false;
  my_mod:= my_minute mod 5;
// Minute words
  my_addhour:= 0;
  my_div:= my_minute div 5;

  case my_mod of // Einzel-Minuten
    0:
        ptn2led(c_es_ist);
        ptn2led(c_genau);
        |
    1,2:
        ptn2led(c_es_war);
        ptn2led(c_gerade);
        |
    3,4:
        ptn2led(c_es_ist);
        ptn2led(c_gleich);
        inc(my_div);
        if my_minute > 57 then
          my_addhour:= 1;
        endif;
        |
  endcase;

  case my_div of   // 5-Minuten-Schritte
    0,12:
        my_disp_uhr:= true;
        |
    1:
        ptn2led(c_fuenfmin);
        ptn2led(c_nach);
        |
    2:
        ptn2led(c_zehnmin);
        ptn2led(c_nach);
        |
    3:
        ptn2led(c_viertel);
        ptn2led(c_nach);
        |
    4:
        ptn2led(c_zwanzig);
        ptn2led(c_nach);
        |
    5:
        ptn2led(c_fuenfmin);
        ptn2led(c_vor);
        ptn2led(c_halb);
        my_addhour:= 1;
        |
    6:
        ptn2led(c_halb);
        my_addhour:= 1;
        |
    7:
        ptn2led(c_fuenfmin);
        ptn2led(c_nach);
        ptn2led(c_halb);
        my_addhour:= 1;
        |
    8:
        ptn2led(c_zwanzig);
        ptn2led(c_vor);
        my_addhour:= 1;
        |
    9:
        ptn2led(c_dreiviertel);
        my_addhour:= 1;
        |
    10:
        ptn2led(c_zehnmin);
        ptn2led(c_vor);
        my_addhour:= 1;
        |
    11:
        ptn2led(c_fuenfmin);
        ptn2led(c_vor);
        my_addhour:= 1;
        |
  endcase;
  my_hour:= my_hour + my_addhour;

  case my_hour of // Stunden-Schritte
    0,12:
      ptn2led(c_zwoelf);
      |
    1,13:
      if my_disp_uhr then
        // Sonderfall ein"s"
        ptn2led(c_ein);
      else
        ptn2led(c_eins);
      endif;
      |
    2,14:
      ptn2led(c_zwei);
      |
    3,15:
      ptn2led(c_drei);
      |
    4,16:
      ptn2led(c_vier);
      |
    5,17:
      ptn2led(c_fuenf);
      |
    6,18:
      ptn2led(c_sechs);
      |
    7,19:
      ptn2led(c_sieben);
      |
    8,20:
      ptn2led(c_acht);
      |
    9,21:
      ptn2led(c_neun);
      |
    10,22:
      ptn2led(c_zehn);
      |
    11,23:
      ptn2led(c_elf);
      |
  endcase;

  if my_disp_uhr then
    ptn2led(c_uhr);
  endif;
  if my_hour < 5 then
    ptn2led(c_nachts);
  elsif my_hour > 8 then
    if my_hour < 12 then
      ptn2led(c_vor12);
      ptn2led(c_mittag);
    elsif my_hour < 19 then
      ptn2led(c_nach12);
      ptn2led(c_mittag);
    endif;
  endif;

end;

{--------------------------------------------------------------}
{ Main Program }
{$IDATA}

begin
  InitPorts;
  TickTimerTime(1000);  // Wert in us
  TickTimerStart;
  Blinkenlights:= true;
  BlinkTimer:= 20;
  
  EnableInts;
  MinuteSema:= true;
  i:= DS1307getSecond;  // First Power up, Clock HALT Bit löschen
  DS1307setSecond(i);

  loop
    if TickSema then
      TickSema:=false;
      TESTPIN:= not TESTPIN;
      LED_SR_next;
    endif;

    if MinuteSema then
      //Blinkenlights:= true;
      BlinkTimer:= 10;
      MinuteSema:= false;
      minute:= DS1307getMinute;
      hour:= DS1307getHour;
      time_to_letters(hour, minute,false);
      LEDupdateRequest:= true;
    endif;
    
    if SecondSema then
      SecondSema:= false;
      if not HOURBTN then // neg. Logik!
        inctolimwrap(hour,23,0);
        DS1307setHour(hour);
        DS1307setSecond(0);
        RTCsetHour(hour);
        RTCsetSecond(0);
        time_to_letters(hour, minute, true);
        LEDupdateRequest:= true;
        Blinkenlights:= false;
      endif;
      if not MINUTEBTN then // neg. Logik!
        if inctolimwrap(minute,59,0) then
          inctolimwrap(hour,23,0);
        endif;
        DS1307setHour(hour);
        DS1307setMinute(minute);
        DS1307setSecond(0);
        RTCsetMinute(minute);
        RTCsetSecond(0);
        time_to_letters(hour, minute, true);
        LEDupdateRequest:= true;
        Blinkenlights:= false;
      endif;
    endif;
    
    if Blinkenlights then
      if isSysTimerZero(UpdateTimer) and Blinkenlights then
        setSysTimer(UpdateTimer, lo(randomrange(5,15)));
        for i:= 0 to 11 do
          LED_word_array[i]:= (LED_word_array[i] + random) and $FFF;
        endfor;
        if not dectolim(BlinkTimer, 0) then
          Blinkenlights:= false;
          time_to_letters(hour, minute,false);
        endif;
      endif;
    endif;

  endloop;
end wordclock.



Wir wären für jede Hilfe dankbar.
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: Ds1307 synchronisieren mit Dcf77

 · 
Posted: 25.11.2013 - 13:49  ·  #2
Hallo,

wenn die DCF eine Uhrzeit/Datum zur Verfügung stellt dann können diese Daten
dazu benutzt werden um den Uhrenchip neu zu stellen. Das reicht einmal am Tag.

rolf
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   50   64 · Page-Gen-Time: 0.03541s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI