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 CCS Technical Support

PIC16F690 and I2c master

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



Joined: 22 Aug 2005
Posts: 275

View user's profile Send private message

PIC16F690 and I2c master
PostPosted: Mon Aug 08, 2011 3:47 am     Reply with quote

Hi to all,

I'm working around eeprom 2408 with PIC16F690. I already use it with slave I2c bus but now I need to use it as master.

I can't write and read data from eeprom and before analyze all bus signal with oscilloscope I decided to ask you help and more information.

I'm using ccs V3.249, does it support master function of PIC16F690 ?
in datasheet i read about limit of SSP in master application.

The driver used for eeprom is standard 2408.C.

my i2c bus configutation is:

Quote:

#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL,force_hw,SLOW=100000)


Thanks for help,

Regards,
Fabri
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Mon Aug 08, 2011 6:22 am     Reply with quote

Get rid of force_hw.
Use force_sw instead.
The 16F690, _does not support I2C master mode on it's SSP hardware_. The compiler will happily perform software I2C, but you are currently trying to force it to use the hardware, which does not support this.
Look at section 13.11 of the data sheet. Modes supported:
Code:

Four mode selection bits (SSPCON<3:0>)
allow one of the following I2C modes to be selected:
• I2C Slave mode (7-bit address)
• I2C Slave mode (10-bit address)
• I2C Slave mode (7-bit address), with Start and
Stop bit interrupts enabled to support Firmware
Master mode
• I2C Slave mode (10-bit address), with Start and
Stop bit interrupts enabled to support Firmware
Master mode
• I2C Start and Stop bit interrupts enabled to
support Firmware Master mode; Slave is idle

Note the lack of _any_ master modes.

Best Wishes
Fabri



Joined: 22 Aug 2005
Posts: 275

View user's profile Send private message

PostPosted: Fri Aug 12, 2011 7:25 am     Reply with quote

Thanks Ttelmah for suggestion but it still doesn't work....

I tried with:
Code:

#use i2c(master, sda=PIN_B4, scl=PIN_B6,force_sw)

does it enough for PIC16F690 software I2c bus?

The software stay in loop in routine ext_eeprom_ready(). It seems there's no ack from eeprom.

Some year ago I wrote code for PIC16F876A and 24C32 and I haven't any kind of problem....

Thanks for suggestions,

Fabri
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Fri Aug 12, 2011 8:04 am     Reply with quote

The software I2C routines generally run fine (assuming you haven't got something like a very early V4 compiler). 3.249 is OK.
I'd be triple checking:
1) Pin configuration - you have turned _off_ the ADC on pin B4.
2) Connections.
3) Pull up resistors.
4) Address of the EEPROM. - have you got the right pins pulled up/down.

Best Wishes
epalite



Joined: 06 Apr 2008
Posts: 16

View user's profile Send private message

PostPosted: Wed Sep 07, 2011 10:29 pm     Reply with quote

Fabri wrote:

Code:

#use i2c(master, sda=PIN_B4, scl=PIN_B6,force_sw)

does it enough for PIC16F690 software I2c bus?

The software stay in loop in routine ext_eeprom_ready(). It seems there's no ack from eeprom.

Some year ago I wrote code for PIC16F876A and 24C32 and I haven't any kind of problem....


As you are implementing a firmware based master, you have to note if F690 will be fast enough to service the I2C. If you run F690 at 8MHz, you might only be able to effectively drive a bus clock SCL at 50kHz considering all your bus and error handling and processing. A scope capture of what went wrong would be useful. Hope that helps!
zasi80



Joined: 03 Oct 2011
Posts: 4
Location: London

View user's profile Send private message

PostPosted: Tue Oct 04, 2011 3:12 pm     Reply with quote

Hi
I was fighting with I2C and my PIC16f690 for 3 days (I'm beginner), and finally made it work !!! I used EEPROM AT24C512B. I've done simulation and physical circuit however when I swapped EEPROM AT24C512B for 24AA08 in my simulation it didn't work so there must be something about that memory (I didn't go through datasheet). Hope it will help.


Code:

#include<16f690.h>
#fuses NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOMCLR, INTRC_IO
#use delay(clock=4000000)
#use rs232(baud=4800, xmit=pin_b7, rcv=pin_b6)    // to see results on display
#use i2c (master ,sda=PIN_c1,scl=PIN_c2, stream=z )         
//---------------------------



void main()
  {
   int n,  byte111=0;

   delay_ms(1000);
   putc(254);      //for LCD
   putc(1);   
   delay_ms(10);

   i2c_start();      
   i2c_write(0b10100000);   //device address + last bit 0 to write / 1 to read   
   i2c_write(0);         //eeprom address high (8 bits - some bits don't care depending on memory size)
   i2c_write(0);         //eeprom address low  (8 bits)

   i2c_write('4');      //after this instruction address in EEPROM is incremented internally - no need to do in PIC
   i2c_write('5');
   i2c_write('6');            
                  
   i2c_stop();
         
   delay_ms(10);      //delays needed for correct write to eeprom (time depends on memory)
                  //when writing in memory pages (=<64bytes) only one delay at the end is enough

   for(n=0;n<3;n++)         //reads 3 times the same byte
     {
      i2c_start();
      i2c_write(0b10100000);      //dummy write required to clock in address
      i2c_write(0x00);   
      i2c_write(1);            //read address 1
      i2c_start();         
      i2c_write(0b10100001);
      byte111=i2c_read(z,0);      //don't acknowledge if it is last byte in memory page (or random read)
      i2c_stop();            //to be able to set NO ACKNOWLEDGE stream must get a name in #use i2c  (corrected - name is not necessary)
                           // here stream named "z"
      putc(byte111);

     }

   printf("  Done");


  }


Last edited by zasi80 on Wed Oct 05, 2011 12:00 am; edited 3 times in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 04, 2011 3:29 pm     Reply with quote

Code:
 
// don't acknowledge if it is last byte in memory page (or random read)
// to be able to set NO ACKNOWLEDGE stream must get a name in
//#use i2c here stream named "z"

byte111=i2c_read(z,0); 


Are you saying that you must put the 'stream' parameter in the #use i2c()
statement, and that you must specify the stream to be allowed to do a
NACK ? I've never seen this to be true.

It should do a NACK if you do this (no streams specified or used):
Code:

#use i2c (master, sda=PIN_C1, scl=PIN_C2) 

byte111=i2c_read(0); 
 

If that doesn't work, post your CCS compiler version.

Also, CCS has the same basic code, except it's written as driver routines,
in this file:
Quote:
c:\program files\picc\drivers\24512.c
zasi80



Joined: 03 Oct 2011
Posts: 4
Location: London

View user's profile Send private message

PostPosted: Tue Oct 04, 2011 11:54 pm     Reply with quote

Sorry, my mistake
byte111=i2c_read(0); does the same.
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