My headache with PCF8583 and dsPIC30F6014A

General discussion on mikroPascal for dsPIC30/33 and PIC24.
Post Reply
Author
Message
digitstudios
Posts: 26
Joined: 31 May 2005 13:32

My headache with PCF8583 and dsPIC30F6014A

#1 Post by digitstudios » 27 Apr 2009 22:34

Hi friends, I have attached below, a small program written in
MikroPascal.
The goal is set the date and time trough rs232 Serial interface on
PCF8583 then display it on LCD.
The trouble is that when I try to set up a date on 2009, the result
after reading is 2001, on 2008 the reading is 2000 but on 2007 the
reading is 2003.
Someone could give me an idea about that, and how does it happen?
Thanks in advance

Gianluca

Code: Select all

type
  TTime = record
    year, month, day, hours, minutes, seconds : byte;
end;


var sec, min1, hr, day, mn, year : byte;
    tnum, txt : array[6] of byte;

var TimeToWrite : TTime;
    byteReceived, receivedOK : byte;



implementation


procedure SetTimeByRs232();
begin
   TimeToWrite.year    := 0;
   TimeToWrite.month   := 0;
   TimeToWrite.day     := 0;
   TimeToWrite.hours   := 0;
   TimeToWrite.minutes := 0;
   TimeToWrite.seconds := 0;

   Uart1_Init(9600);
   receivedOK := 0;

   while (receivedOK = 0) do
     begin
       Uart1_Write_Text('Please send date in DD/MM/YY format');
       Uart1_Write_Char(13);
       Uart1_Write_Char(10);

       receivedOK := 1;

       Delay_ms(100);
       while(Uart1_Data_Ready() = 1) do               // clear received junk
         Uart1_Read_Char();

       while Uart1_Data_Ready() = 0 do nop;                       // day
       byteReceived := Uart1_Read_Char-48;                             // char to num
       TimeToWrite.day := byteReceived*10;
       while Uart1_Data_Ready() = 0 do nop;
       byteReceived := Uart1_Read_Char-48;
       TimeToWrite.day := TimeToWrite.day + byteReceived;

       while Uart1_Data_Ready() = 0 do nop;
       if ( Uart1_Read_Char() <> '/') then receivedOK := 0;            // receive "/"

       while Uart1_Data_Ready() = 0 do nop;                       // month
       byteReceived := Uart1_Read_Char-48;
       TimeToWrite.month := byteReceived*10;
       while Uart1_Data_Ready() = 0 do nop;
       byteReceived := Uart1_Read_Char-48;
       TimeToWrite.month := TimeToWrite.month + byteReceived;

       while Uart1_Data_Ready() = 0 do nop;
       if ( Uart1_Read_Char() <> '/') then receivedOK := 0;            // receive "/"

       while Uart1_Data_Ready() = 0 do nop;                       // year
       byteReceived := Uart1_Read_Char-48;
       TimeToWrite.year := byteReceived*10;
       while Uart1_Data_Ready() = 0 do nop;
       byteReceived := Uart1_Read_Char-48;
       TimeToWrite.year := TimeToWrite.year + byteReceived;



       Uart1_Write_Text('Please send time in HH:MM:SS 24h format');
       Uart1_Write_Char(13);
       Uart1_Write_Char(10);

       while Uart1_Data_Ready() = 0 do nop;                       // hours
       byteReceived := Uart1_Read_Char-48;                             // char to num
       TimeToWrite.hours := byteReceived*10;
       while Uart1_Data_Ready() = 0 do nop;
       byteReceived := Uart1_Read_Char-48;
       TimeToWrite.hours := TimeToWrite.hours + byteReceived;

       while Uart1_Data_Ready() = 0 do nop;
       if ( Uart1_Read_Char() <> ':') then receivedOK := 0;            // receive "/"

       while Uart1_Data_Ready() = 0 do nop;                       // minutes
       byteReceived := Uart1_Read_Char-48;
       TimeToWrite.minutes := byteReceived*10;
       while Uart1_Data_Ready() = 0 do nop;
       byteReceived := Uart1_Read_Char-48;
       TimeToWrite.minutes := TimeToWrite.minutes + byteReceived;

       while Uart1_Data_Ready() = 0 do nop;
       if ( Uart1_Read_Char() <> ':') then receivedOK := 0;            // receive "/"

       while Uart1_Data_Ready() = 0 do nop;                       // seconds
       byteReceived := Uart1_Read_Char-48;
       TimeToWrite.seconds := byteReceived*10;
       while Uart1_Data_Ready() = 0 do nop;
       byteReceived := Uart1_Read_Char-48;
       TimeToWrite.seconds := TimeToWrite.seconds + byteReceived;

       if (receivedOK = 0) then
         begin
           Uart1_Write_Text('Receive error.');
           Uart1_Write_Char(13);
           Uart1_Write_Char(10);
         end;

     end;

           Uart1_Write_Text('Received Ok');
           Uart1_Write_Char(13);
           Uart1_Write_Char(10);
           Uart1_Write_Char((TimeToWrite.year mod 4) shl 6 + (TimeToWrite.day div 10) shl 4 +(TimeToWrite.day mod 10));
           Uart1_Write_Char(13);
           Uart1_Write_Char(10);


   I2C_Init(100000);          // initialize I2C
   I2C_Start;            // issue start signal

   I2c_Write($A0);          // address PCF8583
   I2c_Write(0);            // start from word at address 0 (configuration word)
   I2c_Write($80);          // write $80 to config. (pause counter...)
   I2c_Write(0);            // write 0 to cents word


   I2c_Write((TimeToWrite.seconds div 10) shl 4 + (TimeToWrite.seconds mod 10)); // write seconds word
   I2c_Write((TimeToWrite.minutes div 10) shl 4 + (TimeToWrite.minutes mod 10)); // write minutes word
   I2c_Write((TimeToWrite.hours div 10) shl 4 + (TimeToWrite.hours mod 10)); // write hours word
   I2c_Write((TimeToWrite.year mod 4) shl 6 + (TimeToWrite.day div 10) shl 4 +(TimeToWrite.day mod 10));
   I2c_Write((TimeToWrite.month div 10) shl 4 + (TimeToWrite.month mod 10));  // write weekday/month

   I2C_Stop;             // issue stop signal

   I2C_Start;            // issue start signal
   I2c_Write($A0);          // address PCF8530
   I2c_Write(0);            // start from word at address 0
   I2c_Write(0);            // write 0 to config word (enable counting)
   I2C_Stop;             // issue stop signal
