This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Interfacing BQ3200 to pic16f877a. Trying to store rtc data to eeprom.

Other Parts Discussed in Thread: BQ32000

Hi All,

Can any one go through the code  and find why its not working. There are no compiling errors, I think it should work. I'm really thank ful for your time and help.

The code is sort of made up not developed.

Varun.

 

#include <pic.h>
#include "delay.h"
#include "eepromrdwr.h"
#include "BQ32000.h"
//#include "i2c_new.h"

unsigned char Time_Hr=0, Time_Min=0, address=0;
unsigned char min=0,year=0,sec=0,date=0,month=0,hours=0;

#define init_ports() TRISA=0x00,PORTA=0x00,TRISB=0x00,PORTB=0x00,TRISC=0x00,PORTC=0x00,PORTD=0x00,TRISD=0x00;

 

void BQInit() {
  
    //OpenI2C(MASTER, SLEW_ON);
   //SSPADD=09;  //clock = FOSC/(4 * (SSPADD + 1))
    //setSeconds(128);
    setSeconds(0);
    setMinutes(30);
    setHours(10);
    setDay(MONDAY);
    setDate(14);
    setMonth(3);
    setYear(11);
}

char getReg(char reg) {
    char data;
      
        IdleI2C();
    StartI2C();
        IdleI2C();
    WriteI2C(BQ_ADRW);
        IdleI2C();
    WriteI2C(reg);
        IdleI2C();
    StartI2C();
        IdleI2C();
    WriteI2C(BQ_ADRR);
    data=ReadI2C();
        NotAckI2C();
        IdleI2C();
    StopI2C();
  
    DelayUs(60); //wait at least 60 us after the RTC exits backup mode to generate a START condition

    return data;
}

void setReg(char reg, char data) {
  
        IdleI2C();
    StartI2C();
        IdleI2C();
    WriteI2C(BQ_ADRW);
        IdleI2C();
    WriteI2C(reg);      
        IdleI2C();
    WriteI2C(data);
        IdleI2C();  
    StopI2C();
  
    DelayUs(60); //wait at least 60 us after the RTC exits backup mode to generate a START condition
  
}

void getSeconds() {
    char data = getReg(SEC_REG);
     sec = (((data&112)>>4)*10+(data&15));
}

void getMinutes() {
    char data = getReg(MIN_REG);
     min = (((data&112)>>4)*10+(data&15));
}

void getHours() {
    char data = getReg(HOURS_REG);
     hours = (((data&48)>>4)*10+(data&15));
}

void getDay(char* weekday) {
    switch(getReg(DAY_REG) & 0x07) {
        case MONDAY:
            sprintf(weekday ,"%s" ,"Mon");
        break;
        case TUESDAY:
            sprintf(weekday ,"%s" ,"Tue");
        break;
        case WEDNESDAY:
            sprintf(weekday ,"%s" ,"Wed");
        break;
        case THURSDAY:
            sprintf(weekday ,"%s" ,"Thu");
        break;
        case FRIDAY:
            sprintf(weekday ,"%s" ,"Fri");
        break;
        case SATURDAY:
            sprintf(weekday ,"%s" ,"Sat");
        break;
        case SUNDAY:
            sprintf(weekday ,"%s" ,"Sun");
        break;
    }
}

void getDate() {
    char data = getReg(DATE_REG);
    date = (((data&48)>>4)*10+(data&15));
}

void getMonth() {
    char data = getReg(MONTH_REG);
    month = (((data&16)>>4)*10+(data&15));
}

void getYear() {
    char data = getReg(YEAR_REG);
    year = (((data&240)>>4)*10+(data&15));
}

void setSeconds(char sec) {
    char data=0;
    //getSeconds(data);
    data &= 0x80;
    sec = ((sec/10)<<4)+sec-((sec/10)*10);
    setReg(SEC_REG, sec|data);
}

void setMinutes(char min) {
    char data=0;
    //getMinutes(data);
    data &= 0x80;
    min = ((min/10)<<4)+min-((min/10)*10);
    setReg(MIN_REG, min|data);
}

void setHours(char hours) {
    char data=0;
    //getHours(data);
    data &= 0xC0;
    hours = ((hours/10)<<4)+hours-((hours/10)*10);
    setReg(HOURS_REG, hours|data);
}

void setDay(char day) {
    setReg(DAY_REG, day);
}

void setDate(char date) {
    date = ((date/10)<<4)+date-((date/10)*10);
    setReg(DATE_REG, date);
}

void setMonth(char month) {
    month = ((month/10)<<4)+month-((month/10)*10);
    setReg(MONTH_REG, month);
}

void setYear(char year) {
    year = ((year/10)<<4)+year-((year/10)*10);
    setReg(YEAR_REG, year);
}

int dayToInt(char* day) {
    if(!strcmp(day,"Sun")) return 1;
    else if(!strcmp(day,"Mon")) return 2;
    else if(!strcmp(day,"Tue")) return 3;
    else if(!strcmp(day,"Wed")) return 4;
    else if(!strcmp(day,"Thu")) return 5;
    else if(!strcmp(day,"Fri")) return 6;
    else if(!strcmp(day,"Sat")) return 7;
    return -1;
}

void intToDay(int d, char* weekday) {
    switch(d) {
            case MONDAY:
                sprintf(weekday ,"%s" ,"Mon");
            break;
            case TUESDAY:
                sprintf(weekday ,"%s" ,"Tue");
            break;
            case WEDNESDAY:
                sprintf(weekday ,"%s" ,"Wed");
            break;
            case THURSDAY:
                sprintf(weekday ,"%s" ,"Thu");
            break;
            case FRIDAY:
                sprintf(weekday ,"%s" ,"Fri");
            break;
            case SATURDAY:
                sprintf(weekday ,"%s" ,"Sat");
            break;
            case SUNDAY:
                sprintf(weekday ,"%s" ,"Sun");
            break;
        }
}


