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

16F877A i2c to 16F690

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



Joined: 21 Apr 2012
Posts: 7

View user's profile Send private message

16F877A i2c to 16F690
PostPosted: Sat Apr 21, 2012 4:46 pm     Reply with quote

Hello i have been at this for a bit and have not found what might be my problem. I had searched up what others had done and turn out empty there too. i'm using v. 4.120 of the ccs c and real world app.

List of questions that might solve the problem.

1. I'm using the sample code to make my 16f690 a slave and its running at 8 mhz. The master is 16F877A and its on a crystal of 20mhz. would this be a cause that my all results to be 0xff? what would one do to correct this.

2. Is a buffer array necessarily need?

my code.

Master
Code:


#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,fast,sda=PIN_C4,scl=PIN_C3,force_hw)



#include "C:\Users\Alique\Documents\Dropbox\SCHOOL\data ack\lcd_4bit.c"
#include "C:\Users\Alique\Documents\Dropbox\SCHOOL\data ack\I2C_COM.c"


#byte TRISA = 0x85
#byte PORTA = 0x05


int adc_0, copy1;


void adc(void);

void read()
{
   int data;
   i2c_start();
   i2c_write(0xa0);
   i2c_write(0x00);
   i2c_write("a");
   i2c_stop();
   delay_ms(1000);
   i2c_start();
   i2c_write(0xa0);
   i2c_write(0x00);
   i2c_start();
   i2c_write(0xa1);
   data = i2c_read(0);
   i2c_stop();
   
   dsp_add(L2B1);
   text_1("return:");
   dbin(data);
}

void main()
{

   setup_adc_ports(AN0_AN1_AN3);
   setup_adc(ADC_CLOCK_DIV_2);

   TRISA = 0xfb;
   ini(2);
dsp_add(L1B1);
   text_1("ADC_0:");
   dsp_add(L2B1);


while(1)
{
adc();
if(copy1 != adc_0)
{
dsp_add(L1B8);
dbin(adc_0);
read();
}
}
}

void adc(void)
{
copy1=adc_0;
SET_ADC_CHANNEL(0);
delay_ms(5); 
adc_0=READ_ADC();
}



slave

Code:


#include <16F690.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOCPD                    //No EE protection
#FUSES NOPUT                    //No Power Up Timer
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled

#use delay(clock=8000000)
#use i2c(Slave,Fast,sda=PIN_C4,scl=PIN_C3,address=0xa0)


#byte TRISB = 0x86
#byte TRISC = 0x87

#byte PORTB = 0x06
#byte PORTC = 0x07

#bit C0 =0x07.0


INT buffer[0x08],address;


#int_SSP
void ssp_interupt ()
{
   BYTE incoming, state;

   state = i2c_isr_state();

   if(state < 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      if(state == 1)                     //First received byte is address
         address = incoming;

      if(state == 2)                     //Second received byte is data
         buffer[address] = incoming;

   }
   if(state == 0x80)                     //Master is requesting data
   {
         i2c_write(buffer[address]);
   }
}


void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_16,255,4);
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_8MHZ);

   
   TRISC = 0XFe;
 
   WHILE(1)
   {
        C0=1;
        delay_us(buffer[0x00]);
        C0=0;
        delay_us(buffer[0x00]); 
   }
   
}


if there is any thing missing i will post.

thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Apr 21, 2012 5:30 pm     Reply with quote

Code:
....................    i2c_write("a"); 
0045:  MOVWF  24
0046:  CALL   02B
....................     
....................    i2c_write('a'); 
0047:  MOVLW  61
0048:  MOVWF  24
0049:  CALL   02B

What's the difference between double quotes and single quotes ?
What does each one send to the i2c_write() routine ?
alique89



Joined: 21 Apr 2012
Posts: 7

View user's profile Send private message

PostPosted: Sat Apr 21, 2012 5:41 pm     Reply with quote

Originally i was using an int in the place of the "a" so that it looked like this

Code:


 int data;
   i2c_start();
   i2c_write(0xa0);
   i2c_write(0x00);
   i2c_write(adc_0);
   i2c_stop();
   delay_ms(1000);
   i2c_start();
   i2c_write(0xa0);
   i2c_write(0x00);
   i2c_start();
   i2c_write(0xa1);
   data = i2c_read(0);
   i2c_stop();   


