Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

PIC16 issue with I2C communication

Status
Not open for further replies.

allkhush

Newbie level 3
Newbie level 3
Joined
Apr 6, 2012
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,321
Hi there,
I have been working on pic16F877A for a while, and I found that there is some problem with its MSSP module when used in slave mode. My experiment is as follows-
I have atmega128 as master and PIC16F877A as slave. I want slave to transmit few bytes to master on request and interpret(switch on/off set of loads) a byte while in WRITE mode. After initializing the I2C in both the devices, I see that master is doing its work perfectly fine, but the slave doesn't seem to receive anything as it's SSPIF flag doesn't get set which then calls ISR. This, I verified by manually setting SSPIF, and printing a character through UARTwriteChar in ISR, works fine.

I am trying to write a character 'c' (actually random byte) via I2C from master to slave continuously as long as it gets the ACK from slave, i.e. when I2C lines are removed master stops writing.
So, either slave is not receiving anything which is not true since its ACK is sent, Or it receives the data and sends the ACK but there is problem with setting the SSPIF flag after receiving data.
Is there a problem with the internal settings of PIC16 related to I2C or am I missing something important?
Following are the codes-


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
void I2C_INIT(void)
{
    TRISCbits.TRISC3 = 1;                  /* SDA and SCL as input pin */
    TRISCbits.TRISC4 = 1;                  /* these pins can be configured either i/p or o/p */
    SSPCON1bits.SSPM3 = 0;
    SSPCON1bits.SSPM2 = 1;                // SLAVE mode with 7bit address
    SSPCON1bits.SSPM1 = 1;
    SSPCON1bits.SSPM0 = 0;  
    SSPSTATbits.SMP = 0;                 // Slew rate set to NORMAL/STANDARD speed @ 100kHz  
    SSPADD = I2C_ADDR;                     // SLAVE address is (7bit). Lsb is R/W flag bit
    SSPSTATbits.CKE = 0;                 // Disable SMBus 
    SSPCON1bits.SSPEN = 1;                 // Enable I2C Master port                   
    SSPCON1bits.SSPOV = 0;                 // Clear Buffer Overflow
    SSPCON1bits.CKP = 1;                 // Clock Released  
    SSPCON2bits.SEN = 1;                // Clock stretching is enabled
    INTCONbits.PEIE = 1;                // Enable peripheral interrupts
    INTCONbits.GIE = 1;                 // Enable global interrupts
    PIR1bits.SSPIF = 0;                 // reset MSSP interrupt flag bit
    PIE1bits.SSPIE = 1;                 // Enable serial port interrupts
    BCLIF = 0;                          // Clear the bus collision interrupt flag
    BCLIE = 1;                          // Enable bus collision interrupts
}
 
void interrupt ISR(void)
{
    if(SSPIF)
    {       
        USARTWriteChar('a');
        if(!SSPSTATbits.R_nW)    // read or write can be known from lsb of ADDRESS BYTE
        {    
            if(SSPSTATbits.D_nA)
            {
                CommandByte = SSPBUF;                     // get data
                USARTWriteChar('(');
                OBCcommandresponse();
                //USARTWriteChar(CommandByte);
                USARTWriteChar(')');
 
            }
            if(!SSPSTATbits.D_nA)
            {
                USARTWriteChar('<');
                sendHM_data();
                USARTWriteChar('>');
            }   
        }
    }
    if (BCLIF)                               // Did a bus collision occur? usually in master mode
    {
        crap = SSPBUF;                      // dummy read SSPBUF to clear BF bit
        BCLIF = 0;                          // clear bus collision Int Flag bit
        SSPCONbits.CKP = 1;                // Release CLK
    }
    SSPIF = 0;
}
 
void main()
{ 
        USARTInit(9600);
        USARTWriteChar('b');
        I2C_INIT();
        //SSPIF = 1;
        while(1)
        {
        }
}



Any kind of help is appreciated.
 
Last edited by a moderator:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top