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

Got trouble with 16f877 i2c in communicatio with rtc pcf8583

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







Got trouble with 16f877 i2c in communicatio with rtc pcf8583
PostPosted: Wed Nov 13, 2002 1:52 pm     Reply with quote

Hi everybody.
I'm doing a pcb board with the two chips, but have no way to communicate 16F877 with pcf 8583 via i2c.

I've got two problems:

1) PCF8583 is connected like it's told in philips specifications and with a capacitor of 20pF from OSC1 to gnd.It's suppose to begin to oscillate after reset condition, but in my case it doesn't oscillate. When reset Pcf8583 the configuration register is cleared in all bits, it means that have select a 32.7 KHz oscillator, but i don't know if it is the internal or the external of the same value that i have between OSC1&OSC2.

2) I2C communication doesn't work.
The 16F877 seems to wait the RTC response, but it doesn't come.
I'm tested the SDA &SCL lines but have a very [censored] signal. no pulses, nothing but noise.

I send dates by the serial port and visualize it in a Lcd, both things works fine, but when writing or reading in PFC8583 the system gets waiting.

I can see it because after giving the address for reading the program hangs up at POINT A and after giving the address & the data in the writepcf function, the program gets hung up IN POINT B.

Can you see what is the problem??

I'm getting crazy, I'm trying to locate the error since last Friday, but i can't see it.

Thanks.

This is the code:




#include <16f877.h>
#include <stdlib.h>
#include <stdio.h>


#ifndef PCF_SDA
#define PCF_SDA PIN_B7
#define PCF_SCL PIN_B6
#endif

#use i2c(master,sda=PCF_SDA, scl=PCF_SCL)


int dir=0,comando=0,dato=0;

//////////////////////////// DECLARACIÓŽ DE FUNCIONES ///////////////////////////////////////////




///// FUNCIONES PARA MANEJO DEL PCF8583 /////
void configure_ctrl_reg(byte ctrl_reg);


void writePCF(byte address,byte data);
byte readPCF(byte address);



////////////////////////// PROGRAMA PRINCIPAL ////////////////////////////////////////////////////


main()
{
if(kbhit())
{
comando=getc();
}
if (comando==1)
{
printf(lcd_putc,"leer registro");
delay_ms(1000);
lcd_putc('\f');
printf(lcd_putc,"esperando direccion");
dir=getc();
lcd_putc('\f');
printf(lcd_putc," direccion=\%d",dir);
delay_ms(1000);
dato=readPCF(dir);////POINT A////
lcd_putc('\f');
printf(lcd_putc," lectura=\%d",dato);
delay_ms(1000);
putc(dato);
dato=0;
lcd_putc('\f');
printf(lcd_putc,"read ended");
}

else if (comando==2)

{
lcd_putc('\f'
printf(lcd_putc,"escribir registro");
delay_ms(1000);
lcd_putc('\f');
printf(lcd_putc,"esperando direccion");
dir=getc();
lcd_putc('\f');
printf(lcd_putc," direccion=\%d",dir);
delay_ms(1000);
lcd_putc('\f');
printf(lcd_putc,"esperando valor reg");
dato=getc();
lcd_putc('\f');
printf(lcd_putc," valor=\%d",dato);
delay_ms(1000); ///POINT B////
writePCF(dir,dato);dato=0;
lcd_putc('\f');
printf(lcd_putc,"write ended");
}


}
}

/////////////////// FUNCIONES PARA CONFIGURAR EL RTC PCF8583 ///////////////////////////////////////////////////////

void configure_ctrl_reg(byte ctrl_reg)
{
i2c_start();
i2c_write(0xa0);
i2c_nack();
i2c_write(0x00); /* control register address */
i2c_nack();
i2c_write(ctrl_reg);
i2c_nack();
i2c_stop();
}

void writePCF(byte address, byte data)
{

i2c_start();
i2c_write(0xa0);
i2c_nack();
i2c_write(address);
i2c_nack();
i2c_write(data);
i2c_nack();
i2c_stop();
}


byte readPCF(byte address)
{
byte data;

i2c_start();
i2c_write(0xa0);
i2c_nack();
i2c_write(address);
i2c_nack();
i2c_start();
i2c_write(0xa0);
i2c_nack();
data=i2c_read();
i2c_stop();
return(data);
}

void i2c_nack(void)
{
output_high(PIN_C4); /*fuerza a 1 sda*/
output_high(PIN_C3); /*clock pulse*/
output_high(PIN_C3);
}



___________________________
This message was ported from CCS's old forum
Original Post ID: 8860
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: Got trubles with 16f877 i2c in comunication with rtc pcf
PostPosted: Wed Nov 13, 2002 2:38 pm     Reply with quote

