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

#Use I2C() and SSP interrupts not working on PIC16F883

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



Joined: 06 Feb 2004
Posts: 26
Location: Curitiba, Brazil

View user's profile Send private message Visit poster's website

#Use I2C() and SSP interrupts not working on PIC16F883
PostPosted: Sun Aug 17, 2008 11:33 pm     Reply with quote

I have a really strange I2C problem that I want to share with you all in hopes that someone can shed some light on a solution.

Hardware:
PIC16F883 (On the MCP1631 Multi-Chemistry Battery Charger Reference Design Demo Board)
Compiler:
CCS PCWHD version 4.077
ICD Environment:
MPLAB 8.14 with RealICE debugger

Problem #1:
The #use i2c(SLAVE, SDA=PIN_C3, SCL=PIN_C4, ADDRESS=0x22) compiler directive does not setup the PIC16F883 MSSP module. The following code was compiled and run on the target board.

Code:

#include <16F883.h>
#device ADC=10
#fuses INTRC,NOWDT,MCLR,DEBUG,NOPROTECT,NOLVP,NOBROWNOUT,NOPUT,NOCPD
#use delay(clock=8000000)   // 8MHz Clock
#use i2c(SLAVE, SDA=PIN_C3, SCL=PIN_C4, ADDRESS=0x22)

#byte   SSPSTAT = 0x094
#byte   SSPCON2 = 0x091
#byte   SSPADD = 0x093
#byte   SSPCON = 0x014
#byte   PIR1 = 0x00C
#bit   GCEN = SSPCON2.7
#bit   SSPIF = PIR1.3

#INT_SSP
void ssp_interupt(void)
{
   if(SSPIF)
      SSPIF = 0;
      
   delay_us(1);
   delay_us(1);
   delay_us(1);
                              
}// End ISR SSP

void main(void)
{
   setup_oscillator(OSC_8MHZ,0);   //set oscillator to 8Mhz
   
   set_tris_c (0b00011000);      // C3 and C4 are INPUTS
   
   //SSPCON = 0b00110110;
   GCEN = 1;                  // Allow General Calls
   //SSPADD = 0x22;               // Slave Device Address
   
   enable_interrupts(INT_SSP);      // Enable I2C Interrupts
   enable_interrupts(GLOBAL);      // Enable Global Interrupts
   
   while(TRUE)
   {
      
   }
}


Debugger Watch Window shows:
Address Symbol Name Value
014 SSPCON 00000000
091 SSPCON2 10000000
094 SSPSTAT 00000000
093 SSPADD 0x00
00C PIR1 00000000
013 SSPBUF 0x44

Then I checked to see if I could directly set the register values.

Code:

#include <16F883.h>
#device ADC=10
#fuses INTRC,NOWDT,MCLR,DEBUG,NOPROTECT,NOLVP,NOBROWNOUT,NOPUT,NOCPD
#use delay(clock=8000000)   // 8MHz Clock
//#use i2c(SLAVE, SDA=PIN_C3, SCL=PIN_C4, ADDRESS=0x22)

#byte   SSPSTAT = 0x094
#byte   SSPCON2 = 0x091
#byte   SSPADD = 0x093
#byte   SSPCON = 0x014
#byte   PIR1 = 0x00C
#bit   GCEN = SSPCON2.7
#bit   SSPIF = PIR1.3

#INT_SSP
void ssp_interupt(void)
{
   if(SSPIF)
      SSPIF = 0;
      
   delay_us(1);
   delay_us(1);
   delay_us(1);
                              
}// End ISR SSP

void main(void)
{
   setup_oscillator(OSC_8MHZ,0);   //set oscillator to 8Mhz
   
   set_tris_c (0b00011000);      // C3 and C4 are INPUTS
   
   SSPCON = 0b00110110;
   GCEN = 1;                  // Allow General Calls
   SSPADD = 0x22;               // Slave Device Address
   
   enable_interrupts(INT_SSP);      // Enable I2C Interrupts
   enable_interrupts(GLOBAL);      // Enable Global Interrupts
   
   while(TRUE)
   {
      
   }
}


This time when running the compiled program, I get the expected results.

Debugger Watch Window shows:
Address Symbol Name Value
014 SSPCON 00110110
091 SSPCON2 10000000
094 SSPSTAT 00000000
093 SSPADD 0x22
00C PIR1 00000000
013 SSPBUF 0x44

