CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

problem with sleep and wake up PIC16F876A

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
HGHK



Joined: 29 Jun 2010
Posts: 33

View user's profile Send private message Yahoo Messenger

problem with sleep and wake up PIC16F876A
PostPosted: Wed Oct 13, 2010 3:38 pm     Reply with quote

I use PIC16F876A and PCF8563 for RTC. PCF8563 make an external interrupt for alarm. For testing I connect a LED to RA3 by resistor to indicate state of test program. It must be turn on 3 time to sleep but it turn 6 or 7 time after any reset. I use ccs pcwhd compiler ver. 4.084.
I send source here. Please help me!
debug.c:
Code:
#include "C:\Documents and Settings\HGhK\Desktop\CRP\temp project\debprg.h"
#include "C:\Documents and Settings\HGhK\Desktop\CRP\temp project\PCF8583.c"

// command set definition

#define Test_Temperature             0x00
#define Read_Temperature_Limits      0x01
#define Set_Temperature_Limits       0x03
#define Read_Time_And_Report         0x07
#define Set_Time_from_Recive         0x0F
#define Read_Sleep_Period            0x1F
#define Set_Sleep_Period             0x3F
#define Reset_Temp_counter           0x7F
#define Controler_Connected          0xFF
#define Report_Temp_counter          0xFE

// -------------------------------------------------
//  EEPROM Data Address

#define Temperature_In_Reng_Count    0x01
#define Hi_Temperature_Limit         0x04
#define Lo_Temperature_Limit         0x06
#define Period_Time_reg              0x09


#define Time_Period_defult           2

// -------------------------------------------------

date_time_t   Time,*t;
PCF8563_Alarm AlarmTime,*ALT;
float         Temprature;
int8          counter=0,command=0x00,Time_Period=Time_Period_defult;
signed int8   Lo_limit_Temp,Hi_limit_Temp;
int8 cnt;

#int_EXT
void  EXT_isr(void)
{
command = Test_Temperature;
}

// #include "C:\Documents and Settings\HGhK\Desktop\CRP\temp project\functions.c"

void main()
{

   Time=&t;
   AlarmTime=&ALT;
   enable_interrupts(INT_EXT);ext_int_edge(H_TO_L);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   disable_interrupts(INT_RB);
   enable_interrupts(INT_EXT);ext_int_edge(H_TO_L);
   disable_interrupts(INT_AD);
   disable_interrupts(INT_TBE);
   disable_interrupts(INT_RDA);
   disable_interrupts(INT_SSP);
   disable_interrupts(INT_EEPROM);
   enable_interrupts(GLOBAL);
   // TODO: USER CODE!!

   PCF8563_init();
   Time.day      = 1;
   Time.hours    = 1;
   Time.minutes  = 1;
   Time.month    = 1;
   Time.seconds  = 1;
   Time.weekday  = 1;
   Time.year     = 1;
PCF8563_set_datetime(*t);
   set_tris_a (0x01);
   output_high(PIN_A3);         // *
   delay_ms( 1000 );
   output_low(PIN_A3);
   delay_ms( 1000 );
 while(1){


PCF8563_read_datetime(*t);
output_high(PIN_A3);         // *
delay_ms( 1000 );

Time.minutes  =  Time.minutes + Time_Period_defult;
if ( Time.minutes > 59 ){ Time.hours++;Time.minutes=Time.minutes-60;}
if ( Time.hours > 23 ){ Time.hours = Time.hours - 24 ;  }
AlarmTime.minutes = Time.minutes ;
AlarmTime.hours   = Time.hours   ;
Set_Alarm(PCF8563_MH_Mode,ALT);
config_PCF8563_Interrupt(Alarm_Interrupt_Enable,Timer_INT_Pulse_off);
enable_interrupts(GLOBAL);
output_low(PIN_A3);
delay_ms( 10 );
output_high(PIN_A3);         // *
delay_ms( 1000 );
output_low(PIN_A3);
delay_ms( 1000 );
enable_interrupts(GLOBAL);
sleep();
output_high(PIN_A3);         // *
delay_ms( 10 );
output_low(PIN_A3);

          }
}


debug.h:
Code:
#include <16F876A.h>
#device ICD=TRUE
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES LP                       //Low power osc < 200 khz
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES DEBUG                    //Debug mode for use with ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=32768)
#use rs232(baud=256,parity=O,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Slow=100000,sda=PIN_C4,scl=PIN_C3,force_hw)

pcf8563:

Code:
// PCF8563.C
// Command Set:
// PCF8563_init(void)
// PCF8563_write_byte(int8 address, int8 data)
// PCF8563_read_byte(int8 address)
// bin2bcd(int8 value)
// bcd2bin(char bcd_value)
// PCF8563_set_datetime(date_time_t *dt)
// PCF8563_read_datetime(date_time_t *dt)
// Set_Alarm(int8 AMode,PCF8563_Alarm *AT)
// config_CLKOUT()
// config_PCF8563_Timer()
// config_PCF8563_Interrupt()