void main(void)
{
 init_ports();
 char Time_Hr=0, Time_Min=0, address=0;
 //I2C_init();
 I2CInit();
 BQInit();
while(1)
{
 RB1=1;
 DelayMs(250);
 DelayMs(250);
 DelayMs(250);                      //total of 1.25 sec delay
 DelayMs(250);
 DelayMs(250);
 RB1=0;
// getHours();
// Time_Hr = &hours;
 //WriteByteToEE(Time_Hr, address++);
  getMinutes();                                  // Time_Min= &min;
  WriteByteToEE(min, address++);
  DelayMs(50);
 
  getSeconds();
  WriteByteToEE(sec, address++);
 
  getHours();
  WriteByteToEE(hours, address++);
}
 
}

 

*************************************************************************

 

HEADER FILES:

/*header file for BQ32000*/

#ifndef BQ32000_H_
#define BQ32000_H_

#define XTAL_FREQ 4MHZ

//#include "i2c/i2c.h"
#include "i2c_new.h"
#include "delay.h"
//#include "lcd.h"
#include <stdio.h>
#include <string.h>

//addresses
#define BQ_ADRW     0b11010000
#define BQ_ADRR     0b11010001

//Registers
#define SEC_REG      0
#define MIN_REG      1
#define HOURS_REG    2
#define DAY_REG      3
#define DATE_REG     4
#define MONTH_REG    5
#define YEAR_REG     6
#define CAL_REG      7
#define TCH2_REG     8
#define CFG2         9

//Week days (DAY_REG)
#define SUNDAY       1
#define MONDAY       2
#define TUESDAY      3
#define WEDNESDAY    4
#define THURSDAY     5
#define FRIDAY       6
#define SATURDAY     7

//void BQInit();
char getReg(char reg);
void setReg(char reg, char data);

void setSeconds(char);
void setMinutes(char);
void setHours(char);
void setDay(char);
void setDate(char);
void setMonth(char);
void setYear(char);

void getSeconds();
void getMinutes();
void getHours();
void getDay(char*);
void getDate();
void getMonth();
void getYear();

int dayToInt(char* day);
void intToDay(int d, char* weekday);


#endif /*BQ32000_H_*/

*****************************************

//===============================================================
// I2C functions
//---------------------------------------------------------------

void I2CInit(void){
        TRISC3 = 1;      /* SDA and SCL as input pin */
        TRISC4 = 1;      /* these pins can be configured either i/p or o/p */
        SSPSTAT |= 0x80; /* Slew rate disabled */
        SSPCON = 0x28;   /* SSPEN = 1, I2C Master mode, clock = FOSC/(4 * (SSPADD + 1)) */
        SSPCON2=0x00;
        SSPADD = 9;    /* 100Khz @ 4Mhz Fosc */
}

void IdleI2C( void) {         // Idle check, wait for buss to go to Idle state
   while (RW == 1);               // SSPSTAT:2 wait for transmit to finish
   while ((SSPCON2 & 0x1F) != 0) ;   // wait for buss not busy
}


void StartI2C( void) {
   SEN = 1;            // SSPCON2:0 initiate I2C START condition
   while (SEN == 1);      // wait until START bit finishes
}


void RestartI2C( void) {
   RSEN = 1;            // SSPCON2:1 Repeated Start
   while (RSEN);
}


void WriteI2C( unsigned char DataByte ){
   SSPBUF = DataByte;
   while (RW == 1);
}


unsigned char ReadI2C( void) {
   RCEN = 1;               // SSPCON2:3 Receive enable
   while (RCEN == 1);
   return SSPBUF;
}


void StopI2C( void) {
   PEN = 1;            // SSPCON2:2 initiate I2C STOP condition
   while (PEN);
}


void AckI2C( void) {
   ACKDT = 0;            // SSPCON2:5 set to ACK
   ACKEN = 1;            // SSPCON2:4  initiate I2C ACK condition
   while ( ACKEN);             // wait until ACK sequence is over
}


void NotAckI2C( void) {
   ACKDT = 1;            // initiate I2C notACK condition
   ACKEN = 1;
   while ( ACKEN);             // wait until ACK sequence is over
}


unsigned char IsACKI2C( void) {
   if (ACKSTAT == 0) {
      return 1;         // ACK detected
   } else {
      return 0;         // ACK not detected
   }
}


unsigned char DataRdyI2C( void) {
   unsigned char a;
  
   return a;
}

  • Hi All,

    here with I am attaching the project file of: Interfacing BQ32000DR with 16F877A. Compiler used hi-tech C. I'm happy that its working.

    Here BCD data is converted to ascii and stored in on chip eeprom.

    bye,

    Varun

    BQ32000_f877a_intrfc.rar
  • Varun,

    I have a some questions to better understand your problem:

    1. What is not working specifically?

    2. What is your target device for the code you have provided?

    3. What is the data/clock frequency that is generated?

    To help debug the problem, can you change the code to only perform read operations and output the read value?  This will help establish that the I2C protocol is being handled correctly (START, STOP, SLAVE ADDRESS, etc.).  The bq32000 should start up with some value for time that does not make sense, but that is OK for this test.

    If the read works, then try to only write the seconds register and read back the updated RTC time (or just the seconds is OK).

     

    Regards,

     

    Brad

  • Hello Brad,

    I have finally arrived at the working code and the working circuit, thats what I have put up as .rar file.

    My code is working now.

    Thanks for the concern.

    Regards,

    Varun.