In asm i do see there is a huge difference between the two so i'm not sure if that is the starting point of my problem?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Apr 21, 2012 5:46 pm     Reply with quote

Use the single quotes, and slow down the master PIC to 4 MHz.
temtronic



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

View user's profile Send private message

PostPosted: Sat Apr 21, 2012 6:42 pm     Reply with quote

also be sure to use the correct value I2C bus pullup resistors !
Ttelmah



Joined: 11 Mar 2010
Posts: 19349

View user's profile Send private message

PostPosted: Sun Apr 22, 2012 4:08 am     Reply with quote

and get rid of the 'Fast' keyword in the slave.
Slave I2C devices do not specify the speed. This is controlled by the master.

Best Wishes
jeremiah



Joined: 20 Jul 2010
Posts: 1323

View user's profile Send private message

PostPosted: Sun Apr 22, 2012 7:25 am     Reply with quote

Also, take some time to look up i2c_isr_state() in the compiler manual. You are doing your ISR incorrectly in quite a few places. They even give an example of how to do the ISR there (though I think they have a typo: i@c ).
alique89



Joined: 21 Apr 2012
Posts: 7

View user's profile Send private message

PostPosted: Sun Apr 22, 2012 10:55 am     Reply with quote

Here is what i have done so far.

1. changed the Quotes.

2. checked the resistor values to be between 10 k and 6k

3. i looked over the slave ssp isr and found 3 logic errors.

4. removed fast out of the #USE I2C command.

Still no luck.

@jeremaih asides the logic errors that i have seen you point out in other post, was there anything else? i did look over the manual and was more confused at the end of reading it.

@pcm i can't lower the clock due to it being a dev board with a Crystal and i need it to remain at 20 mhz for other communications. Unless you meant to assign a speed for the i2c to communicate with. I could also bring the slave chip up to the same speed.
jeremiah



Joined: 20 Jul 2010
Posts: 1323

View user's profile Send private message

PostPosted: Sun Apr 22, 2012 12:05 pm     Reply with quote

I would say go ahead and either update your original post with the corrected code or post it new so we can take a look at the changes.

Also of note: At SOME point in the 4.1xx series, they changed how the slave address is input in the #use i2c(). For a while they used the 7bit notation (0x50), but later on switched back to the 8 bit notation (0xa0). I don't remember when they switched back, so the first thing I would check is if your ISR is firing at all. find a debug line, set it low, and then call output_toggle() on that pin in the ISR each time it fires. Make sure the ISR is even being fired off. Just use something simple in the master. Have the master simply do:

Code:

while(TRUE){
   i2c_start();
   i2c_write(YOUR_SLAVES_ADDRESS_HERE_8BIT_FORMAT);
   i2c_stop();
   delay_ms(1000);
}


Theoretically that should fire off the ISR every second on the slave side.

The first step is to verify some kind of communication happens. After that, we'll look at verifying the actual data coming across.
Ttelmah



Joined: 11 Mar 2010
Posts: 19349

View user's profile Send private message

PostPosted: Sun Apr 22, 2012 12:39 pm     Reply with quote

Two comments:

Your resistor value is _high_ depends on the wire length (capacitance of bus), but typical values for a 5v 'fast' bus are 2.2K to 4.7K.

PCM programmer has posted a little utility program here, that scans an I2C bus and reports every slave device it finds. Run this instead of your master for testing.

Best Wishes
alique89



Joined: 21 Apr 2012
Posts: 7

View user's profile Send private message

PostPosted: Sun Apr 22, 2012 3:16 pm     Reply with quote

we have progress!! Very Happy

OK so i'm now pretty sure its the slave side that i'm going to need to fine tune. I know for sure that there is communication and that a values is sent.

the code is all new. i restarted form scratch. so there will be some new errors for sure.


master i2c
Code:
 
#include <16F877A.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=20000000)
#use rs232(baud=26000,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)