#ifndef PCF8563_SDA
#define PCF8563_SDA  PIN_C4
#define PCF8563_SCL  PIN_C3
#endif

#use i2c(master, sda=PCF8563_SDA, scl=PCF8563_SCL)

#ifndef PCF8563_WRITE_ADDRESS
#define PCF8563_WRITE_ADDRESS 0xA2
#define PCF8563_READ_ADDRESS  0xA3
#endif

// Register addresses
#define PCF8563_CTRL_STATUS_REG1   0x00
#define PCF8563_CTRL_STATUS_REG2   0x01
#define PCF8563_SECONDS_REG        0x02
#define PCF8563_MINUTES_REG        0x03
#define PCF8563_HOURS_REG          0x04
#define PCF8563_DAY_REG            0x05
#define PCF8563_WEEK_REG           0x06
#define PCF8563_MONTH_REG          0x07
#define PCF8563_YEAR_REG           0x08
#define PCF8563_ALARM_MINS_REG     0x09
#define PCF8563_ALARM_HOURS_REG    0x0A
#define PCF8563_ALARM_DAY_REG      0x0B
#define PCF8563_ALARM_WEEKDAY_REG  0x0C
#define PCF8563_CTRL_CLKOUT_REG    0x0D
#define PCF8563_CTRL_TIMER_REG     0x0E
#define PCF8563_TIMER_REG          0x0F


int8 CTRL_STATUS_REG1,CTRL_STATUS_REG2,LV_sec,MINUTES_REG;
int8 HOURS_REG,DAY_REG,WEEK_REG,C_Mon,YEAR_REG;
int8 CTRL_TIMER_REG,TIMER_REG,CTRL_CLKOUT_REG;

#bit LowVoltage = LV_sec.7
#bit Century = C_Mon.7

   
#define  bcd_min   MINUTES_REG
#define  bcd_hrs   HOURS_REG
#define  bcd_day   DAY_REG
#define  bcd_yer   YEAR_REG
#define  wek       WEEK_REG



// Commands for the Control/Status register.
#define PCF8563_START_COUNTING     0x08
#define PCF8563_STOP_COUNTING      0x28


//*************************************  for Set_Alarm()
#define PCF8563_Alarm_off          0x00
#define PCF8563_M_Mode             0x01
#define PCF8563_MH_Mode            0x04
#define PCF8563_MHW_Mode           0x07
#define PCF8563_MHD_Mode           0x0B 

//*************************************  for config_CLKOUT()
#define PCF8563_CLKOUT_off         0x00
#define PCF8563_CLKOUT_32KHz       0x80
#define PCF8563_CLKOUT_1KHz        0x81
#define PCF8563_CLKOUT_32Hz        0x82
#define PCF8563_CLKOUT_1Hz         0x83

//*************************************  for config_PCF8563_Timer()
#define PCF8563_Timer_off          0x00
#define PCF8563_Timer_4KHz         0x80
#define PCF8563_Timer_64Hz         0x81
#define PCF8563_Timer_1Hz          0x82
#define PCF8563_Timer_1_60Hz       0x83

//*************************************  for config_PCF8563_Interrupt()
#define Alarm_Interrupt_Enable     0x01
#define Timer_Interrupt_Enable     0x02
#define A_T_Interrupt_Enable       0x03
#define Timer_INT_Pulse_on         0x10
#define Timer_INT_Pulse_off        0x00

char const weekday_names[7][10] =
{
{"Sunday"},
{"Monday"},
{"Tuesday"},
{"Wednesday"},
{"Thursday"},
{"Friday"},
{"Saturday"}
};   
               
// This structure defines the user's date and time data.
// The values are stored as unsigned integers.  The user
// should declare a structure of this type in the application
// program. Then the address of the structure should be
// passed to the PCF8563 read/write functions in this
// driver, whenever you want to talk to the chip.
typedef struct
{
int8 seconds;    // 0 to 59
int8 minutes;    // 0 to 59
int8 hours;      // 0 to 23  (24-hour time)
int8 day;        // 1 to 31
int8 weekday;    // 0 = Sunday, 1 = Monday, etc.
int8 month;      // 1 to 12
int8 year;       // 00 to 99
}date_time_t;

typedef struct
{
int8 minutes;    // 0 to 59
int8 hours;      // 0 to 23  (24-hour time)
int8 day;        // 1 to 31
int8 weekday;    // 0 = Sunday, 1 = Monday, etc.
}PCF8563_Alarm;


//----------------------------------------------
void PCF8563_write_byte(int8 address, int8 data)
{
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8563_WRITE_ADDRESS);
i2c_write(address);
i2c_write(data);
i2c_stop();
enable_interrupts(GLOBAL);
}   

