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

PIC24FJ64GA004 I2C not working

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



Joined: 08 Nov 2017
Posts: 6
Location: South Africa

View user's profile Send private message

PIC24FJ64GA004 I2C not working
PostPosted: Wed Nov 08, 2017 4:31 pm     Reply with quote

I seem to have hit a snag in my code development with the PIC24FJ64GA004. All the ports that I require work except for the I2C. I have tried various permutations but can't seem to get any change on the port at all.

These are the use I2C codes I've tried:
Code:

//#use I2C(MASTER,SCL=SCL1,SDA=SDA1)
//#use i2c(stream=I2C1_STREAM,Master,I2C1,SLOW,FORCE_HW)
//#use i2c(stream=I2C2_STREAM,Master,I2C2,SLOW,FORCE_HW)
//#use i2c(stream = I2C2_Stream, Master,Fast,sda=SDA2,scl=SCL2, FORCE_SW)
//#use i2c(stream = I2C1_Stream, Master,Fast,sda=SDA1,scl=SCL1, FORCE_SW)

Code I've tried to get the I2C to work:
Code:

//SET_TRIS_B(0);
//i2c_start();
//i2c_write(0x40);
//i2c_write(I2C1_STREAM, 'a');
//i2c_write(I2C2_STREAM, 'a');
//i2c_stop();

Any advice would be much appreciated
dyeatman



Joined: 06 Sep 2003
Posts: 1934
Location: Norman, OK

View user's profile Send private message

PostPosted: Wed Nov 08, 2017 4:40 pm     Reply with quote

Try looking at this post. It should help.

http://www.ccsinfo.com/forum/viewtopic.php?t=44153&highlight=pic24fj64ga004
_________________
Google and Forum Search are some of your best tools!!!!
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Nov 08, 2017 5:16 pm     Reply with quote

You really should goto the code library here and download PCM P's 'I2C Scanner' program. Compile, install, run. It WILL confirm the PIC can acess the I2C device, displaying all available device addresess.

Like a 1Hz LED program, the I2C scanner is a 'must have' program to confirm the hardware is goo.

Jay
Robotix0805



Joined: 08 Nov 2017
Posts: 6
Location: South Africa

View user's profile Send private message

PostPosted: Thu Nov 09, 2017 2:41 am     Reply with quote

Thank you for all the replies and advice. Will try again tonight :-)
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Thu Nov 09, 2017 3:42 am     Reply with quote

#use i2c(stream=I2C1_STREAM,Master,I2C1,SLOW)

Should have worked.
Using the hardware port name _forces_ the hardware port to be used. Overrides FORCE_HW or FORCE_SW completely.

How are the analog ports configured?. Critical....

The problem Jeremiah was having was that the analog was being left enabled on the pins. Though the default setup will adjust the TRIS, is does not adjust the ANSEL register. You see this on a PIC18Fxx50, where if you have the PortB ANSEL fuse set, it will stop peripherals on PortB working, unless you specifically turn off the ANSEL bits with an analog setup.

It sounds as if your pins may well be set as analog, since otherwise the software I2C would always work.
Robotix0805



Joined: 08 Nov 2017
Posts: 6
Location: South Africa

View user's profile Send private message

PostPosted: Thu Nov 09, 2017 3:59 am     Reply with quote

Been using

setup_adc(adc_off);

before I even setup the tris registers. Currently the tris registers are set to outputs on the I2C pins.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Thu Nov 09, 2017 4:02 am     Reply with quote

No.....

That turns off the ADC, but does not release the ports.

setup_adc_ports(NO_ANALOGS);

is needed to release the ANSEL bits.
Robotix0805



Joined: 08 Nov 2017
Posts: 6
Location: South Africa

View user's profile Send private message

PostPosted: Thu Nov 09, 2017 4:08 am     Reply with quote

Ah cool. Will add it to my code. Did try that earlier as well but then my #use I2C might have been wrong.
Robotix0805



Joined: 08 Nov 2017
Posts: 6
Location: South Africa

View user's profile Send private message

PostPosted: Fri Nov 10, 2017 1:50 am     Reply with quote

Thank you for all the suggestions. I still can't get the code to work. So decided to attach my code to see if anyone can spot something really obvious I'm doing wrong. Will be changing out the chip later today just to eliminate that as a problem. Tried the I2C Scanner, but all it does is give me a high or ACK on each address. On my logic analyzer it shows the pins staying high. As an absolute last resort (Not keen at all) I'll fall back onto XC16 just to see if I can get the I2C to work.

**********Main File**********

Code:
#include <24FJ64GA004.h>
#include "main.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <interrupts.h>

#use delay (clock = 4000000)

