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

Any Suggestions!

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



Joined: 20 Dec 2003
Posts: 14

View user's profile Send private message

Any Suggestions!
PostPosted: Thu Mar 11, 2004 9:02 pm     Reply with quote

Hello All!
I am using port B interrupt on change to implement a software SPI. I set RB4 as clock and RB5 as latch, data is connected to RB1. I left shift 16 bits of data on a clock L->H and then if I receive Latch L->H trigger, I process the 16-bit data. Of the 16 bits, If bit 0 (the first bit that I receive) is high, I send some configuration data through UART.
To test my code, I send 16 clock pulses and corresponding 16 bits of data (the data changes at -ve edge of clock to avoid any timing issues), then I set latch high. The data that I send is FFFF (first bit is 1) so, I expect to see something from the UART, but I see that the UART works once in 5 or 6 times that I send the data. Also I observe that this freq changes if the latch high pulse width is increased. I am using a clock freq of 2 MHz. But after some time if latch pulse if high for long time, then I see the UART data sent each time I latch the 16-bit data, even if MSB bit is not set! I am clueless
Please advise if I am doing something wrong in my code? My code is attached. My device is 16F874A and 20 MHz osc.

*************************************************************
#INT_RB

void intRB()
{
if(SPI_ENABLE == 0) // shift data if the latch is low
{
if((SPI_CLK == 1) && (WAIT == 0)) //Clock L->H
{
// move two bytes from the DIN line to our (long) word
shift_left(&DIN_data[0],2, SPI_DIN);
}
WAIT = 0;
}
else // enable L->H transition, time to process the shifted data
{
WAIT = 1;

if(bit_test(DIN_data[1],7)) // check for BIT if high
{
BIT_FLG = 1; //set the bit activate flag
}
// start storing the data in the registers

if(bit_test(DIN_data[1],6) && bit_test(DIN_data[1],5))
{
RF.Tx2_L = DIN_data[0];
RF.Tx2_H = DIN_data[1];
}
else if(!bit_test(DIN_data[1],6) && bit_test(DIN_data[1],5))
{
RF.Tx1_L = DIN_data[0];
RF.Tx1_H = DIN_data[1];
}
else if(bit_test(DIN_data[1],6) && !bit_test(DIN_data[1],5))
{
RF.Rx2_L = DIN_data[0];
RF.Rx2_H = DIN_data[1];
}
else if(!bit_test(DIN_data[1],6) && !bit_test(DIN_data[1],5))
{
RF.Rx1_L = DIN_data[0];
RF.Rx1_H = DIN_data[1];
}
}
}


#use delay(clock=20000000)

main()

{
//port initialization

//Interrupt defines

ENABLE_INTERRUPTS(INT_RB);

ENABLE_INTERRUPTS(GLOBAL);

delay_ms(settle); // Let the inputs settle down

while(true)
{

if(BIT_FLG == 1)
{
BIT_FLG = 0;
printf("%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",
RF.Tx1_H,RF.Tx1_L,RF.Tx2_H,RF.Tx2_L,
RF.Rx1_H,RF.Rx1_L,RF.Rx2_H,RF.Rx2_L);

}
}



} Rolling Eyes
Ttelmah
Guest







Re: Any Suggestions!
PostPosted: Fri Mar 12, 2004 4:57 am     Reply with quote

tmach wrote:
Hello All!
I am using port B interrupt on change to implement a software SPI. I set RB4 as clock and RB5 as latch, data is connected to RB1. I left shift 16 bits of data on a clock L->H and then if I receive Latch L->H trigger, I process the 16-bit data. Of the 16 bits, If bit 0 (the first bit that I receive) is high, I send some configuration data through UART.
To test my code, I send 16 clock pulses and corresponding 16 bits of data (the data changes at -ve edge of clock to avoid any timing issues), then I set latch high. The data that I send is FFFF (first bit is 1) so, I expect to see something from the UART, but I see that the UART works once in 5 or 6 times that I send the data. Also I observe that this freq changes if the latch high pulse width is increased. I am using a clock freq of 2 MHz. But after some time if latch pulse if high for long time, then I see the UART data sent each time I latch the 16-bit data, even if MSB bit is not set! I am clueless
Please advise if I am doing something wrong in my code? My code is attached. My device is 16F874A and 20 MHz osc.

*************************************************************
#INT_RB

void intRB()
{
if(SPI_ENABLE == 0) // shift data if the latch is low
{
if((SPI_CLK == 1) && (WAIT == 0)) //Clock L->H
{
// move two bytes from the DIN line to our (long) word
shift_left(&DIN_data[0],2, SPI_DIN);
}
WAIT = 0;
}
else // enable L->H transition, time to process the shifted data
{
WAIT = 1;

if(bit_test(DIN_data[1],7)) // check for BIT if high
{
BIT_FLG = 1; //set the bit activate flag
}
// start storing the data in the registers

if(bit_test(DIN_data[1],6) && bit_test(DIN_data[1],5))
{
RF.Tx2_L = DIN_data[0];
RF.Tx2_H = DIN_data[1];
}
else if(!bit_test(DIN_data[1],6) && bit_test(DIN_data[1],5))
{
RF.Tx1_L = DIN_data[0];
RF.Tx1_H = DIN_data[1];
}
else if(bit_test(DIN_data[1],6) && !bit_test(DIN_data[1],5))
{
RF.Rx2_L = DIN_data[0];
RF.Rx2_H = DIN_data[1];
}
else if(!bit_test(DIN_data[1],6) && !bit_test(DIN_data[1],5))
{
RF.Rx1_L = DIN_data[0];
RF.Rx1_H = DIN_data[1];
}
}
}


#use delay(clock=20000000)

main()

{
//port initialization

//Interrupt defines

ENABLE_INTERRUPTS(INT_RB);

ENABLE_INTERRUPTS(GLOBAL);

delay_ms(settle); // Let the inputs settle down

while(true)
{

if(BIT_FLG == 1)
{
BIT_FLG = 0;
printf("%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",
RF.Tx1_H,RF.Tx1_L,RF.Tx2_H,RF.Tx2_L,
RF.Rx1_H,RF.Rx1_L,RF.Rx2_H,RF.Rx2_L);

}
}



} Rolling Eyes


Seriously, I'd suspect your problem is latency.
When the interrupt occurs on RB, The code takes a _very_ long time (in computer terms), to actually get to the interrupt handler. I did some 'rough' calculations for another thread, and predicted about 108 clock cycles to get to the start of the handler for a 16 family chip. Now with a 2MHz SPI clock, you will potentially receive edges at just 10 clock cycle intervals. Hence you will have missed perhaps 10 of the SPI clocks, when you reach the handler for the first time. By the second loop round, you will probably have just about finished clocking your data, and whether you see a '1' or a '0' will then depend on luck. Clocking at a slower rate, the probability that data is still arriving increases.
You are trying to operate, perhaps a factor of about 20* above the maximum practical frequency for an interrupt driven receive routine. You need to rethink, and either operate at a very slow rate, using the interrupt apporach, or possibly operate at the high rate (which could just about be done if you stay inside the routine), and send a single 'trigger' edge, to make the slave go into the handler routine, then wait long enough for it to have reached the handler, and then send the rest of the clocks...
This problem exists, to a lesser extent, with the hardware SPI, but even here, the need to place the 'return' byte into the buffer, soon after the data has arrived, and the lack of double buffering on the receiver, makes high rates hard to achieve. Crying or Very sad

Best Wishes
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