//----------------------------------------------
int8 PCF8563_read_byte(int8 address)
{
int8 retval;
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8563_WRITE_ADDRESS);
i2c_write(address);
i2c_start();
i2c_write(PCF8563_READ_ADDRESS);
retval = i2c_read(0);
i2c_stop();
enable_interrupts(GLOBAL);
return(retval);
}   

//----------------------------------------------
//           PCF8563 Initial             // //

void PCF8563_init(void)
{
PCF8563_write_byte(PCF8563_CTRL_STATUS_REG1,PCF8563_START_COUNTING);
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8563_READ_ADDRESS);
CTRL_STATUS_REG1 = i2c_read();
CTRL_STATUS_REG2 = i2c_read();
LV_sec           = i2c_read();
MINUTES_REG      = i2c_read();
HOURS_REG        = i2c_read();
DAY_REG          = i2c_read();
WEEK_REG         = i2c_read();
C_Mon            = i2c_read();
YEAR_REG         = i2c_read();
                   i2c_read();
                   i2c_read();
                   i2c_read();
                   i2c_read();
CTRL_CLKOUT_REG  = i2c_read();
CTRL_TIMER_REG   = i2c_read();
TIMER_REG        = i2c_read(0);
i2c_stop();
enable_interrupts(GLOBAL);
}   

//----------------------------------------------
// This function converts an 8 bit binary value
// to an 8 bit BCD value.
// The input range must be from 0 to 99.

int8 bin2bcd(int8 value)
{
char retval;

retval = 0;

while(1)
  {
   // Get the tens digit by doing multiple subtraction
   // of 10 from the binary value.
   if(value >= 10)
     {
      value -= 10;
      retval += 0x10;
     }
   else // Get the ones digit by adding the remainder.
     {
      retval += value;
      break;
     }
   }

return(retval);
}

//----------------------------------------------
// This function converts an 8 bit BCD value to
// an 8 bit binary value.
// The input range must be from 00 to 99.

char bcd2bin(char bcd_value)
{
char temp;

temp = bcd_value;

// Shifting the upper digit right by 1 is
// the same as multiplying it by 8.
temp >>= 1;

// Isolate the bits for the upper digit.
temp &= 0x78;

// Now return: (Tens * 8) + (Tens * 2) + Ones
return(temp + (temp >> 2) + (bcd_value & 0x0f));

}
//----------------------------------------------
//----------------------------------------------

void PCF8563_set_datetime(date_time_t *dt)
{

int8 bcd_sec;
int8 bcd_mon;

// Convert the input date/time into BCD values
// that are formatted for the PCF8563 registers.
 
bcd_sec = bin2bcd(dt->seconds);
bcd_min = bin2bcd(dt->minutes);
bcd_hrs = bin2bcd(dt->hours);   
bcd_day = bin2bcd(dt->day) | (dt->year << 6);
bcd_mon = bin2bcd(dt->month) | (dt->weekday << 5);
bcd_yer = bin2bcd(dt->year);
wek     = dt->weekday;
// Stop the RTC from counting, before we write to
// the date and time registers.
PCF8563_write_byte(PCF8563_CTRL_STATUS_REG1,PCF8563_STOP_COUNTING);

// Write to the date and time registers.  Disable interrupts
// so they can't disrupt the i2c operations.
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8563_WRITE_ADDRESS);
i2c_write(PCF8563_SECONDS_REG);   // Start at seconds reg.   
i2c_write(bcd_sec);
i2c_write(bcd_min);
i2c_write(bcd_hrs);   
i2c_write(bcd_day);
i2c_write(wek);
i2c_write(bcd_mon);
i2c_write(bcd_yer);
i2c_stop();
enable_interrupts(GLOBAL);

// Now allow the PCF8563 to start counting again.

PCF8563_write_byte(PCF8563_CTRL_STATUS_REG1,PCF8563_START_COUNTING);

}
//----------------------------------------------

//----------------------------------------------
// Read the Date and Time from the hardware registers
// in the PCF8563.   We don't have to disable counting
// during read operations, because according to the data
// sheet, if any of the lower registers (1 to 7) is read,
// all of them are loaded into "capture" registers.
// All further reading within that cycle is done from
// those registers.