#include "C:\Users\Alique\Documents\Dropbox\SCHOOL\data ack\lcd_4bit.c"
#include "C:\Users\Alique\Documents\Dropbox\SCHOOL\data ack\I2C_COM.c"


#byte TRISA = 0x85
#byte PORTA = 0x05


int adc_0, copy1,data ;


void adc(void);

void write()

   i2c_start();
   i2c_write(0xa0);
   i2c_write(0x00);
   i2c_write(adc_0);
   i2c_stop();
}

void main()
{

   setup_adc_ports(AN0_AN1_AN3);
   setup_adc(ADC_CLOCK_DIV_2);

   TRISA = 0xfb;
   ini(2);
dsp_add(L1B1);
   text_1("ADC_0:");
   dsp_add(L2B1);


while(1)
{
adc();
if(copy1 != adc_0)
{
dsp_add(L1B8);
dbin(adc_0);
write();

}
}
}

void adc(void)
{
copy1=adc_0;
SET_ADC_CHANNEL(0);
delay_ms(5); 
adc_0=READ_ADC();
}




Slave code

Code:


#include <16F690.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOCPD                    //No EE protection
#FUSES NOPUT                    //No Power Up Timer
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled

#use delay(clock=8000000)
#use i2c(Slave,sda=PIN_B4,scl=PIN_B6,force_hw,address=0xa0)


#byte TRISB = 0x86
#byte TRISC = 0x87

#byte PORTB = 0x06
#byte PORTC = 0x07

#bit C0 =0x07.0
#bit C1 =0x07.1

INT buffer[0x02],address;




#int_SSP
void SSP_isr(void)
{

 BYTE incoming, state;

   state = i2c_isr_state();
 C1=!C1;
   if(state <= 0x80)                     //Master is sending data
   {
      incoming = i2c_read();
      if(state == 1)                     //First received byte is address
         address = incoming;

      if(state == 2)                     //Second received byte is data
         buffer[address] = incoming;

   }
   if(state >= 0x80)                     //Master is requesting data
   {
         i2c_write(buffer[address]);
   }
}



void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_16,255,1);
   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   setup_oscillator(OSC_8MHZ);

    TRISC = 0XFC;
 
   WHILE(1)
   {
        C0=!C0;
        delay_ms(buffer[0x00]);
     
   }

}


so far i'm not seeing and results or dimming of the led i'm using.
Ttelmah



Joined: 11 Mar 2010
Posts: 19349

View user's profile Send private message

PostPosted: Mon Apr 23, 2012 1:51 am     Reply with quote

Before worrying about the slave, get the master reading the ADC.
The clock rate you have selected for the ADC, is about 16* faster than it can handle. I doubt if it'll be returning anything even remotely useable. Data sheet Table 11-1. "Tad vs. Maximum device operating frequencies". 2Tosc (ADC_CLOCK_DIV_2) is allowed up to a maximum CPU clock of 1.25MHz.....

Best Wishes
alique89



Joined: 21 Apr 2012
Posts: 7

View user's profile Send private message

PostPosted: Mon Apr 23, 2012 4:41 am     Reply with quote

The ADC is outputting fine. i check by changing it to a optimal speed recommended by the data sheet and gave me the same results.

I'll be at the shop today so i know i'll have better test equipment then the analog scope i was using. i may also try to get two of the same chips to master/ slave and see if its speed related or code.
Ttelmah



Joined: 11 Mar 2010
Posts: 19349

View user's profile Send private message

PostPosted: Mon Apr 23, 2012 7:32 am     Reply with quote

Seriously, it _won't_ be 'outputting just fine'. Clocking this type of ADC too fast will mean you probably have something like 3-4bits of real resolution, if that. Part of the lesson here, is _read the data sheet, and follow what it says_, don't assume things are 'OK', because it looks vaguely alright.

Best Wishes
alique89



Joined: 21 Apr 2012
Posts: 7

View user's profile Send private message

PostPosted: Wed Apr 25, 2012 7:25 pm     Reply with quote

Sorry Ttelmah there was a misunderstanding. You were right, it was indeed one of three problems needing to be solved. With the right equipment I found I have reversed the wiring of the scl and sda, and that I had a nack problem in my code.

I will be posting the final product when i have more time.
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