|
|
View previous topic :: View next topic |
Author |
Message |
kmp84
Joined: 02 Feb 2010 Posts: 363
|
MCP79410 driver |
Posted: Sat Apr 06, 2019 3:25 pm |
|
|
Hello All,
Is there some working driver for MCP79410 RTC chip? I tried with some my modification, but it did not succeed.
Best Regards! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9269 Location: Greensville,Ontario
|
|
Posted: Sat Apr 06, 2019 7:30 pm |
|
|
With every I2C device, use PCM P's I2C scanner program from the code library to confirm the PIC can communicate with the I2C device.
I did a quick read of the datasheet and the base address appears to be 0xDE.
Have you the correct I2C bus pullups?
Have you a coin cell battery connected ?
Is this just the chip or a premade 'module'? If a module, post a link to it's datasheet.
What PIC ??
Show us your code ! It might be a simple mistype.
Jay |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 363
|
|
Posted: Sun Apr 07, 2019 4:02 am |
|
|
Hi mr."temtronic",
I forgot to say that:
1. PCM's scanner program found slave address 0xAE, 0xDE;
2. Have been connected pull-up 4k7;
3. Have been connected backup source to pin 'vbat'.
Here is sample test program:
Code: |
#include <33EP512MU810.h>
#device ICSP=1
#use delay(crystal=8MHz, clock=8MHz)
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOJTAG //JTAG disabled
#FUSES NOPROTECT
/* HW UART4 */
#pin_select U4RX=PIN_E6 // Rx Com4.
#pin_select U4TX=PIN_E7 // Tx Com4.
#define RS485_EN_UART4 PIN_D4 // RE/DE Com4.
#use rs232(UART4,baud=9600,errors,enable=RS485_EN_UART4)
//#define RTC_SDA2 PIN_F4
//#define RTC_SCL2 PIN_F5
#use i2c(master, I2C2)
//#define MCP7941x_EEPROM_I2C_ADDR 0xAE
#define MCP7941x_RTC_I2C_ADDR 0xDE
#define RTC_LOCATION 0x00
BYTE bin2bcd(BYTE binary_value){
BYTE temp;
BYTE retval;
temp = binary_value;
retval = 0;
while(1)
{
// Get the tens digit by doing multiple subtraction
// of 10 from the binary value.
if(temp >= 10)
{
temp -= 10;
retval += 0x10;
}
else // Get the ones digit by adding the remainder.
{
retval += temp;
break;
}
}
return(retval);
}
// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value){
BYTE temp;
temp = bcd_value;
// Shifting upper digit right by 1 is same as multiplying 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));
}
// Get the date/time:
void MCP7941x_getDateTime(
byte &second,
byte &minute,
byte &hour,
byte &dayOfWeek,
byte &dayOfMonth,
byte &month,
byte &year)
{
i2c_start();
i2c_write(MCP7941x_RTC_I2C_ADDR);
i2c_write(RTC_LOCATION);
i2c_start();
i2c_write(MCP7941x_RTC_I2C_ADDR+1);
// A few of these need masks because certain bits are control bits
second = bcd2bin(i2c_read() & 0x7f); // 01111111
minute = bcd2bin(i2c_read() & 0x7f); // 01111111
hour = bcd2bin(i2c_read() & 0x3f); // 00111111
dayOfWeek = bcd2bin(i2c_read() & 0x07); // 01111111
dayOfMonth = bcd2bin(i2c_read() & 0x3f); // 00111111
month = bcd2bin(i2c_read() & 0x1f); // 00011111
year = bcd2bin(i2c_read()); // 11111111
i2c_stop();
}
// Set the date/time, set to 24hr and enable the clock:
// (assumes you're passing in valid numbers)
void MCP7941x_setDateTime(
byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
{
i2c_start();
i2c_write(MCP7941x_RTC_I2C_ADDR);
i2c_write(RTC_LOCATION);
i2c_write(bin2bcd(second) & 0x7f); // set seconds and disable clock (01111111)
i2c_write(bin2bcd(minute) & 0x7f); // set minutes (01111111)
i2c_write(bin2bcd(hour) & 0x3f); // set hours and to 24hr clock (00111111)
i2c_write(0x08 | (bin2bcd(dayOfWeek) & 0x07)); // set the day and enable battery backup (00000111)|(00001000)
i2c_write(bin2bcd(dayOfMonth) & 0x3f); // set the date in month (00111111)
i2c_write(bin2bcd(month) & 0x1f); // set the month (00011111)
i2c_write(bin2bcd(year)); // set the year (11111111)
i2c_stop();
// Start Clock:
i2c_start();
i2c_write(MCP7941x_RTC_I2C_ADDR);
i2c_write(RTC_LOCATION);
i2c_write(bin2bcd(second) | 0x80); // set seconds and enable clock (10000000)
i2c_stop();
}
void main(){
delay_ms(1000);
BYTE second;
BYTE minute;
BYTE hour;
BYTE dayOfWeek;
BYTE dayOfMonth;
BYTE month;
BYTE year;
printf("\n\rMCP7941x_RTC_EXMPLE....");
/*
// Set the date/time, set to 24hr and enable the clock:
// (assumes you're passing in valid numbers)
void MCP7941x_setDateTime(
byte second, // 0-59
byte minute, // 0-59
byte hour, // 1-23
byte dayOfWeek, // 1-7
byte dayOfMonth, // 1-28/29/30/31
byte month, // 1-12
byte year) // 0-99
*/
MCP7941x_setDateTime(0, 1, 13, 7, 7, 4, 19);
for(;;){
MCP7941x_getDateTime(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
printf("\r\nDATA: %02d/\%02d/\%02d",dayOfMonth,month,year);
printf(" TIME:\%02d:\%02d:\%02d\r\n",hour,minute,second);
delay_ms(1000);
}
}
|
and print result:
MCP7941x_RTC_EXMPLE....
DATA: 45/25/-91 TIME:45:85:85
DATA: 45/25/-91 TIME:45:85:85
DATA: 45/25/-91 TIME:45:85:85
DATA: 45/25/-91 TIME:45:85:85 |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9269 Location: Greensville,Ontario
|
|
Posted: Sun Apr 07, 2019 5:54 am |
|
|
I've seen the '45' and '85' magical numbers before, and are indicating you're not either setting the RTC or starting the RTC or maybe a bad 32KHz xtal.
4K7 pullups are OK for 5 volts, 3k3 for 3 volts.
You should probably set the I2C speed for SLOW although it's rated to 400KHz, you need to be sure pullups are designed for that as well as board layout.
I don't have one to test here so I can't confirm/deny your code is good.
Jay |
|
|
|
|
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
|