void PCF8563_read_datetime(date_time_t *dt)
{
int8 bcd_sec;
int8 bcd_min;
int8 bcd_hrs;
int8 bcd_day;
int8 wek;
int8 bcd_mon;
int8 bcd_yer;

//  LowVoltage = VL_sec.7
//  Century    = C_Mon.7

// Disable interrupts so the i2c process is not disrupted.
disable_interrupts(GLOBAL);

// Read the date/time registers inside the PCF8563.
i2c_start();
i2c_write(PCF8563_WRITE_ADDRESS);
i2c_write(PCF8563_SECONDS_REG);   // Start at seconds reg.
i2c_start();
i2c_write(PCF8563_READ_ADDRESS);

LV_sec  = i2c_read();     
bcd_min = i2c_read();     
bcd_hrs = i2c_read();
bcd_day = i2c_read();
wek     = i2c_read();
C_Mon   = i2c_read();
bcd_yer = i2c_read(0);

i2c_stop();

enable_interrupts(GLOBAL);

// Convert the date/time values from BCD to
// unsigned 8-bit integers.  Unpack the bits
// in the PCF8563 registers where required.
bcd_sec     = LV_sec & 0x7F;
bcd_mon     = C_Mon  & 0x7F;
dt->seconds = bcd2bin(bcd_sec);     
dt->minutes = bcd2bin(bcd_min);     
dt->hours   = bcd2bin(bcd_hrs & 0x3F);
dt->day     = bcd2bin(bcd_day & 0x3F);
dt->month   = bcd2bin(bcd_mon & 0x1F);
dt->weekday =    wek & 0x07;
dt->year    = bcd2bin(bcd_yer);   

}
//----------------------------------------------
void Set_Alarm(int8 AMode)
{
if (AMode == 0x00)
   {
    disable_interrupts(GLOBAL);
    i2c_start();
    i2c_write(PCF8563_WRITE_ADDRESS);
    i2c_write(PCF8563_ALARM_MINS_REG);   // Start at alarm min reg.   
    i2c_write(0x80);
    i2c_write(0x80);
    i2c_write(0x80);   
    i2c_write(0x80);
    i2c_stop();
    enable_interrupts(GLOBAL);
   }
}
void Set_Alarm(int8 AMode,PCF8563_Alarm *AT)
{
int8 min = 0x80;
int8 hrs = 0x80;
int8 day = 0x80;
int8 wek = 0x80;
 
switch (AMode){
          case 0x01: min = bin2bcd(AT->minutes);
                     break;
          case 0x04: min = bin2bcd(AT->minutes);
                     hrs = bin2bcd(AT->hours);
                     break;
          case 0x07: min = bin2bcd(AT->minutes);
                     hrs = bin2bcd(AT->hours);
                     wek = AT->weekday;
                     break;
          case 0x0B: min = bin2bcd(AT->minutes);
                     hrs = bin2bcd(AT->hours);
                     day = bin2bcd(AT->day);
                     break;
               }

disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8563_WRITE_ADDRESS);
i2c_write(PCF8563_ALARM_MINS_REG);   // Start at alarm min reg.   
i2c_write(min);
i2c_write(hrs);
i2c_write(day);   
i2c_write(wek);
i2c_stop();
enable_interrupts(GLOBAL);

}

//----------------------------------------------

void config_CLKOUT(int8 mode)
{
PCF8563_write_byte(PCF8563_CTRL_CLKOUT_REG, mode);
}

//----------------------------------------------

void config_PCF8563_Timer(int8 mode)
{
PCF8563_write_byte(PCF8563_CTRL_TIMER_REG, mode);
}

//----------------------------------------------

void config_PCF8563_Interrupt(int8 mode,ti_tp)
{
mode = mode | ti_tp;
PCF8563_write_byte(PCF8563_CTRL_STATUS_REG2, mode);
}

//----------------------------------------------
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Oct 14, 2010 1:24 pm     Reply with quote

Quote:

