View previous topic :: View next topic |
Author |
Message |
Matro Guest
|
PIC16F88 / SSP module problem |
Posted: Mon Feb 11, 2008 7:31 am |
|
|
Hi everybody,
I'm in trouble with the SSP module of the PIC16F88 that I use in I2C slave mode (7-bit address).
All works well when I write to the device. But as soon as I try to send a "read" command to the PIC it completely crashes. The SDA line goes to 0V and the SCL line goes to a strange constant 1.18V.
Does somebody know where could be the problem?
In the .lst generated file the "i2c_write" function gives the 2 following lines that could be an infinite loop (and that I can't understand) :
Code: |
029D: BTFSC 14.0
029E: GOTO 29D
|
(Register 0x14 is SSPCON)
Tell me if posting a part of the C code can help.
Thanks in advance for your help,
Matro |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Feb 11, 2008 7:55 am |
|
|
Quote: | The SDA line goes to 0V and the SCL line goes to a strange constant 1.18V. | How did you measure this? With a multimeter or a scope?
The assembly code you posted is not all code for the i2c_write function, or at least shouldn't be. This is only the loop that waits for all I2C data to have been transmitted (it's not infinite, the next instruction will be skipped when bit 14.0 is clear).
Important is that the correct RAM bank is selected (bank 1), but from the short piece of code you posted this can't be checked.
What is your compiler version?
And post a short (max. 15 lines) example program demonstrating your problem. The program should be complete including #fuses etc. so we can copy / paste it into our compiler. |
|
|
Matro Guest
|
|
Posted: Mon Feb 11, 2008 8:07 am |
|
|
Thanks for your answer ckielstra.
The voltages are "measured" by a scope, so I'm sure it's totally DC voltage. ;-)
I'm working with CCS 4.057.
Below is the complete generated asm code of the i2c_write function :
Code: |
0298: MOVF 3A,W
0299: MOVWF 13
029A: BSF 14.4
029B: BCF 0C.3
029C: BSF 03.5
029D: BTFSC 14.0
029E: GOTO 29D
029F: CLRF 78
02A0: BCF 03.5
02A1: BTFSC 14.4
02A2: INCF 78,F
|
0x3A is the parameter, 0x78 is the return value.
What I don't understand the "BTFSC 14.0" is that it poll the value of the SSPM0 bit. And this one is used to configure the mode of the SSP (SPI/I2C/...). So I don't see the reason for that. But I could definitely understand such a code if it was polling the "transmit complete" flag.
I will try to summarize the problem in a short code that you can test.
Thanks. |
|
|
Matro Guest
|
Code sample |
Posted: Mon Feb 11, 2008 9:00 am |
|
|
Here is a test code that produced exactly the same issue :
Code: |
#include <16F88.h>
#FUSES NOWDT
#FUSES INTRC
#FUSES NOPUT
#FUSES MCLR
#FUSES BROWNOUT
#FUSES NOLVP
#FUSES NOCPD
#FUSES NOWRT
#FUSES NODEBUG
#FUSES NOPROTECT
#FUSES NOFCMEN
#FUSES NOIESO
#FUSES CCPB3
#use delay(clock=8000000)
#use i2c(Slave,Slow,sda=PIN_B1,scl=PIN_B4,restart_wdt,force_hw,address=0x20)
BYTE data = 0xAA;
void I2C_send(void)
{
i2c_write(data);
}
void I2C_receive(BYTE param)
{
data = param;
}
#int_SSP
void SSP_isr(void)
{
BYTE I2C_status; //internal I2C HW status
I2C_status = i2c_isr_state(); //get status of internal I2C HW
if(I2C_status >= 0x80) //if host is reading
{
I2C_send(); //send the register value
}
else if(I2C_status == 0x00)
{
//i2c_read(); //do nothing
}
else //if the host is sending a value byte
{
I2C_receive(i2c_read()); //update register with value
}
}
void main()
{
output_high(PIN_A7); //start power supply
while(1);
}
|
Hoping it will be helpful for problem understanding. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Feb 11, 2008 9:04 am |
|
|
Quote: | What I don't understand the "BTFSC 14.0" is that it poll the value of the SSPM0 bit. | The PIC uses banked memory addressing for the RAM and SFR's. The maximum address range in the commands is only 128 bytes, or 0x7F. In order to address all memory you have to select the correct memory bank first (bits 5 and 6 in the Status register, address 0x03). So with bank1 selected the 0x14 address becomes 0x80 + 0x14=0x94 which is the SSSTAT register. Bit 0 is the 'Buffer full status bit' for I2C and SPI.
The strange 1.18V you measure indicates a hardware problem. Do you have all required pull up resistors present? What value do they have?
Is your PIC accidentally working in master mode instead of slave mode?
I see you posted an example program while I was typing this message. Give me a few minutes to have a look. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Feb 11, 2008 9:13 am |
|
|
First remark: You do not enable the interrupts, so the interrupt routines are never called. Again this suggests a hardware problem, how about the pull-up resistors on SDA and SCL?
Try adding: Code: | enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL); |
|
|
|
Matro Guest
|
|
Posted: Mon Feb 11, 2008 9:38 am |
|
|
You're right. I forgot to copy the enable interrupts from the orginal code.
The pull-up resistors are classical 4K7.
I'm definitely not sure that it is a HW problem because the "write" transfers are OK and the problem is just on the "read" ones.
I don' think that the PIC is working in master mode because the 16F88 is not able to do that. ;-)
And the i2c master is necessarily OK because it works fine in another project.
My mistake for the "BTFSC 14.0" instruction, I forgot the RAM bank feature for a few minutes. :-)
Thanks for your help. Feel free to append with new suggestions if you have. All info could be helpful. |
|
|
|