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

i2c...arrgghh....help!!!

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



Joined: 04 May 2006
Posts: 17
Location: Sweden

View user's profile Send private message

i2c...arrgghh....help!!!
PostPosted: Mon May 08, 2006 6:51 am     Reply with quote

Hi can someone please take a look at my code before I totally lose it over here:

What I want to is: send two bytes of data from a master-PIC to a slave-PIC. Nothing more. I�ve tried looking at some examples but it just doesn�t work.

Hopefully you can see what belongs to i2c and not. The master uses send_to_slave() to send the two bytes, The slave uses an interrupt-routine to receive them. What am I doing wrong?

MASTER-code:
================

Code:
#include <puls.H>

#fuses NOWDT

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





int16 freq=20;    //aktuell frekvens f�r mastern

int8  step=1;     //Vald steg-niv� (1-4)

int8  channel=1;  //Vald kanal (1-3)

byte pressed=0;   //nedtryckt tangent



byte tmp4;  //anv av lcd_write_as_hex

byte tmp3;  //anv av timer1_isr()

byte tmp2;  //anv av lcd_info()

byte tmp1;

int16 temp;

int16 temp2=0;

int16 temp3=0;

boolean write_zero=false;





struct lcd_map

{

    int data:8;

    boolean rs;

    boolean enable;

    boolean rw;

    int unused:5;

}

lcd;

#byte lcd = 0x08







//CPU1 - Timer 1

int16 t1sv=3035; //Start-v�rde (65535-3035=62500) f�r Timer1 (ger 20Hz)

int16 t1svmod;



//F�r de andra processorerna

int16 freq2=20;   //frekvens - CPU2

int8  step2=4;    //stegniv� - CPU2

int16 freq3=20;   //frekvens - CPU3

int8  step3=1;    //stegniv� - CPU3









//(((((((((((((((((((((((( INTERRUPTS ))))))))))))))))))))))))))))



#int_timer1    //KANAL 1

timer1_isr()

{

   tmp3=TIMER1_CTRL;

   TIMER1_CTRL=0x00;

   t1svmod=t1sv;

   TIMER_1_LOW=t1svmod&0x00FF; //laddar med den f�rsta byten av t1sv

   t1svmod >>= 8; //shiftar 8 bitar till h�ger

   TIMER_1_HIGH=t1svmod&0x00FF;//laddar med den andra byten av t1sv

   port_c ^= 1;   //0->1 el. 1->0

   TIMER1_CTRL=tmp3;

}





//%%%%%%%%%%%%%%%%%%%%%%%% FUNKTIONER %%%%%%%%%%%%%%%%%%%%%%%%%%%%



byte keyboard_in()   //en funktion som kollar vilken knapp som �r intryckt och returnerar motsvarande v�rde

{

   set_tris_b(0xF0); //v�ljer de f�rsta �tta benen p� port_b som ing�ngar, vilket g�r att de interna pull_up-most�nden kopplas hit

   port_b_pullups(true); //drar upp pull_up-motst�nden till ettor



      port_b = 0x0E;             //aktiverar f�rsta kolumnen f�r att sedan f�rs�ka hitta den knapp som �r nedtryckt genom bit-testing...

      if(!bit_test (port_b,7))

            return 3;            //betyder att knapp 3 �r nedtryckt -> avsluta intruktionen och returnera v�rdet 3

      if(!bit_test (port_b,4))

            return 0;

      if(!bit_test (port_b,5))

            return 1;

      if(!bit_test (port_b,6))

            return 2;



      port_b = 0x0D;                   //se ovan

      if(!bit_test (port_b,7))

            return 7;

      if(!bit_test (port_b,4))

            return 4;

      if(!bit_test (port_b,5))

            return 5;

      if(!bit_test (port_b,6))

            return 6;





      port_b = 0x0B;                //se ovan

      if(!bit_test (port_b,7))

            return 11;

      if(!bit_test (port_b,4))

            return 8;

      if(!bit_test (port_b,5))

            return 9;

      if(!bit_test (port_b,6))

            return 10;





      port_b = 0x07;             //se ovan

      if(!bit_test (port_b,7))

            return 15;

      if(!bit_test (port_b,4))

            return 12;

      if(!bit_test (port_b,5))

            return 13;

      if(!bit_test (port_b,6))

            return 14;



}



void lcd_waitbusy()