void main()
{

Time=&t;
AlarmTime=&ALT;

These two lines are the opposite of what you want. You created an
instance of a structure. You also created a pointer to the structure.
You should initialize the pointer so it points to the structure. But you're
doing the opposite of that above (in both lines).

Quote:
#use delay(clock=32768)
#use i2c(Master,Slow=100000,sda=PIN_C4,scl=PIN_C3,force_hw)

This part here is incredibly wishful thinking. If your PIC's oscillator is
only 32.768 KHz, how can your hardware i2c baud rate generator
(which runs from Fosc/4 = 8192 Hz) ever be 100 KHz ?


Quote:
#FUSES LVP

Are you using a Low Voltage programmer ? These are only available
as home-built hobby projects, such as the TLVP programmer.
99.9 % of all PIC users don't use LVP mode. They use ICD2, PicStart-
Plus, ICD-U40, PicKit 2 or 3, etc. All of these are High Voltage
programmers. They require NOLVP as the fuse.

Quote:
// PCF8563.C
#ifndef PCF8563_SDA
#define PCF8563_SDA PIN_C4
#define PCF8563_SCL PIN_C3
#endif

#use i2c(master, sda=PCF8563_SDA, scl=PCF8563_SCL)

Here you have a 2nd instance of #use i2c(), at the top of the pcf8563
driver file. This line (not the first one with Force_hw) is actually used for
the pcf8583.c file. In CCS, the latest #use i2c() statement in the file
is in control, and all lines in the file that come after it will be compiled for
the parameters given in that #use i2c() line.
HGHK



Joined: 29 Jun 2010
Posts: 33

View user's profile Send private message Yahoo Messenger

I2C in Lower speed than standard
PostPosted: Sat Oct 16, 2010 5:06 am     Reply with quote

Dear PCM programmer, thanks for your attention.Smile

Now, do you know, can I use I2C in 8192Hz speed? and if it possible I must set SSPADD as 00H. How can I do it? How can write to this register?
Is it true if I write :
Code:
#use i2c(Master,Slow=8190,sda=PIN_C4,scl=PIN_C3,force_hw)

I Use ICD2 for programming. but it can't run in debug mode and failed, help me please.
For that pointer I must write:
Code:

*t=Time;
*ALT=AlarmTime;

is it true?
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

Re: I2C in Lower speed than standard
PostPosted: Sat Oct 16, 2010 7:57 am     Reply with quote

HGHK wrote:
Dear PCM programmer, thanks for your attention.Smile

Now,do you know, can I use I2C in 8192Hz speed? and if it possible I must set SSPADD as 00H. how can I do it? How can write to this register?
Is it true if I write :
Code:
#use i2c(Master,Slow=8190,sda=PIN_C4,scl=PIN_C3,force_hw)



The SSPADD is only useful in SLAVE mode. Not master.
(EDIT: Allow me to better qualify that "usefullness" concept in master mode. In Master mode, the SSPADD holds the I2C bit rate, so unless you're fiddling with it regularly, there's no reason to be editing it in master mode. I have an app that changes the speed of the CPU around, so I need to adjust any speeds based off Fosc. Unless you're doing that, SSPADD is sort of set once and forget in Master mode. At least in my experience. The datasheet says:

SSPADD register holds the slave device address when
the SSP is configured in I2C Slave mode. When the
SSP is configured in Master mode, the lower seven bits
of SSPADD act as the Baud Rate Generator reload
value.
)

Is your PIC supposed to be a slave or master I2C device?

Quote:

I Use ICD2 for programming. but it can't run in debug mode and failed


Then something else is wrong. change LVP to NOLVP and post your ICSP circuit for us.
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Oct 16, 2010 4:09 pm     Reply with quote

To see the value that the compiler is loading into the SSPADD register,
go to the Project / Build Options menu in MPLAB. Then go to the tab for
the CCS compiler. Then in the List File section, select "Symbolic Format".
Now re-compile the program and look at the .LST file. It's in the project
directory after you successfully compile the program. Look for the
line where the SSPADD register is loaded.

If it's loading a number into SSPADD, the number will be "xx" (in hex)
and the code will look like this:
Code:
MOVLW xx
MOVWF SSPADD

or if it's setting the SSPADD register to 0x00, the code will look like this:
Code:

CLRF SSPADD
HGHK



Joined: 29 Jun 2010
Posts: 33

View user's profile Send private message Yahoo Messenger

correction aplied but not worked
PostPosted: Sat Oct 16, 2010 4:25 pm     Reply with quote

I correct my program as :
test1.c:
Code:
#include "C:\Documents and Settings\HGhK\Desktop\CRP\temp project\test1.h"
#include "C:\Documents and Settings\HGhK\Desktop\CRP\temp project\PCF8583.c"
#define Time_Period_defult           2

date_time_t   Time,*t;
PCF8563_Alarm AlarmTime,*ALT;
int8 SSPADD,counter=0,command=0x00,Time_Period=Time_Period_defult;
#locate SSPADD=0x93
#int_EXT
void  EXT_isr(void)
{

}
void main()
{
   SSPADD=0x00;
   t=&Time;
   ALT=&AlarmTime;
   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_EXT);ext_int_edge(H_TO_L);
   enable_interrupts(GLOBAL);
   set_tris_a (0x08);
   PCF8563_init();
   Time.day      = 1;
   Time.hours    = 1;
   Time.minutes  = 1;
   Time.month    = 1;
   Time.seconds  = 1;
   Time.weekday  = 1;
   Time.year     = 1;
   PCF8563_set_datetime(*t);
   output_high(PIN_A3);         // *
   delay_ms( 1000 );
   output_low(PIN_A3);
   delay_ms( 1000 );
while(1){
   PCF8563_read_datetime(*t);
   Time.minutes  =  Time.minutes + Time_Period_defult;
   Set_Alarm(PCF8563_M_Mode,*ALT);
   config_PCF8563_Interrupt(Alarm_Interrupt_Enable,Timer_INT_Pulse_off);
   enable_interrupts(GLOBAL);
   output_high(PIN_A3);         // *
   delay_ms( 1000 );
   output_low(PIN_A3);
   delay_ms( 1000 );
sleep();
   delay_ms( 200 );
   config_PCF8563_Interrupt(Alarm_Interrupt_Enable,Timer_INT_Pulse_off);
   clear_interrupt(INT_EXT);
       }
}

