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

I2C master\slave

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



Joined: 24 Jun 2005
Posts: 206

View user's profile Send private message Send e-mail

I2C master\slave
PostPosted: Sat Aug 06, 2005 5:59 am     Reply with quote

Hi All, after spending the last 4 hours on this fourm and google, i still do not understand what i am doing :(

All i want to do is turn on and off two LED every 2 seconds (this works)
I also want to display whether the LEDs are on or off on a LCD. I can write to the lcd, but my I2C code will not work. I have added a line to show when the slave starts the interrupt, but i never does.

Can somebody please, please help me...

Thank you

Mark
Code:

//Master
#include <16f877a.h>
#fuses NOWDT,HS, NOPROTECT, BROWNOUT, NOPUT, NODEBUG, NOLVP
#use delay(clock=20000000)
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3, FORCE_HW)

int light1stat;
int light2stat;

void main()
{
         light1stat = 1;
   while(1){
      light1stat++;
      i2c_start();
      i2c_write(0xa0);
      i2c_write(light1stat);
      i2c_stop();
      output_low(PIN_D7);
      delay_ms(1000);
      light2stat = 1;
        output_low(PIN_D6);
      delay_ms(1000);
      light1stat = 0;
      output_high(PIN_D7);
      delay_ms(1000);
      light1stat = 0;
      output_high(PIN_D6);
      delay_ms(1000);
      }
}


Code:

//slave
#include <16f877a.h>
#include <marklcd420.c>
#fuses NOWDT,HS, NOPROTECT, BROWNOUT, NOPUT, NODEBUG, NOLVP
#use delay(clock=20000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, FORCE_HW, address=0xa0)

int light1stat;
int light2stat;
int count;

enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);   

void main()
{
   count=1;

      lcd_init();
      printf(lcd_putc,"Ready");
      lcd_gotoxy(1,2);
      printf(lcd_putc,"Light1: %U",light1stat);
      lcd_gotoxy(1,3);
      printf(lcd_putc,"Light2: %U",light2stat);

      while(1){
      
      
      }
}   
      
#INT_SSP
void ssp_interupt ()      
{
   count++;
   lcd_gotoxy(1,4);
   printf(lcd_putc,"Count: %U",count);
   
   i2c_start();
   light1stat = i2c_read();
   //light1stat = i2c_read();
   i2c_stop();
}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sat Aug 06, 2005 8:14 am     Reply with quote

Look at the example programs. Your slave receive is totally wrong. There is an example slave program that will work for you.
Markdem



Joined: 24 Jun 2005
Posts: 206

View user's profile Send private message Send e-mail

PostPosted: Sun Aug 07, 2005 12:59 am     Reply with quote

I have spent the time looking at the example programs, both on the web and in the example folder in CCS, but i dont understand how they work. I need somthing "more" basic. Is the master code at least OK?
Markdem



Joined: 24 Jun 2005
Posts: 206

View user's profile Send private message Send e-mail

PostPosted: Sun Aug 07, 2005 6:18 am     Reply with quote

I have now tired some more debugging on this. My slave programe will never enter the interrupt part. Am i doing somthing wrong here??
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sun Aug 07, 2005 6:59 am     Reply with quote

Look at ex_slave.c That program is meant to emulate a serial eeprom. It could be changed a bit to suit your needs.

I suspect that since you never enter the interrupt, maybe you forgot to add the pullups to the lines.

Also you might try this code out
http://www.ccsinfo.com/forum/viewtopic.php?t=21456
Markdem



Joined: 24 Jun 2005
Posts: 206

View user's profile Send private message Send e-mail

PostPosted: Sun Aug 14, 2005 3:16 am     Reply with quote

Hi All, after retring for a long time to get this working, i am so close, but yet so far.

When i run my new code, it works, but it will only run for a few seconds. After tht, both PIC will just stop. The LEDs on the master stop flashing, and my cound on the LCD on the master will stop. If i run the master without the slave, it will run OK. If i run the slave without the master, it is OK. the problem is only when two chips are on the bus at te same time.

I have looked at all the example programs, but they are all to complex for me and my project, so i cant use them. I just dont understand what they are doing.

The printf statments in the interrupt are only for debugging.

Can sombody please help

Thank you , mark

Code:

#include <16f877a.h>
#fuses NOWDT,HS, NOPROTECT, BROWNOUT, NOPUT, NODEBUG, NOLVP
#use delay(clock=20000000)
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3, FORCE_HW)

int light1stat;
int light2stat;