{

   set_tris_d(0xFF);

   lcd.rw = true;

   while(1)

   {

      delay_us(50);

      if(bit_test(lcd.data,7)==0)

      {

            set_tris_d(0x00);

            lcd.rw = false;

            return;

      }

   }

}



void lcd_control(byte ctrl_in)

{

   lcd_waitbusy();

   lcd.rs=false;

   lcd.rw=false;

   lcd.data = ctrl_in;

   lcd.enable=true;

   delay_cycles(4);

   lcd.enable=false;

   delay_ms(2);

   lcd.data = 0x00;

}



void lcd_data(byte data_in)

{

   lcd_waitbusy();

   lcd.rs=true;

   lcd_waitbusy();

   lcd.data=data_in;

   lcd.enable=true;

   delay_cycles(4);

   lcd.enable=false;

   delay_ms(2);

   lcd.data = 0x00;

}



void lcd_write_as_hex(byte b) //funktion som skriver ut en byte i hex-form

{

   tmp4=b>>4;

   if(tmp4>9)

      lcd_data(tmp4+0x37);

   else

      lcd_data(tmp4+0x30);

   tmp4=b&0xF;

   if(tmp4>9)

      lcd_data(tmp4+0x37);

   else

      lcd_data(tmp4+0x30);

}



void calc_write_freq()  //skriver ut frekvens p� LCD:n

{

   switch(channel)

   {

      case 1:

      temp2=freq;

      break;



      case 2:

      temp2=freq2;

      break;



      case 3:

      temp2=freq3;

      break;

   }



   temp3=temp2/1000;

   if(temp3>0)

   {

      write_zero=true;

      lcd_data(temp3+0x30);

      temp3=temp3*1000;

      temp2=temp2-temp3;

   }



   temp3=temp2/100;

   if(temp3>0 || write_zero)

   {

      lcd_data(temp3+0x30);

      write_zero=true;

      temp3=temp3*100;

      temp2=temp2-temp3;

   }





   temp3=temp2/10;

   if(temp3>0 || write_zero)

   {

      lcd_data(temp3+0x30);

      temp3=temp3*10;

      temp3=temp2-temp3;

   }

   write_zero=false;



   lcd_data(temp3+0x30);



   lcd_data(' ');

   lcd_data('H');

   lcd_data('z');



}



void info_lcd()   //Skriver ut vald kanal, stegniv� och frekvens till LCD:n

{

   lcd_control(0x01);

   lcd_data('K');

   lcd_data('a');

   lcd_data('n');

   lcd_data('a');

   lcd_data('l');

   lcd_data(':');

   lcd_write_as_hex(channel);

   lcd_data(' ');

   lcd_data('S');

   lcd_data('t');

   lcd_data('e');

   lcd_data('g');

   lcd_data(':');

   switch(channel)

   {

      case 1:

      lcd_write_as_hex(step);

      break;



      case 2:

      lcd_write_as_hex(step2);

      break;



      case 3:

      lcd_write_as_hex(step3);

      break;

   }

   lcd_control(0x41 + 0x80);

   lcd_data('F');

   lcd_data('r');

   lcd_data('e');

   lcd_data('k');

   lcd_data('v');

   lcd_data('e');

   lcd_data('n');

   lcd_data('s');

   lcd_data(':');



   calc_write_freq();



}



void send_to_slave() //I2C-funktion

{

   switch(channel)

   {

      case 2: //skicka till slav-1

      i2c_start();

      i2c_write(0xa0);     //adress

      i2c_write(freq2>>8);    //data

      i2c_write(freq2&0x00FF);

      i2c_stop();

      break;



      case 3: //skicka till slav-2

      i2c_start();

      i2c_write(0x50);     //adress

      i2c_write(freq3>>8);    //data

      i2c_write(freq3&0x00FF);

      i2c_stop();

      break;



      default:

      break;

   }

}







//������������������������������������������������������������������������������

//������������������������������������ MAIN ������������������������������������

//������������������������������������������������������������������������������



main()

{

   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);

   setup_port_a(NO_ANALOGS);

   setup_adc(ADC_CLOCK_INTERNAL);

   setup_psp(PSP_DISABLED);

   setup_ccp1(CCP_OFF);

   setup_ccp2(CCP_OFF);

   setup_spi(spi_master | SPI_L_TO_H | spi_clk_div_4);