and test1.h:
Code:
#include <16F876A.h>
#device ICD=TRUE
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES LP                       //Low power osc < 200 khz
#FUSES NOPUT                    //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES DEBUG                    //Debug mode for use with ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=32768)
#define I2C_SCL   PIN_C3
#define I2C_SDA   PIN_C4
#use rs232(baud=256,parity=O,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Slow=8192,sda=PIN_C4,scl=PIN_C3,force_hw)

and PCF8563.c :
Code:
#ifndef PCF8563_WRITE_ADDRESS
#define PCF8563_WRITE_ADDRESS 0xA2
#define PCF8563_READ_ADDRESS  0xA3
#endif

// Register addresses
#define PCF8563_CTRL_STATUS_REG1   0x00
#define PCF8563_CTRL_STATUS_REG2   0x01
#define PCF8563_SECONDS_REG        0x02
#define PCF8563_MINUTES_REG        0x03
#define PCF8563_HOURS_REG          0x04
#define PCF8563_DAY_REG            0x05
#define PCF8563_WEEK_REG           0x06
#define PCF8563_MONTH_REG          0x07
#define PCF8563_YEAR_REG           0x08
#define PCF8563_ALARM_MINS_REG     0x09
#define PCF8563_ALARM_HOURS_REG    0x0A
#define PCF8563_ALARM_DAY_REG      0x0B
#define PCF8563_ALARM_WEEKDAY_REG  0x0C
#define PCF8563_CTRL_CLKOUT_REG    0x0D
#define PCF8563_CTRL_TIMER_REG     0x0E
#define PCF8563_TIMER_REG          0x0F


int8 CTRL_STATUS_REG1,CTRL_STATUS_REG2,LV_sec,MINUTES_REG;
int8 HOURS_REG,DAY_REG,WEEK_REG,C_Mon,YEAR_REG;
int8 CTRL_TIMER_REG,TIMER_REG,CTRL_CLKOUT_REG;

#bit LowVoltage = LV_sec.7
#bit Century = C_Mon.7

   
#define  bcd_min   MINUTES_REG
#define  bcd_hrs   HOURS_REG
#define  bcd_day   DAY_REG
#define  bcd_yer   YEAR_REG
#define  wek       WEEK_REG



// Commands for the Control/Status register.
#define PCF8563_START_COUNTING     0x08
#define PCF8563_STOP_COUNTING      0x28


//*************************************  for Set_Alarm()
#define PCF8563_Alarm_off          0x00
#define PCF8563_M_Mode             0x01
#define PCF8563_MH_Mode            0x04
#define PCF8563_MHW_Mode           0x07
#define PCF8563_MHD_Mode           0x0B 

//*************************************  for config_CLKOUT()
#define PCF8563_CLKOUT_off         0x00
#define PCF8563_CLKOUT_32KHz       0x80
#define PCF8563_CLKOUT_1KHz        0x81
#define PCF8563_CLKOUT_32Hz        0x82
#define PCF8563_CLKOUT_1Hz         0x83

//*************************************  for config_PCF8563_Timer()
#define PCF8563_Timer_off          0x00
#define PCF8563_Timer_4KHz         0x80
#define PCF8563_Timer_64Hz         0x81
#define PCF8563_Timer_1Hz          0x82
#define PCF8563_Timer_1_60Hz       0x83

//*************************************  for config_PCF8563_Interrupt()
#define Alarm_Interrupt_Enable     0x01
#define Timer_Interrupt_Enable     0x02
#define A_T_Interrupt_Enable       0x03
#define Timer_INT_Pulse_on         0x10
#define Timer_INT_Pulse_off        0x00

char const weekday_names[7][10] =
{
{"Sunday"},
{"Monday"},
{"Tuesday"},
{"Wednesday"},
{"Thursday"},
{"Friday"},
{"Saturday"}
};   
               
// This structure defines the user's date and time data.
// The values are stored as unsigned integers.  The user
// should declare a structure of this type in the application
// program. Then the address of the structure should be
// passed to the PCF8563 read/write functions in this
// driver, whenever you want to talk to the chip.
typedef struct
{
int8 seconds;    // 0 to 59
int8 minutes;    // 0 to 59
int8 hours;      // 0 to 23  (24-hour time)
int8 day;        // 1 to 31
int8 weekday;    // 0 = Sunday, 1 = Monday, etc.
int8 month;      // 1 to 12
int8 year;       // 00 to 99
}date_time_t;

typedef struct
{
int8 minutes;    // 0 to 59
int8 hours;      // 0 to 23  (24-hour time)
int8 day;        // 1 to 31
int8 weekday;    // 0 = Sunday, 1 = Monday, etc.
}PCF8563_Alarm;


