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 conversion/ and WAIT

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








i2c conversion/ and WAIT
PostPosted: Sun Dec 24, 2006 4:04 pm     Reply with quote

I have 2 questions.

SITUATION:
I am using a PIC18F2520 as a Slave. The slave processes its analog inputs and prepares a data packet with 8 values from its 10 bit ADC.

1. I need to send 5 of the 8 values as 16 bit values to the master, and the rest 3 values as 8 bit values. Since I am using a 8 bit I2C format. I was thinking of sending 2 write commands for the 16 bit values and 1 write command for the 8 bit values. How do I convert the ADC count I receive from the 10 bit ADC and convert them into 16 bit or 8 bit values of 0s and 1s so I can send them to the master using the write command.

2. I noticed that the I2C slave example uses interrupts. I am worried about a problem. What if the master quarries for the data packet while the slave is preparing the data packet. How can I make the interrupt wait? Initially I was thinking of removing the interrupt and putting the I2C in the main forever loop. But I could not compile the code without using the interrupt. It did not let me use the state command and someothers as well.

I would really appreciate your help.
Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Dec 24, 2006 4:59 pm     Reply with quote

Quote:
How do I convert the ADC count I receive from the 10 bit ADC and
convert them into 16 bit or 8 bit values of 0s and 1s so I can send them
to the master using the write command.

1. Read the 10-bit ADC value and put it into a 16-bit variable.
See the sample code in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=29281

2. Use the make8() function to extract the LSB and MSB bytes from
a 16-bit integer variable. Then transmit the individual bytes, one at
a time.

3. After you receive the LSB and MSB bytes, use the make16() function
to re-assemble them back into a 16-bit variable.
Guest








PostPosted: Sun Dec 24, 2006 7:21 pm     Reply with quote

Dear PCM Programmer,
Thanks. I will try that out.
Guest








PostPosted: Sun Dec 24, 2006 7:37 pm     Reply with quote

Dear PCM Programmer,
This is related to the previous question.

SITUATION:
I am using a PIC18F2520 as a Slave. The slave processes its analog inputs and prepares a data packet with 8 values from its 10 bit ADC. And then using I2C it sends it to the Master.
The Master is some other microcontroller that has a forever main loop that keeps querying for the data packet from the slave, and then gets the data packet from the slave. It gets the data packet from the slave constantly at some constant rate that I am not aware of.

Q. I noticed that the I2C slave example uses interrupts. I am worried about a problem. What if the master quarries for the data packet while the slave is preparing the data packet. How can I make the interrupt wait? Initially I was thinking of removing the interrupt and putting the I2C in the main forever loop. But I could not compile the code without using the interrupt. It did not let me use the state command and some others as well.
Is there an easy way to make the interrupt wait? And if we make the interrupt wait then I guess there is no difference than actually having it in a forever loop where it every time checks for query after it prepares the data packet. How do I do this?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Dec 24, 2006 10:04 pm     Reply with quote

The simple way is to add another signal line between the master and
slave devices, which will be an interrupt from the slave to the master.
Use the EXT_INT input on the master PIC to receive the interrupt from
the slave PIC. When the master gets the interrupt, it knows the slave
has data ready, and it can then issue a request for the data.
Guest








PostPosted: Mon Dec 25, 2006 12:40 am     Reply with quote

I do not have access to the code on the Master Device. But I do know that it regularly collects data from the slave. Is there someway I can make the master wait? As in make the master wait for the ACK when it wants to start the I2C. I dont know what the master does in an I2C when it has to wait for the ACK. I cant change any code on the master, so whatever I will have to do will have to be in the slave PIC18F2520.
Thanks
Mark



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

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

PostPosted: Mon Dec 25, 2006 1:46 am     Reply with quote

The slave will hold the clock line low until you release it. This is known as clock stretching.

Another method is not to respond to the master when you are not ready. This is what eeproms do when they are writing to their memory. The master should look for the ACK from the slave. If the slave does not ACK, then the master usually keeps trying until the slave ACK's.
Guest








PostPosted: Mon Dec 25, 2006 12:27 pm     Reply with quote

I wanted to do the exact thing you suggested, but the issue is that as soon as the Master queries the interrupt causes it to receive an ACK. I am using the Ex_Slave.c. from c:\Program Files\Picc\Examples. It uses interrupts, and if I remove the interrupts I get more than a hundred errors when I compile.
Since this is my first time programming any kind of microcontroller, I was trying to use the same code as in EX_Slave.c and make the master wait for the ACK.
Sorry for my novice questions in this field.
Any Suggestions!!!
Ttelmah
Guest







PostPosted: Tue Dec 26, 2006 3:44 am     Reply with quote

OK.
The hardware implements the 'wait' functionality. You have two possible solutions:
1) Implement a buffer. Have the interrupt respond as normal, returning the 'last' completed reading. As soon as a new reading is available, update the buffer. This is what is done in most commercial chips, since it is relatively dangerous to hold the master for too long.
2) Disable the interrupt. What you do, is disable the I2C interrupt, before you start taking your reading. The interrupt flag will be set, but no interrupt will occur, and the clock will be held. As soon as the reading is complete, re-enable the interrupt, and the handler will be called, returning the new reading. Now there are dangers with this approach. Many 'master' devices, will have a timeout if the clock is held for too long. Also the master itself, may wait for responses, and the approach may then slow it down...

Best Wishes
Mark



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

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

PostPosted: Tue Dec 26, 2006 9:25 am     Reply with quote

If you disable the SSP module (or say make it a master) then it will not ACK it's slave address. If the master's code is written properly, then it should continue to poll the slave until it gets an ACK and then read the data.
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