//====================== I/O ============================



   set_tris_e(0x00);  // PORT-E: alla utg�ngar

   set_tris_d(0x00);  // PORT-D: alla utg�ngar

   set_tris_c(0x00);  // PORT-C: alla utg�ngar



//=======================================================



//================== SETUP - Timer1 =====================



   enable_interrupts(INT_TIMER1);

   enable_interrupts(GLOBAL);

   TIMER1_CTRL=0x11;



//=======================================================





//=================== SETUP - LCD =======================



   lcd_control(0x38);

   lcd_control(0x06);

   lcd_control(0x0C);

   lcd_control(0x01);



   info_lcd();



//=======================================================



   while(1)

   {

      pressed=keyboard_in();



      //UPP

      if(pressed==1)

      {

         pressed=0;

         switch(channel)

         {

            case 1:

            if(step==4 || freq>7000) freq=freq+200;

            else if(step==3 || freq>6000) freq=freq+100;

            else if(step==2 || freq>5000) freq=freq+50;

            else freq=freq+5;

            if(freq>13000) freq=13000;

            //................................

            if(freq>40 && TIMER1_CTRL==0x11) TIMER1_CTRL=0x01;

            temp=2*freq;

            if(TIMER1_CTRL==0x11) temp=2495000/temp;

            else temp=4990000/temp;

            t1sv=65535-temp;

            break;



            case 2:

            if(step2==4 || freq2>7000) freq2=freq2+200;

            else if(step2==3 || freq2>6000) freq2=freq2+100;

            else if(step2==2 || freq2>5000) freq2=freq2+50;

            else freq2=freq2+5;

            if(freq2>13000) freq2=13000;

            send_to_slave();

            break;



            case 3:

            if(step3==4 || freq3>7000) freq3=freq3+200;

            else if(step3==3 || freq3>6000) freq3=freq3+100;

            else if(step3==2 || freq3>5000) freq3=freq3+50;

            else freq3=freq3+5;

            if(freq3>13000) freq3=13000;

            send_to_slave();

            break;

         }

         info_lcd();

         delay_ms(500);

      }



      //NER

      if(pressed==2)

      {

         pressed=0;

         switch(channel)

         {

            case 1:

            if(step==4 || freq>7000) freq=freq-200;

            else if(step==3 || freq>6000) freq=freq-100;

            else if(step==2 || freq>5000) freq=freq-50;

            else freq=freq-5;

            if(freq<20) freq=20;

            //.....................................

            if(freq<=40 && TIMER1_CTRL==0x01) TIMER1_CTRL=0x11;

            temp=2*freq;

            if(TIMER1_CTRL==0x11) temp=2495000/temp;

            else temp=4990000/temp;

            t1sv=65535-temp;

            break;



            case 2:

            if(step2==4 || freq2>7000) freq2=freq2-200;

            else if(step2==3 || freq2>6000) freq2=freq2-100;

            else if(step2==2 || freq2>5000) freq2=freq2-50;

            else freq2=freq2-5;

            if(freq2<20) freq2=20;

            send_to_slave();

            break;



            case 3:

            if(step3==4 || freq3>7000) freq3=freq3-200;

            else if(step3==3 || freq3>6000) freq3=freq3-100;

            else if(step3==2 || freq3>5000) freq3=freq3-50;

            else freq3=freq3-5;

            if(freq3<20) freq3=20;

            send_to_slave();

            break;

         }

         info_lcd();

         delay_ms(500);

      }



      //STEP

      if(pressed==5)

      {

         switch(channel)

         {

            case 1:

            step++;

            if(step>4) step=1;

            break;

            case 2:

            step2++;

            if(step2>4) step2=1;

            break;

            case 3:

            step3++;

            if(step3>4) step3=1;

            break;

         }

         info_lcd();

         delay_ms(500);

      }



      //KANAL

      if(pressed==4)

      {

         channel++;

         if(channel>3) channel=1;

         info_lcd();

         delay_ms(500);

      }

   }

}

//������������������������������������������������������������������������������



SLAVE-code:
============
Code:
#include <puls.H>

#fuses HS,NOWDT,NOPROTECT

#use i2c(slave,sda=PIN_C4,scl=PIN_C3,address=0xa0)





int16 freq=20;    //aktuell frekvens f�r denna slav

int16 freq_tmp=20;





int16 temp;

byte tmp3;  //anv av timer1_isr()

byte received;



typedef enum {FIRST_READ, LAST_READ} I2C_STATE;