:=1) PCF8583 is connected like it's told in philips specifications and with a capacitor of 20pF from OSC1 to gnd.

I don't see that in the PCF8583 data sheet.
<a href="http://www.semiconductors.philips.com/acrobat/datasheets/PCF8583_5.pdf" TARGET="_blank">http://www.semiconductors.philips.com/acrobat/datasheets/PCF8583_5.pdf</a>
There is a schematic on page 22, that shows a variable
capacitor going from OSCI to VDD. Where do you see the
20 pf to GND ?

Another small question: Are you using a 32.768 crystal ?
It's required, according to Section 71.0, on page 12 of
the data sheet.

--------------------------
:=
:=2) I2C communicattion doesn't work.

It appears that you are trying to use Peter Anderson's
i2c routines, instead of the CCS routines. Here's
some of his typical i2c code.
<a href="http://www.phanderson.com/PIC/PICC/CCS_PCM/24_256_1.html" TARGET="_blank">http://www.phanderson.com/PIC/PICC/CCS_PCM/24_256_1.html</a>

:=
:= void i2c_nack(void)
:= {
:= output_high(PIN_C4); /*fuerza a 1 sda*/
:= output_high(PIN_C3); /*clock pulse*/
:= output_high(PIN_C3);
:= }

If you are in fact trying to use Peter Anderson's routines,
then the code above is not correct. In his routines,
he has "output_low()" for the last line. I don't know
why you changed it.


:=
:=
___________________________
This message was ported from CCS's old forum
Original Post ID: 8864
Ed Arnold
Guest







Re: Got trubles with 16f877 i2c in comunication with rtc pcf
PostPosted: Wed Nov 13, 2002 3:07 pm     Reply with quote

:=/////////////////// FUNCIONES PARA CONFIGURAR EL RTC PCF8583 ///////////////////////////////////////////////////////
:=
:= void configure_ctrl_reg(byte ctrl_reg)
:= {
:= i2c_start();
:= i2c_write(0xa0);
:= i2c_nack();
:= i2c_write(0x00); /* control register address */
:= i2c_nack();
:= i2c_write(ctrl_reg);
:= i2c_nack();
:= i2c_stop();
:= }

To restate PCM programmer's notes. You must use an external oscolator. Also, I don't see where you ever call configure control register. This is also very important. If you don't plan to use your F877 as a slave, I suggest using the CCS built in routines (for Master only), they work just fine.

Ed Arnold
___________________________
This message was ported from CCS's old forum
Original Post ID: 8867
isa
Guest







Re: Got trubles with 16f877 i2c in comunication with rtc pcf
PostPosted: Thu Nov 14, 2002 11:34 am     Reply with quote

First of all thanks for helping me.

In fact the 20 pF capacitor goes from Osc1 to Vdd, i made a writting mistake.

I don't configure the pcf8583 cause i think that when reset, PCF8583 is configurated with 0x00 word.

Of course i'm using an external Xtal whose value is 32.76Khz, but i can't get the normal signal in pin Osc2 from PCF8583, i only get noise, so that, i asked if the reset configuration of PCF8583 uses the external or internal oscilator.My board is prepared to use the external oscilator with a 20pF, and two resistor from scl& sda to Vcc, each one.

When i program the Pcf8583 in the main program, my board hungs up, so that i thougth that with the reset configuration was enough, maybe doesn't it.

The nack funcion was coppied from the person you have told, i thougth it would be ok, but yes, it was a silly thing.

I use the i2c ccs functions, but it doesn't works at all.

Here you have the last try of today:

#include <16f877.h>
#include <stdlib.h>
#include <stdio.h>


#ifndef PCF_SDA
#define PCF_SDA PIN_B7
#define PCF_SCL PIN_B6
#endif

#use i2c(master,sda=PCF_SDA, scl=PCF_SCL)

int dir=0,comando=0,dato=0;

///// FUNCIONES PARA MANEJO DEL PCF8583 /////
void configure_ctrl_reg(byte ctrl_reg);

void writePCF(byte address,byte data);
byte readPCF(byte address);


#use delay (clock=4000000)


/////////// Configuración del puerto serie. 19200 baudios////////
////////// 1 bit de Star y 1 bit de Stop, sin paridad /////////
////////// Tx es el PIN_C6(25) y Rx PIN_C7(26) /////////
#use rs232(baud=19200,bits=8,parity=N,xmit=PIN_C6,rcv=PIN_C7)





//////////////////// RUTINA DE ATENCIÓN A LA INTERRUPCIÓN EXTERNA ////////////////////////////////