//----------------------------------------------
void PCF8563_write_byte(int8 address, int8 data)
{
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8563_WRITE_ADDRESS);
i2c_write(address);
i2c_write(data);
i2c_stop();
enable_interrupts(GLOBAL);
}   

//----------------------------------------------
int8 PCF8563_read_byte(int8 address)
{
int8 retval;
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8563_WRITE_ADDRESS);
i2c_write(address);
i2c_start();
i2c_write(PCF8563_READ_ADDRESS);
retval = i2c_read(0);
i2c_stop();
enable_interrupts(GLOBAL);
return(retval);
}   

//----------------------------------------------
//           PCF8563 Initial             // //

void PCF8563_init(void)
{
PCF8563_write_byte(PCF8563_CTRL_STATUS_REG1,PCF8563_START_COUNTING);
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8563_READ_ADDRESS);
CTRL_STATUS_REG1 = i2c_read();
CTRL_STATUS_REG2 = i2c_read();
LV_sec           = i2c_read();
MINUTES_REG      = i2c_read();
HOURS_REG        = i2c_read();
DAY_REG          = i2c_read();
WEEK_REG         = i2c_read();
C_Mon            = i2c_read();
YEAR_REG         = i2c_read();
                   i2c_read();
                   i2c_read();
                   i2c_read();
                   i2c_read();
CTRL_CLKOUT_REG  = i2c_read();
CTRL_TIMER_REG   = i2c_read();
TIMER_REG        = i2c_read(0);
i2c_stop();
enable_interrupts(GLOBAL);
}   

//----------------------------------------------
// This function converts an 8 bit binary value
// to an 8 bit BCD value.
// The input range must be from 0 to 99.

int8 bin2bcd(int8 value)
{
char retval;

retval = 0;

while(1)
  {
   // Get the tens digit by doing multiple subtraction
   // of 10 from the binary value.
   if(value >= 10)
     {
      value -= 10;
      retval += 0x10;
     }
   else // Get the ones digit by adding the remainder.
     {
      retval += value;
      break;
     }
   }

return(retval);
}

//----------------------------------------------
// This function converts an 8 bit BCD value to
// an 8 bit binary value.
// The input range must be from 00 to 99.

char bcd2bin(char bcd_value)
{
char temp;

temp = bcd_value;

// Shifting the upper digit right by 1 is
// the same as multiplying it by 8.
temp >>= 1;

// Isolate the bits for the upper digit.
temp &= 0x78;

// Now return: (Tens * 8) + (Tens * 2) + Ones
return(temp + (temp >> 2) + (bcd_value & 0x0f));

}
//----------------------------------------------
//----------------------------------------------

void PCF8563_set_datetime(date_time_t *dt)
{

int8 bcd_sec;
int8 bcd_mon;

// Convert the input date/time into BCD values
// that are formatted for the PCF8563 registers.
 
bcd_sec = bin2bcd(dt->seconds);
bcd_min = bin2bcd(dt->minutes);
bcd_hrs = bin2bcd(dt->hours);   
bcd_day = bin2bcd(dt->day) | (dt->year << 6);
bcd_mon = bin2bcd(dt->month) | (dt->weekday << 5);
bcd_yer = bin2bcd(dt->year);
wek     = dt->weekday;
// Stop the RTC from counting, before we write to
// the date and time registers.
PCF8563_write_byte(PCF8563_CTRL_STATUS_REG1,PCF8563_STOP_COUNTING);

// Write to the date and time registers.  Disable interrupts
// so they can't disrupt the i2c operations.
disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8563_WRITE_ADDRESS);
i2c_write(PCF8563_SECONDS_REG);   // Start at seconds reg.   
i2c_write(bcd_sec);
i2c_write(bcd_min);
i2c_write(bcd_hrs);   
i2c_write(bcd_day);
i2c_write(wek);
i2c_write(bcd_mon);
i2c_write(bcd_yer);
i2c_stop();
enable_interrupts(GLOBAL);

// Now allow the PCF8563 to start counting again.

PCF8563_write_byte(PCF8563_CTRL_STATUS_REG1,PCF8563_START_COUNTING);

}
//----------------------------------------------

//----------------------------------------------
// Read the Date and Time from the hardware registers
// in the PCF8563.   We don't have to disable counting
// during read operations, because according to the data
// sheet, if any of the lower registers (1 to 7) is read,
// all of them are loaded into "capture" registers.
// All further reading within that cycle is done from
// those registers.