I2C_STATE i2c_status=FIRST_READ;



//Timer 1

int16 t1sv=3035; //Start-v�rde (65535-3035=62500) f�r Timer1 (ger 20Hz)

int16 t1svmod;







//(((((((((((((((((((((((( INTERRUPTS ))))))))))))))))))))))))))))



#int_timer1    //KANAL 1

timer1_isr()

{

   tmp3=TIMER1_CTRL;

   TIMER1_CTRL=0x00;

   t1svmod=t1sv;

   TIMER_1_LOW=t1svmod&0x00FF; //laddar med den f�rsta byten av t1sv

   t1svmod >>= 8; //shiftar 8 bitar till h�ger

   TIMER_1_HIGH=t1svmod&0x00FF;//laddar med den andra byten av t1sv

   port_c ^= 1;   //0->1 el. 1->0

   TIMER1_CTRL=tmp3;

}



#int_ssp

receive_isr()

{

   //ladda freq med mottaget v�rde

   if(i2c_poll())

   {

      if(i2c_status==FIRST_READ)

      {

         received=i2c_read();

         freq_tmp=received;

         i2c_status=LAST_READ;

      }

      else if(i2c_status==LAST_READ)

      {

         received=i2c_read();

         freq_tmp=(freq_tmp<<8)&0xFF00;

         freq_tmp=freq_tmp+received;

         i2c_status=FIRST_READ;



         freq=freq_tmp;

         if(freq>40) TIMER1_CTRL=0x01;

         else TIMER1_CTRL=0x11;

         temp=2*freq;

         if(TIMER1_CTRL==0x11) temp=2495000/temp;

         else temp=4990000/temp;

         t1sv=65535-temp;

      }

      port_d ^= 1; //indikator

   }

}





//������������������������������������������������������������������������������

//������������������������������������ MAIN ������������������������������������

//������������������������������������������������������������������������������



main()

{

   setup_counters(RTCC_INTERNAL,RTCC_DIV_2);

   setup_port_a(NO_ANALOGS);

   setup_adc(ADC_CLOCK_INTERNAL);

   setup_psp(PSP_DISABLED);

   setup_ccp1(CCP_OFF);

   setup_ccp2(CCP_OFF);

   setup_spi(spi_slave | SPI_L_TO_H | SPI_SS_DISABLED);



//====================== I/O ============================



   set_tris_d(0x00);  // PORT-D: alla utg�ngar

   set_tris_c(0xFE);  // PORT-C: alla ing�ngar, utom C0(puls)



//=======================================================



//========================I2C============================

   enable_interrupts(INT_SSP);

//=======================================================



//================== SETUP - Timer1 =====================



   enable_interrupts(INT_TIMER1);

   enable_interrupts(GLOBAL);

   TIMER1_CTRL=0x11;



//=======================================================



   while(1){};

}

//������������������������������������������������������������������������������



Sad
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon May 08, 2006 9:08 am     Reply with quote

Your more likley to get assisatance is you post the minimal code necessary to demonstrate the problem. Not many have the time to debug someone elses long code listing.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
new2pic



Joined: 02 May 2006
Posts: 16

View user's profile Send private message

PostPosted: Mon May 08, 2006 11:18 am     Reply with quote

i dont know if this helps but this works for me:


SEN = 1;
while(comm_not_finished);

bit comm_not_finished (data passed to function)

while(!SSPIF);
SSPIF = 0;
switch (x)
{
case 0:
SSPBUF = <insert data1>;
x = 1;
break;
case 1:
if (ACKSTAT) {
x = 0;
SEN = 1;
break;
}
SSPBUF = <insert data2>;
x = 2;
break;
case 2:
if (ACKSTAT)
{
x = 0;
SEN = 1;
break;
}
PEN = 1;
x = 3;
break;
case 3:
x = 0;
return 1;

}
return FALSE;
}
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 08, 2006 12:51 pm     Reply with quote

A huge listing and not even complete, puls.h is missing.
I can't find some #fuse settings and the #device setting, are these in the missing puls.h file?

Code:
   setup_spi(spi_slave | SPI_L_TO_H | SPI_SS_DISABLED);
You are using I2C, not SPI. This line seems tricky to me and I would remove it.

Sorry, I'm too lazy to study the rest of your huge program.

Have a look at ex_slave.c in the examples directory for how CCS sets up an I2C slave.
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