void main()
{
      
      delay_ms(1000);
      while(1)
      {
        i2c_start();
      delay_ms(100);
      i2c_write(0xa0);
      delay_ms(100);
      i2c_write(0x07);
      delay_ms(100);
      i2c_stop();
      output_low(PIN_D7);
      delay_ms(1000);
      light2stat = 1;
        output_low(PIN_D6);
      delay_ms(1000);
      light1stat = 0;
      output_high(PIN_D7);
      delay_ms(1000);
      light1stat = 0;
      output_high(PIN_D6);
      delay_ms(1000);
      }
}


Code:

#include <16f877a.h>
#include <marklcd420.c>
#fuses NOWDT,HS, NOPROTECT, BROWNOUT, NOPUT, NODEBUG, NOLVP
#use delay(clock=20000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0, FORCE_HW)
#use rs232(baud=9600,parity=N,bits=8,xmit=PIN_C6,rcv=PIN_C7)

#byte PIC_SSPBUF=0x13
#byte PIC_SSPADD=0x93

int isrcount;
char dummy;
int light1stat;
int count;


#INT_SSP
void ssp_interupt ()
{
   dummy = i2c_read();   
   printf("sspbuf=%Lx\r\n",PIC_SSPBUF);
   printf("sspadd=%Lx\r\n",PIC_SSPADD);
   light1stat = i2c_read();
   printf("sspbuf2=%Lx\r\n",PIC_SSPBUF);
   printf("sspadd2=%Lx\r\n",PIC_SSPADD);
   isrcount++;
}
void main()
{

       enable_interrupts(GLOBAL);
      enable_interrupts(INT_SSP);      
      lcd_init();
         light1stat = 0;
      while(1)
      {
      lcd_gotoxy(1,1);
      printf(lcd_putc,"Count: %U",count);
      lcd_gotoxy(1,2);
      printf(lcd_putc,"Light1: %S",light1stat);
      lcd_gotoxy(1,3);
      printf(lcd_putc,"dummy: %U",dummy);
      lcd_gotoxy(1,4);
       printf(lcd_putc,"ISR count: %U",isrcount);
       count++;      
      }

}
ddscott



Joined: 17 Aug 2005
Posts: 4
Location: Livermore, CA

View user's profile Send private message

PostPosted: Tue Aug 23, 2005 9:01 am     Reply with quote

I don't know if you ever got a solution to your problem, but this is what I use to handle the i2c interrupt. It seems to work as desired, I use an Aardvark I2C emulator to communicate with the slave PIC.

Hope this helps.

Code:
include "C:\Program Files\PICC\Projects\Bio_Briefcase\i2c_0816.h"

int8 buffer;
boolean rec;
long j;




#int_SSP

void SSP_isr()

{

   if (i2c_poll() == TRUE)
   {
      rec=true;
      buffer=i2c_read();
   }
}


void check_int()
{
long j;
if (buffer == 0x11)
   {
   rec = false;
   buffer = 0;
      for (j=0; j<10000; j++)
         {
          output_toggle(pin_a1);
          delay_ms(1);
         }
   }
return;
}


void main()

{
   int8 data;
   long i;
   rec=false;

   buffer = 0;


   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(VREF_LOW|-2);
   setup_oscillator(False);
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);

   #priority ssp

   while (true) {
      data = buffer;
      rec=false;
      buffer = 0;

         if (data == 0x33)
            {
             data = 0;

               for (i=0; i<30000; i++)
                  {

                     output_toggle(pin_a0);
                     delay_ms(1);

                        if (rec == true)
                        {
                           check_int();
                        }

                  }

            }
       }
}
ella
Guest







Can it be used with Dimax u2c-11 ?
PostPosted: Wed Aug 24, 2005 9:56 am     Reply with quote

I'm using usb to i2c adater from dimax :U2C-11 PC-I2C/SPI/GPIO Interface Adapter. USB Solution...
Do you think your example will work for me?
ddscott



Joined: 17 Aug 2005
Posts: 4
Location: Livermore, CA

View user's profile Send private message

I2C emulators
PostPosted: Wed Aug 24, 2005 10:28 am     Reply with quote

It should work just fine with any emulator. Just be wary that the way PIC stores it's address might be different than how the emulator sends the address. If I want my i2c emulator to talk to address 0x20, I need to set the PIC to respond to address 0x40.

I was able to get the PIC to write data to the emulator yesterday. I monitor bit 2 in the SSPSTAT register. When it is a 1, the master has sent a read cmd, and I jump to a routine that writes data. Don't use i2c_start and i2c_stop instructions with the slave.

If you disable the interrupts to perform a high priority task, you need to reset the SSPCON register in software. For the PIC I am using, 16f767, I load the register with 0x36.

Hope this helps.
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