end;




procedure Zero_Fill(var value : array[10] of byte);    // fill text repesentation
  begin
    if (value[1] = 0) then
      begin           //      with leading zero
        value[1] := value[0];
        value[0] := 48;
        value[2] := 0;
      end;
  end;
//-------------- Trims the leading spaces from array given with *pt
procedure rtrim(var src, dest : array[10] of byte);
  var i, j : word;
  begin
    i := 0;
    j := 0;
    while (src[i] = ' ') do
      inc(i);
    while (src[i] <> 0) do
      begin
        dest[j] := src[i];
        inc(i);
        inc(j);
      end;
    dest[j] := 0;
  end;
//--------------------- Reads time and date information from RTC (PCF8583)

procedure Read_Time(var sec, min, hr, day, mn : byte);
  begin
    I2C_Start();
    I2C_Write(0xA0);
    I2C_Write(2);
    I2c_Restart();
    I2C_Write(0xA1);
    sec := I2c_Read(0);
    min := I2c_Read(0);
    hr  := I2c_Read(0);
    day := I2c_Read(0);
    mn  := I2c_Read(1);
    I2C_Stop();
  end;
  

//-------------------- Formats date and time
procedure Transform_Time(var sec, min, hr, day, mn, year : byte);
  begin
    sec  :=  ((sec and 0xF0) shr 4)*10 + (sec and 0x0F);
    min  :=  ((min and 0xF0) shr 4)*10 + (min and 0x0F);
    hr   :=  ((hr and 0xF0) shr 4)*10 + (hr and 0x0F);
    year :=  (day and 0xC0) shr 6;
    day  :=  ((day and 0x30) shr 4)*10 + (day and 0x0F);
    mn   :=  ((mn and 0x10) shr 4)*10 + (mn and 0x0F);
  end;

