|
|
View previous topic :: View next topic |
Author |
Message |
finch
Joined: 29 Jul 2009 Posts: 1
|
I2C slave without interrupt handler |
Posted: Tue Nov 10, 2009 7:42 am |
|
|
Hi all,
can you help me with I2C for slave without interrupt handler? I have this code for it (chip is PIC18F4480), but it doesn't works:
Code: |
#include <18F4480.h>
#device ADC=10
// Configuration bits
#fuses INTRC_IO
#fuses NOPROTECT
#fuses NOLVP
#fuses NOWDT
// Oscillator frequency 8MHz
#use delay(clock=8000000)
// UART configuration
#use RS232(baud=19200,xmit=PIN_C6,rcv=PIN_C7,bits=8,parity=N)
#use I2C(slave,scl=PIN_C3,sda=PIN_C4,force_hw)
void main() {
char command[20];
int1 process;
process = FALSE;
SSPCON1 = 0x36;
SSPCON2 = 0x00;
for(;;) {
if(SSPSTATbits.BF) {
int word;
int index;
memset(command,0,sizeof(command));
index = 0;
do {
word = i2c_read();
PIR1bits.SSPIF = 0;
command[index++] = word;
if(word == 0)
break;
} while(SSPSTATbits.BF);
process = TRUE;
}
if(process) {
printf("Cmd=%s\r\n",command);
process = FALSE;
}
}
}
|
It receive address byte and then stuck.
Master send message in ASCII format (example): "DF_123\0"
'\0' = 0 ... it means end of message (NULL terminated string).
Thanks. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Nov 10, 2009 8:20 am |
|
|
Quote: | It receive address byte and then stuck. | Yes, most likely with a receive overflow.
Why do you think, that while(SSPSTATbits.BF) will allow you to receive all transmitted characters at once? After receiving the address byte, BF is low for a while and your code hastily truncates the reception. You must either know the number of transmitted characters and wait until they all come in or implement a timeout of at least one I2C character frame. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue Nov 10, 2009 9:29 am |
|
|
First of all, why would you NOT want to use the ISR? It's there for a reason and it makes things very easy.
Looking at your code, if the BF bit is true you call a function memset() and inside that you call sizeof(). Your data, on the I2C bus, is coming in very fast. The calls, to these two functions, are going to take WAY more time that you can afford and WILL lose data.
You might want to re-think what you want to accomplish.
Ronald |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Nov 10, 2009 1:10 pm |
|
|
Quote: | The calls, to these two functions, are going to take WAY more time that you can afford and WILL lose data. |
sizeof() always evaluates to a constant, it's no true function.
memset() would be a problem with a fast (400 kHz) I2C, it should be still O.K. at low speed (100 kHz). |
|
|
Ttelmah Guest
|
|
Posted: Tue Nov 10, 2009 3:58 pm |
|
|
There are a whole lot more comments to make:
Though we have been shown the 'slave' end, no 'master' has been given.
The I2C_hardware_, requires, an address byte. No address is specified for the slave setup shown. The SSPBUF, won't be loaded, till an address match has occured. Then the direction of the following bus transfer, is determined by the low bit of this address byte. The behaviour of the SSPBUF.BF bit, is determined by this direction bit for subsequent transactions.
So:
Add the address to the I2C setup. Make sure this is a legitimate standard address (>0xF, and even).
Ensure the master sends a start, address, (with the low bit being 0), and then sends the data, followed by a stop.
Modify the receive code, to check the data/address bit, and only start reading the data, once this is set.
I suspect the receive is not starting, since there is never an address match.
If you simply want to send data in one direction, without addressing, start, stop etc., then why not just use two wire SPI instead.....
Best Wishes |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Nov 10, 2009 5:32 pm |
|
|
Why do you expect, that no valid address has been sent? Without it, no BF would be seen.
You can't be sure, that the I2C data have been completely correct, but from the post, there's no indication of an actual problem in this regard. |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Wed Nov 11, 2009 3:47 am |
|
|
I see a couple of issues.
Because we can't see the master code the firstproblem is your command termination.
'\0' or null is the normal string terminator in C. If your transmision code does something like:-
Code: |
//assume str="DF_123\0"
for (i=0; i < strlen(str); i++)
{
putc(str[i]);
}
// Or you just use
putc(str);
|
Because this code and putc both look for the termination char of '\0' (strlen will use your inserted '\0' as the string terminator) it will never send the '\0'!
Secondly.
if a character does NOT fill the buffer between the i2c_read() and the while(SSPSTATbits.BF) then it will drop out of the loop. this will most likely happen for each char so that when you print you will get a line
Cmd=c where c is the character recieved for each character.
Also, I am pretty sure that the first character read after an address match is the address! now if your address happens to be a printable character then fine otherwise you would get a coruppted output.
You do not show your definition of SSPSTATbits.BF either.
I presume it is in <18F4480.h>
Could you also show what output you do get.
What makes you think it has recieved the correct address and matched ?
just my thoughts. |
|
|
Ttelmah Guest
|
|
Posted: Wed Nov 11, 2009 4:21 am |
|
|
The point I was making about the address, is that he is not loading one anywhere. It is not in the #use I2C shown, and is not being done manually later. The default SSPADD value, on power on, is 0, which is not a standard address. Addresses below 0xF, are defined in I2C, as special control addresses, and '0' is a general call address. The chip may well not behave normally for this address. Also, since this will be the first byte read, the code will terminate if this is the address being used....
Best Wishes |
|
|
|
|
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
|