void PCF8563_read_datetime(date_time_t *dt)
{
int8 bcd_sec;
int8 bcd_min;
int8 bcd_hrs;
int8 bcd_day;
int8 wek;
int8 bcd_mon;
int8 bcd_yer;

//  LowVoltage = VL_sec.7
//  Century    = C_Mon.7

// Disable interrupts so the i2c process is not disrupted.
disable_interrupts(GLOBAL);

// Read the date/time registers inside the PCF8563.
i2c_start();
i2c_write(PCF8563_WRITE_ADDRESS);
i2c_write(PCF8563_SECONDS_REG);   // Start at seconds reg.
i2c_start();
i2c_write(PCF8563_READ_ADDRESS);

LV_sec  = i2c_read();     
bcd_min = i2c_read();     
bcd_hrs = i2c_read();
bcd_day = i2c_read();
wek     = i2c_read();
C_Mon   = i2c_read();
bcd_yer = i2c_read(0);

i2c_stop();

enable_interrupts(GLOBAL);

// Convert the date/time values from BCD to
// unsigned 8-bit integers.  Unpack the bits
// in the PCF8563 registers where required.
bcd_sec     = LV_sec & 0x7F;
bcd_mon     = C_Mon  & 0x7F;
dt->seconds = bcd2bin(bcd_sec);     
dt->minutes = bcd2bin(bcd_min);     
dt->hours   = bcd2bin(bcd_hrs & 0x3F);
dt->day     = bcd2bin(bcd_day & 0x3F);
dt->month   = bcd2bin(bcd_mon & 0x1F);
dt->weekday =    wek & 0x07;
dt->year    = bcd2bin(bcd_yer);   

}
//----------------------------------------------
void Set_Alarm(int8 AMode)
{
if (AMode == 0x00)
   {
    disable_interrupts(GLOBAL);
    i2c_start();
    i2c_write(PCF8563_WRITE_ADDRESS);
    i2c_write(PCF8563_ALARM_MINS_REG);   // Start at alarm min reg.   
    i2c_write(0x80);
    i2c_write(0x80);
    i2c_write(0x80);   
    i2c_write(0x80);
    i2c_stop();
    enable_interrupts(GLOBAL);
   }
}
void Set_Alarm(int8 AMode,PCF8563_Alarm *AT)
{
int8 min = 0x80;
int8 hrs = 0x80;
int8 day = 0x80;
int8 wek = 0x80;
 
switch (AMode){
          case 0x01: min = bin2bcd(AT->minutes);
                     break;
          case 0x04: min = bin2bcd(AT->minutes);
                     hrs = bin2bcd(AT->hours);
                     break;
          case 0x07: min = bin2bcd(AT->minutes);
                     hrs = bin2bcd(AT->hours);
                     wek = AT->weekday;
                     break;
          case 0x0B: min = bin2bcd(AT->minutes);
                     hrs = bin2bcd(AT->hours);
                     day = bin2bcd(AT->day);
                     break;
               }

disable_interrupts(GLOBAL);
i2c_start();
i2c_write(PCF8563_WRITE_ADDRESS);
i2c_write(PCF8563_ALARM_MINS_REG);   // Start at alarm min reg.   
i2c_write(min);
i2c_write(hrs);
i2c_write(day);   
i2c_write(wek);
i2c_stop();
enable_interrupts(GLOBAL);

}

//----------------------------------------------

void config_CLKOUT(int8 mode)
{
PCF8563_write_byte(PCF8563_CTRL_CLKOUT_REG, mode);
}

//----------------------------------------------

void config_PCF8563_Timer(int8 mode)
{
PCF8563_write_byte(PCF8563_CTRL_TIMER_REG, mode);
}

//----------------------------------------------

void config_PCF8563_Interrupt(int8 mode,ti_tp)
{
mode = mode | ti_tp;
PCF8563_write_byte(PCF8563_CTRL_STATUS_REG2, mode);
}

//----------------------------------------------

It not work.
LED that connected to RA3 turn on 6 or 7 time and then not work! Sad Mad Crying or Very sad
When I use debug in ICD, error ICD0083, ICD0069 are happened. I connect VPP by Pull up resistor and Vdd, GND and PGD, PGC directly to corresponding pin.
Please Help me! Wink Rolling Eyes Shocked
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Oct 16, 2010 4:42 pm     Reply with quote

I don't want to fix your ICD2 problem. Post a question on the Microchip
ICD2 forum, or search their forum archives for the answer. Here is the link:
http://www.microchip.com/forums/f49.aspx
HGHK



Joined: 29 Jun 2010
Posts: 33

View user's profile Send private message Yahoo Messenger

I need help in my code
PostPosted: Sat Oct 16, 2010 11:31 pm     Reply with quote

Dear PCM programmer,
I need your help in my program Not to ICD2 and i say it for Know and my uC programed successfully and run with out debugging.
for example is this method true?:
Code:
 int8 SSPADD;
#locate SSPADD=0x93 
and then in main Program
Code:
  SSPADD=0x00;

Thanks! Wink
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group