Hi everybody! I'm trying to use a BQ32000 with a microcontroller and there is a strange problem...
I can write to any register and read the seconds or minutes register without any problem but when I read an other register, I get the value of this one, and then I can't do anything, the I2C connexion seems like closed. I can't "talk" with the RTC or the TMP101 which is on the same bus (and works perfectly before that), the µC holds on, waiting for an incoming data. I use exactly the same functions for reading and writing for all the registers if we except the value of the pointer register of course. Does anyone have an idea to solve this problem?
Just a precision, I use a 5v/3.3v level converter which seems to works fine.
Benjamin,Please supply additional details on the level shifter you are using. It is possible for I2C to get stuck if the level shifters are not implemented correctly. This happens when the slave device is transmitting a low and fails to receive the correct number of SCL edges.
A similar problem can occur with asynchronous battery backup switchovers. Basically, if the RTC goes into backup mode while driving the I2C bus low it prevents the bus from returning to normal once main power is restored. The action to correct this is listed below:1. Drive the bus with START condition2. Hi-Z the Master SDA output3. Generate 9 SCL periods4. Enable the Master SDA output5. Drive the bus with a STOP condition Do you know if the microcontroller is driving a NACK after the last data read byte? The last data read byte should be followed by a NACK and a STOP. Regards,Brad
Thank you so much! The problem was the ACK I send instead of a NACK! However on the datasheet (figure 5, page 9) it says that a ACK must be send before a STOP and not a NACK. It is normal or it is a mistake? If it's a mistake, it should be corrected to avoid problems like mine. Thank you again for your help!
Best regards,
Benjamin
Benjamin,
Glad to help. I have submitted a request for the data sheet to be updated.
Regards,
Brad
Hi Benjamin,
I am writing code in C for BQ32000, but not able to establish contact with BQ32000,
If possible will you help me with code you written for BQ32000.
I am using LM3S9B96 with internal I2C with pullup of 4.7k Ohm.
My code is for PIC µcontrollers and for the HI-TECH C Compiler but I think that it could help you. There is the header code :
#ifndef BQ32000_H_#define BQ32000_H_#define XTAL_FREQ 32MHZ#include "i2c/i2c.h"#include "delay.h"#include "lcd.h"#include <stdio.h>#include <string.h>//adresses#define BQ_ADRW 0b11010000#define BQ_ADRR 0b11010001//Registres#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//Jours de la semaine (DAY_REG)#define DIMANCHE 1#define LUNDI 2#define MARDI 3#define MERCREDI 4#define JEUDI 5#define VENDREDI 6#define SAMEDI 7void 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(char*);void getMinutes(char*);void getHours(char*);void getDay(char*);void getDate(char*);void getMonth(char*);void getYear(char*);int dayToInt(char* day);void intToDay(int d, char* jour);#endif /*BQ32000_H_*/
and here the source code, if there is any problem, ask me
#include "BQ32000.h"void BQInit() { OpenI2C(MASTER, SLEW_ON); SSPADD=19; //clock = FOSC/(4 * (SSPADD + 1)) setSeconds(128); setSeconds(0); setMinutes(0); setHours(12); setDay(LUNDI); setDate(1); setMonth(1); setYear(10); }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); //temps minimum avant de re grrer un Start return data;}void setReg(char reg, char data) { IdleI2C(); StartI2C(); IdleI2C(); WriteI2C(BQ_ADRW); IdleI2C(); WriteI2C(reg); IdleI2C(); WriteI2C(data); IdleI2C(); StopI2C(); DelayUs(60); //temps minimum avant de re grrer un Start }void getSeconds(char* sec) { char data = getReg(SEC_REG); *sec = (((data&112)>>4)*10+(data&15));}void getMinutes(char* min) { char data = getReg(MIN_REG); *min = (((data&112)>>4)*10+(data&15));}void getHours(char* hours) { char data = getReg(HOURS_REG); *hours = (((data&48)>>4)*10+(data&15));}void getDay(char* jour) { switch(getReg(DAY_REG) & 0x07) { case LUNDI: sprintf(jour ,"%s" ,"Lun"); break; case MARDI: sprintf(jour ,"%s" ,"Mar"); break; case MERCREDI: sprintf(jour ,"%s" ,"Mer"); break; case JEUDI: sprintf(jour ,"%s" ,"Jeu"); break; case VENDREDI: sprintf(jour ,"%s" ,"Ven"); break; case SAMEDI: sprintf(jour ,"%s" ,"Sam"); break; case DIMANCHE: sprintf(jour ,"%s" ,"Dim"); break; }}void getDate(char* date) { char data = getReg(DATE_REG); *date = (((data&48)>>4)*10+(data&15));}void getMonth(char* month) { char data = getReg(MONTH_REG); *month = (((data&16)>>4)*10+(data&15));}void getYear(char* year) { char data = getReg(YEAR_REG); *year = (((data&240)>>4)*10+(data&15));}void setSeconds(char sec) { char data; getSeconds(&data); data &= 0x80; sec = ((sec/10)<<4)+sec-((sec/10)*10); setReg(SEC_REG, sec|data);}void setMinutes(char min) { char data; getMinutes(&data); data &= 0x80; min = ((min/10)<<4)+min-((min/10)*10); setReg(MIN_REG, min|data);}void setHours(char hours) { char data; 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,"Dim")) return 1; else if(!strcmp(day,"Lun")) return 2; else if(!strcmp(day,"Mar")) return 3; else if(!strcmp(day,"Mer")) return 4; else if(!strcmp(day,"Jeu")) return 5; else if(!strcmp(day,"Ven")) return 6; else if(!strcmp(day,"Sam")) return 7; return -1;}void intToDay(int d, char* jour) { switch(d) { case LUNDI: sprintf(jour ,"%s" ,"Lun"); break; case MARDI: sprintf(jour ,"%s" ,"Mar"); break; case MERCREDI: sprintf(jour ,"%s" ,"Mer"); break; case JEUDI: sprintf(jour ,"%s" ,"Jeu"); break; case VENDREDI: sprintf(jour ,"%s" ,"Ven"); break; case SAMEDI: sprintf(jour ,"%s" ,"Sam"); break; case DIMANCHE: sprintf(jour ,"%s" ,"Dim"); break; }}
Hi Benjamin
Thank you very much.
I apply code your, writing and reading to resisters is fine, but RTC is not updating time.
It contunusly shows value which is set by program not gating update.
Plz help if possible.
Will you please give some more information about steps below.
data=ReadI2C(); NotAckI2C();
Just before these instructions, I ask to the BQ32000 to give me the value of a register so I store this value into "data" and then I send a Not Acknowledge to confirm to the BQ3200 that I have receive the information correctly
BQ32000 is giving BCD output. Can I directly store in "char" or have to do some process?
Please help.
That's why I wrote the getSeconds, getMinutes, etc functions. They return the value of the register in a decimal number, not in BCD. If you want to convert them into strings you can use the sprintf function like this :
char h,m,s,aString[12]; // char type does not mean that you store characters into it, only that the data is on one byte (value≤255)
getHours(&h);
getMinutes(&m);
getSeconds(&s);
sprintf(aString,"%2dh %2dm %2ds",h,m,s); // aString will contain something like "08h 36m 54s"
note : Only the getDay function gives you a string directly
Hi Bejamin,
Thank you for great help,
My code is working now.
Thank you again......
you're welcome
hi Benjamin,
Where have you got that header file of i2c, could you please put it up here on the forum,
it would be of great help to me.
Thanks
Varun
PS: because the one that I have is for firmware controlled master mode.
I've got all the I2C relative files from my compiler (Hi-Tech PICC18). I put you all of them in a zip file in attachment
5140.I2C.zip
Thank you Benjamin,