Problem #2:
INT_SSP never occurs.

With a known GOOD I2C Master, I generated a simple QuickWrite transaction, which essentially sends the following:

i2c_start(); // [START]
ack = i2c_write((address<<1)|0x00); // [ADDRESS + W]
i2c_stop(); // [STOP]

I set a breakpoint on the first delay_us(1); statement in the SSP_ISR and ran the program.

Without any code in the SSP isr I am not expecting it to respond, but i did expect the SSP interrupt to occur and stop at the breakpoint. This did not happen.

I ran this same code on a PIC16F88 target board and everything works as expected.

Does anyone have any suggestions?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Aug 18, 2008 12:32 am     Reply with quote

Quote:
#use i2c(SLAVE, SDA=PIN_C3, SCL=PIN_C4, ADDRESS=0x22)

You have the SDA and SCL pins reversed. That's why the code
generation is not correct.

Quote:
i2c_start(); // [START]
ack = i2c_write((address<<1)|0x00); // [ADDRESS + W]
i2c_stop(); // [STOP]

What is contents of the 'address' variable before it is shifted left ?
I want to check if you are confusing the 8-bit slave address format
used by CCS and Microchip, and the 7-bit format used by Philips.
Bill_Smith



Joined: 06 Feb 2004
Posts: 26
Location: Curitiba, Brazil

View user's profile Send private message Visit poster's website

PostPosted: Mon Aug 18, 2008 11:39 am     Reply with quote


Wow PCM, sorry about this. I guess I need some sleep. You were spot on with the pins being reversed and the device address. Changing the #use i2c statement to the following loaded all the MSSP registers correctly.

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0x44)

Rolling the device address bits 1 position to the left so that I am loading the SPPADD register with [0x44], instead of [0x22], solved the No SSP_INT problem as well. I guess CCS must have recently changed how the compiler interprets the I2C Slave address. I could have sworn it used to be as I first had it.

Anyway everything is working now. Thank you for your help.
danishamjad



Joined: 28 Apr 2015
Posts: 1
Location: Pakistan

View user's profile Send private message Yahoo Messenger

Same Issue-- Interrupt is not firing
PostPosted: Tue Apr 28, 2015 9:56 am     Reply with quote

I am trying simple project to study i2c. I am using PIC18F4550 and CCS PIC C compiler.
Here is a scenario.
Master:
1. Button is connected to PIN_E1.
2. When Button is pressed, it sends code 0x01 to slave.
3. When Button is pressed again, it sends code 0x02 to slave.
Slave:
1. Only one slave is connected. It's address is 0x0a.
2. When it receives 0x01, it should turn LED on connected at PIN_E0.
3. When it receives 0x02, it should turn LED off.

I was observing SCL and SDA on oscilloscope and found correct pattern always, when the button is pressed.

But interrupt in slave is not working at all. I just changed slave scenario:
1. LED is turned off at first.
2. Whenever interrupt is fired it should remain turn on.

Here is my slave code:
Code:

#include <18F4550.h>
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES CPUDIV4                  //System Clock by 4
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(crystal=20000000,  clock=5000000)

#use i2c(SLAVE, sda=PIN_B0, scl=PIN_B1, address=0x0a, force_hw)

BYTE address, buffer[0x10];

#INT_SSP
void ssp_interupt (){
BYTE incoming, state;

state = i2c_isr_state();
       
if(state < 0x80)                     //Master is sending data
    {
    incoming = i2c_read();
    if(state == 1)                    //First received byte is address
        address = incoming;
    if(state == 2)                    //Second received byte is data
        buffer[address] = incoming;
    }
if(state == 0x80)                     //Master is requesting data
    {
    i2c_write(buffer[address]);
    }
    output_high(PIN_E0);
}



void main()
{
   setup_timer_3(T3_DISABLED | T3_DIV_BY_1);

   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
   
   set_tris_B ( 0b01111111 );
   set_tris_e(0x06);
   output_low(PIN_E0);
   
   
while(1){}
   
}


Kindly, tell me if I'm doing something wrong.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Apr 28, 2015 10:50 am     Reply with quote

Quote:
#use i2c(SLAVE, sda=PIN_B0, scl=PIN_B1, address=0x0a, force_hw)

Your slave address is not in the valid range. It must be at least 0x10.
See this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=49907
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