#int_ext
void ext_isr()
{
int b=10;
while (b!=-1)
{
lcd_putc('\f');
printf(lcd_putc,"interrupcion ");
lcd_putc('\n');
printf(lcd_putc,"externa \%d",b);
delay_ms(1000);
output_high(PIN_B3);
b--;
}
}


////////////////////////// PROGRAMA PRINCIPAL ////////////////////////////////////////////////////


main()
{
strut Time t_base, t;
struct Date d_base, d;
int i=0;
char car='a';

// configure_ctrl_reg(0x00); WHEN USING IT THE SYSTEM GOES HUNG UP....







while(1)
{
printf(lcd_putc,"caracter c= \%c",car);
lcd_putc('\n');
printf(lcd_putc,"variable i=\%d",i);
output_high(PIN_B3);
delay_ms(100);

output_low(PIN_B3);
delay_ms(100);
lcd_putc('\f');
i++;
car++;

if(kbhit())
{
comando=getc();

if (comando==1)
{
printf(lcd_putc,"leer registro");
delay_ms(1000);
lcd_putc('\f');
printf(lcd_putc,"esperando direccion");
dir=getc();

lcd_putc('\f');
printf(lcd_putc," direccion=\%d",dir);
delay_ms(1000);
dato=readPCF(dir);
lcd_putc('\f');
printf(lcd_putc," lectura=\%d",dato);
delay_ms(1000);
putc(dato);
dato=0;
lcd_putc('\f');
printf(lcd_putc,"read ended");
}

else if (comando==2)

{
lcd_putc('\f');printf(lcd_putc,"escribir registro");
delay_ms(1000);
lcd_putc('\f');printf(lcd_putc,"esperando direccion");
dir=getc();
lcd_putc('\f');printf(lcd_putc," direccion=\%d",dir);
delay_ms(1000);
lcd_putc('\f');printf(lcd_putc,"esperando valor reg");
dato=getc();
lcd_putc('\f');printf(lcd_putc," valor=\%d",dato);
delay_ms(1000);
writePCF(dir,dato);dato=0;
lcd_putc('\f');printf(lcd_putc,"write ended");
}


}
}

/////////////////// FUNCIONES PARA CONFIGURAR EL RTC PCF8583 ///////////////////////////////////////////////////////

void configure_ctrl_reg(byte ctrl_reg)
{
i2c_start();
i2c_write(0xa0);

i2c_write(0x00); /* control register address */

i2c_write(ctrl_reg);

i2c_stop();
}

void writePCF(byte address, byte data)
{

i2c_start();
i2c_write(0xa0);

i2c_write(address);

i2c_write(data);

i2c_stop();
}


byte readPCF(byte address)
{
byte data;

i2c_start();
i2c_write(0xa0);

i2c_write(address);

i2c_start();
i2c_write(0xa0);

data=i2c_read();
i2c_stop();
return(data);
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 8919
isa
Guest







i2c goes well, but Pcf8583 doesn't works....
PostPosted: Thu Nov 14, 2002 12:39 pm     Reply with quote

I have just seen the error, it was this:

#use i2c(master,sda=PCF_SDA, scl=PCF_SCL)


i didn't define who was PCF_SDA & PCF_SCL

it works with

#use i2c(master,sda=PIN_C4,scl=PIN_C3)

and the ccs doesn't give error......

Ok, i read pcf, supposly... and i can write in it, but it give's me always the same read, that is -1......
If you can see what i'm doing wrong... cause i can't see it....


Thanks for all..
Isa.

:=#include <16f877.h>
:= #include <stdlib.h>
:= #include <stdio.h>
:=
:=
:= #ifndef PCF_SDA
:= #define PCF_SDA PIN_B7
:= #define PCF_SCL PIN_B6
:= #endif
:=
#use i2c(master,sda=PIN_C4,scl=PIN_C3)
:=
:= int dir=0,comando=0,dato=0;
:=
:= ///// FUNCIONES PARA MANEJO DEL PCF8583 /////
:= void configure_ctrl_reg(byte ctrl_reg);
:=
:= void writePCF(byte address,byte data);
:= byte readPCF(byte address);
:=
:=
:= #use delay (clock=4000000)
:=
:=
:= /////////// Configuración del puerto serie. 19200 baudios////////
:= ////////// 1 bit de Star y 1 bit de Stop, sin paridad /////////
:= ////////// Tx es el PIN_C6(25) y Rx PIN_C7(26) /////////
:= #use rs232(baud=19200,bits=8,parity=N,xmit=PIN_C6,rcv=PIN_C7)
:=
:=
:=
:=
:=
:=//////////////////// RUTINA DE ATENCIÓN A LA INTERRUPCIÓN EXTERNA ////////////////////////////////
:=
:= #int_ext
:= void ext_isr()
:= {
:= int b=10;
:= while (b!=-1)
:= {
:= lcd_putc('\f');
:= printf(lcd_putc,"interrupcion ");
:= lcd_putc('\n');
:= printf(lcd_putc,"externa \%d",b);
:= delay_ms(1000);
:= output_high(PIN_B3);
:= b--;
:= }
:= }
:=
:=
:=////////////////////////// PROGRAMA PRINCIPAL ////////////////////////////////////////////////////
:=
:=
:= main()
:= {
:= strut Time t_base, t;
:= struct Date d_base, d;
:= int i=0;
:= char car='a';
:=
configure_ctrl_reg(0x00);
=
:= while(1)
:= {
:= printf(lcd_putc,"caracter c= \%c",car);
:= lcd_putc('\n');
:= printf(lcd_putc,"variable i=\%d",i);
:= output_high(PIN_B3);
:= delay_ms(100);
:=
:= output_low(PIN_B3);
:= delay_ms(100);
:= lcd_putc('\f');
:= i++;
:= car++;
:=
:= if(kbhit())
:= {
:= comando=getc();
:=
:= if (comando==1)
:= {
:= printf(lcd_putc,"leer registro");
:= delay_ms(1000);
:= lcd_putc('\f');
:= printf(lcd_putc,"esperando direccion");
:= dir=getc();
:=
:= lcd_putc('\f');
:= printf(lcd_putc," direccion=\%d",dir);
:= delay_ms(1000);
:= dato=readPCF(dir);
:= lcd_putc('\f');
:= printf(lcd_putc," lectura=\%d",dato);
:= delay_ms(1000);
:= putc(dato);
:= dato=0;
:= lcd_putc('\f');
:= printf(lcd_putc,"read ended");
:= }
:=
:= else if (comando==2)
:=
:= {
:= lcd_putc('\f');printf(lcd_putc,"escribir registro");
:= delay_ms(1000);
:= lcd_putc('\f');printf(lcd_putc,"esperando direccion");
:= dir=getc();
:= lcd_putc('\f');printf(lcd_putc," direccion=\%d",dir);
:= delay_ms(1000);
:= lcd_putc('\f');printf(lcd_putc,"esperando valor reg");
:= dato=getc();
:= lcd_putc('\f');printf(lcd_putc," valor=\%d",dato);
:= delay_ms(1000);
:= writePCF(dir,dato);dato=0;
:= lcd_putc('\f');printf(lcd_putc,"write ended");
:= }
:=
:=
:= }
:= }
:=
:=/////////////////// FUNCIONES PARA CONFIGURAR EL RTC PCF8583 ///////////////////////////////////////////////////////
:=
:= void configure_ctrl_reg(byte ctrl_reg)
:= {
:= i2c_start();
:= i2c_write(0xa0);
:=
:= i2c_write(0x00); /* control register address */
:=
:= i2c_write(ctrl_reg);
:=
:= i2c_stop();
:= }
:=
:= void writePCF(byte address, byte data)
:= {
:=
:= i2c_start();
:= i2c_write(0xa0);
:=
:= i2c_write(address);
:=
:= i2c_write(data);
:=
:= i2c_stop();
:= }
:=
:=
:= byte readPCF(byte address)
:= {
:= byte data;
:=
:= i2c_start();
:= i2c_write(0xa0);
:=
:= i2c_write(address);
:=
:= i2c_start();
:= i2c_write(0xa0);
:=
:= data=i2c_read();
:= i2c_stop();
:= return(data);
:= }
___________________________
This message was ported from CCS's old forum
Original Post ID: 8927
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

Re: i2c goes well, but Pcf8583 doesn't works....
PostPosted: Thu Nov 14, 2002 1:02 pm     Reply with quote

:=:= byte readPCF(byte address)
:=:= {
:=:= byte data;
:=:=
:=:= i2c_start();
:=:= i2c_write(0xa0);
:=:=
:=:= i2c_write(address);
:=:=
:=:= i2c_start();
:=:= i2c_write(0xa0);

You need to use the READ address of the chip, in the
line above. It should be "i2c_write(0xa1);"

:=:=
:=:= data=i2c_read();

The line above is the last i2c read operation. Therefore
it needs a "NAK". This is done by using a 0 parameter.
So change the line to: data=i2c_read(0);

:=:= i2c_stop();
:=:= return(data);
:=:= }


You can see these things in the CCS driver files, such as
2402.C, DS1621.C, and many more. Those driver files are
in this folder: C:\Program Files\Picc\Drivers

If you have an older version of the compiler (2.xxx), the
drivers are in this folder: C:\PICC\Examples

You should study those examples.
___________________________
This message was ported from CCS's old forum
Original Post ID: 8931
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