void main()
{
   char data;
   set_tris_a(0);
   set_tris_c(1024);
   SET_TRIS_B(780);

   setup_adc(adc_off);
   setup_adc_ports(NO_ANALOGS );

   setup_timer2(TMR_INTERNAL |TMR_DIV_BY_256 ,4096);
   enable_interrupts(INT_TIMER2);

      output_float(SDA2);
      output_float(SCL2);
      output_high(wirelessSet);
   
      while(1)
      {
      //I2C Write to EEPROM 24LC512
      i2c_start();
      i2c_write(I2C2_STREAM,0xa0);
      i2c_write(I2C2_STREAM,1);
      i2c_write(I2C2_STREAM,2);
      i2c_write(I2C2_STREAM,'a');
      i2c_stop();
      //i2c_write(I2C1_STREAM, 'a');
      i2c_write(I2C2_STREAM, 'a');
      i2c_stop();
      
      //I2C Read from EEPROM 24LC512
      i2c_start();
      i2c_write(0xa0);
      i2c_write(I2C2_STREAM,1);
      i2c_write(I2C2_STREAM,2);
      i2c_start();
      i2c_write(0xa1);
      data=i2c_read(0);
      i2c_stop();
      printf("Response: %c\r\n", data);
         delay_ms(100);
   }
}



**************interrupts.h************

Code:
#int_TIMER2
void TIMER2_isr()
{
    output_toggle(heartbeatLED);
}


************main.h****************

Code:

#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOJTAG                   //JTAG disabled
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES ICSP1                    //ICD uses PGC1/PGD1 pins
//#FUSES IOL1WAY                  //Allows only one reconfiguration of peripheral pins
#FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
#FUSES NOWINDIS                 //Watch Dog Timer in Window mode
#FUSES WPRES128                 //Watch Dog Timer PreScalar 1:128
#FUSES WPOSTS16                 //Watch Dog Timer PostScalar 1:32768
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES OSCIO                    //OSC2 is general purpose output
#FUSES NOPR                     //Pimary oscillaotr disabled
#FUSES I2C1SELD 

//Serial UART1
#pin_select U1TX=   PIN_B13
#pin_select U1RX=   PIN_B12
#define wirelessSet PIN_A1
#define cts       PIN_A3
#define dts       PIN_A2

//I2C1
#define SDA1       PIN_B8
#define SCL1       PIN_B9

//I2C2
#define SDA2       PIN_B2
#define SCL2       PIN_B3

//General IO
#define heartbeatLED   PIN_A0

#use i2c(stream=I2C1_STREAM,Master,I2C1,SLOW,FORCE_HW)
#use i2c(stream=I2C2_STREAM,Master,I2C2,SLOW,FORCE_HW)
#use rs232(UART1,baud=9600,parity=N,bits=8)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 10, 2017 9:40 am     Reply with quote

1. Do you have pull-up resistors on SDA and SCL ? What are the values ?

2. Problem: You have no delay after your write operation.

Look in the 24LC512 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/21754M.pdf
Look at the table on page 4, at this parameter:
Quote:
TWC Write cycle time (byte or page) 5 ms

It takes time for the eeprom to do a write operation.
You have to handle this delay in your driver program. It's not done
automatically.

You could add a delay statement after the eeprom write code ends.
Example:
Code:

i2c_start();
.
.
.
i2c_stop();
delay_ms(5);

But this isn't the best way. The 5 ms number is the max possible delay.
The eeprom could finish it earlier than that.

Let's look at the code in the supplied CCS driver file, 24512.c.
This file is in your CCS installation \Drivers folder.
Note how it's logically laid out. It doesn't have 1's and 2's. It has
parameters for address and data. Then note the section shown in bold
below. This a way of doing the Write Cycle delay more exactly. It's called
"Ack polling". It polls (reads) the eeprom chip until it gets an Ack.
When it gets an Ack, the eeprom write cycle is done.
Quote:
void write_ext_eeprom(long int address, BYTE data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();

i2c_start();
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}


i2c_stop();
}

You can read about Ack polling in this section of the 24LC512 data sheet:
Quote:
7.0 ACKNOWLEDGE POLLING
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Fri Nov 10, 2017 10:22 am     Reply with quote

He is also writing to the port after sending stop.
Not actually sure what this will do. Suspect it'll cause an error though....
Code:

      i2c_stop();
      //i2c_write(I2C1_STREAM, 'a');
      i2c_write(I2C2_STREAM, 'a');
      i2c_stop();


Also he should be using the stream names for the start and stop as well.
If you setup multiple I2C's, the stream names need to be used for everything.
Robotix0805



Joined: 08 Nov 2017
Posts: 6
Location: South Africa

View user's profile Send private message

PostPosted: Mon Nov 13, 2017 3:38 am     Reply with quote

So over the weekend I replaced the micro with a new one and the I2C1 port works like a charm. However the I2C2 port still seems to be giving issues. It'll work and then not work and then work again and so on.

As for the strange I2C commands. I'm not for the moment attempting to connect to the I2C devices on the bus. Infact they are still in the components bin. I'm only trying to get the I2C to work. Using my logic analyzer and pull up resistors I can observe the stability of the bus.

Now attempting to make the I2C2 bus to work. Will update if I find a solution that makes the bus work consistently.
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