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

Need help sending a in16 from a master-PIC to a slave-PIC

 
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

Need help sending a in16 from a master-PIC to a slave-PIC
PostPosted: Thu May 04, 2006 1:31 pm     Reply with quote

Hi!

Right now I΄m using a PIC16F877A to generate a square-wave signal. This PIC-processor is also connected to a LCD display. What I want to do is send a 16-bit integer to one of two other identical PIC-processors(without LCD though) by i2c. This integer will tell a slave-PIC what freguency it should generate. That΄s it! I don΄t want to read anything from a either of the slave-PICs, just send an integer. I have the code for both master and slave(s). I would appreciate if someone could take a look at both and tell me the next step or what I΄ve done wrong so far.

Master-CODE: The things to look at here should be:
*the #use i2c(...) statement
*the function send_to_slave();
*the initialization i main()
//========================
#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()
{
set_tris_b(0xF0);
port_b_pullups(true);

port_b = 0x0E;
if(!bit_test (port_b,7))
return 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)
{
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();
delay_us(50);
i2c_write(0xa0); //adress
delay_us(50);
i2c_write(freq2>>8); //data
delay_us(50);
i2c_write(freq2&0x00FF);
i2c_stop();
break;

case 3: //skicka till slav-2
i2c_start();
delay_us(50);
i2c_write(0x50); //adress
delay_us(50);
i2c_write(freq3>>8); //data
delay_us(50);
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: In the interrupt-routine I just want to place the incoming 16-bit integer in the variable "freq".

#include <puls.H>
#fuses NOWDT
#use i2c(slave,sda=PIN_C4,scl=PIN_C3,address=0xa0,FORCE_HW)


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


int16 temp;
byte tmp3; //anv av timer1_isr()



//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(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;*/
/*if(bit_test(i2c_stat,6))*/ port_d=i2c_buff;
i2c_buff=0x00;
bit_clear(i2c_ctrl,3);
}


//€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€
//€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€ 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);
bit_clear(i2c_ctrl,3);
//=======================================================

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

enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
TIMER1_CTRL=0x11;

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


while(1){};
}
//€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€


PLEASE HELP ME!!!! :-(

/David[/code]
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu May 04, 2006 3:11 pm     Reply with quote

Your basic problem is that you are re-inventing the wheel several times
with your code. You are writing your own LCD and keypad drivers,
and also the i2c slave code. You should be using the CCS drivers
and example files:

KBD.C -- keypad driver
LCD.C -- LCD driver
EX_SLAVE.C -- Sample code for an i2c slave

Look for these files in:
c:\Program Files\PICC\Drivers
and
c:\Program Files\PICC\Examples

Also, you are doing a lot of time-consuming math in your INT_SSP
routine. You should only get the incoming i2c byte in that routine.
Don't do anything else.
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