//-------------------- Output values to LCD
procedure Display_Time( sec, min1, hr, day, mn, year : byte);
  begin
    WordToStr(word(day), tnum);
    rtrim(tnum, txt);
    Zero_Fill(txt);
    Lcd_Out(1, 6, txt);

    WordToStr(word(mn), tnum);
    rtrim(tnum, txt);
    Zero_Fill(txt);
    Lcd_Out(1,9,txt);

    WordToStr(word(year), tnum);
    rtrim(tnum, txt);
    Zero_Fill(txt);
    Lcd_Out(1,14,txt);
//    Lcd_Chr(1,15,48+year);

    WordToStr(word(hr), tnum);
    rtrim(tnum, txt);
    Zero_Fill(txt);
    Lcd_Out(2,6,txt);

    WordToStr(word(min1), tnum);
    rtrim(tnum, txt);
    Zero_Fill(txt);
    Lcd_Out(2,9,txt);

    WordToStr(word(sec), tnum);
    rtrim(tnum, txt);
    Zero_Fill(txt);
    Lcd_Out(2,12,txt);
  end;

//------------------ Performs project-wide init
procedure Init_Main();
  begin
    ADPCFG := 0xFFFF;
    TRISD  := 0;                // designate portd as output
    Lcd_Init_DsPICPro3();
    I2C_Init(100000);           // initialize I2C
    txt := 'Date:';             // prepare and output static text on LCD
    Lcd_Out(1,1,txt);
    Lcd_Chr(1,8,':');
    Lcd_Chr(1,11,':');
    txt := 'Time:';
    Lcd_Out(2,1,txt);
    Lcd_Chr(2,8,':');
    Lcd_Chr(2,11,':');
    txt := '----';
    Lcd_Out(1,12,txt);
    Lcd_Cmd(LCD_CURSOR_OFF);   // cursor off
  end;
//----------------- Main procedure


begin
  Init_Main();                                       // perform initialization
  SetTimeByRs232();
 while true do
    begin
      Read_Time(sec, min1, hr, day, mn);       // read time from RTC(PCF8583)
      Transform_Time(sec, min1, hr, day, mn, year);  // format date and time
      Display_Time(sec, min1, hr, day, mn, year);    // prepare and display on LCD
      Delay_ms(1000);                                // wait 1s
    end;
Gianluca Colombo

digitstudios
Posts: 26
Joined: 31 May 2005 13:32

Very strange!!

#2 Post by digitstudios » 28 Apr 2009 10:31

This morning I tryed to set up this value :
"31/12/07 23:59:51"
then after 10 seconds, the time displayed was "01/01/04 00:00:01"
Heeeeeeeeelp me please!!!
My Headache is worse than last night ;)
Gianluca Colombo

yo2lio
Posts: 1878
Joined: 19 Sep 2006 12:57
Location: Romania, Arad City
Contact:

#3 Post by yo2lio » 28 Apr 2009 13:11

Hello,

Read PCF8583 datasheet, you have two bits for year !
Best regards, Florin Andrei Medrea.

http://www.microelemente.ro/
http://www.microelemente.ro/produse-si-servicii/
http://www.microelemente.ro/custom-software/

mail : florin@microelemente.ro

Post Reply

Return to “mikroPascal for dsPIC30/33 and PIC24 General”