Problem in PIC to PIC Synchronous Communication

Discussion in 'Embedded Systems and Microcontrollers' started by Tajiknomi, Nov 24, 2015.

  1. Tajiknomi

    Thread Starter Member

    Mar 18, 2010
    The purpose of my simulation was to implement Synchronous communication between two PIC's. One as a master and another as a slave. I have read the data sheet in order to understand the configuration before programming both.
    So i have programmed both PIC (16f877A) using IDE (MicroC pro) & Simulated the circuit in Proteus-8 professional.

    How the circuit should work ? (Kindly check the attached snapshot)
    1) The master PIC should acknowledge the IOC(Interrupt on change) at RB5.
    2) After moving to IOC ISR, it should transmit the status of PORTA serially to Slave PIC.
    3) The Slave PIC should receive the byte & transfer the byte to its PORTB.

    Problem : The transmitter (Master PIC) transmits the byte but the "Receiver (Slave PIC) receive-interrupt ISR doesn't execute"

    Note : In the Transmit ISR & Receive ISR both contains a line which flip the bits of PORTB. But when i execute the program, it works fine for Master PIC (transmitter) but doesn't work for Slave(Receiver), which means that Transmit ISR execute fine but Receive ISR doesn't execute at all !

    Transmitter (Master Code)

    Code (Text):
    2. /*     USRT Transmit module ( Synchronous Transmission ) (Master Mode)
    3.         It will transfer data via Tx pin respectively
    4.         Baud Rate = 9600
    5.         BRGH = 1 (High speep Baud rate generator) -- Used to Minimize the percentage error in baud rate (Visit Data sheet to see it)
    6.         Frequency of MCU = 4MHz
    7.         For different frequencies, calculate value of SPBRG = [Fosc/4(Desire-Baud.Rate)]-1
    8.         Value computed for SPBRG should be convert to Hexa before putting it in SPBRG (as in the below code)
    10.         IOC (Interrupt on change) pins [RB4-RB7], when signal status is changed on one of these pins,it will cause interrupt
    11.         In ISR module, PORTA [RA0-RA3] will be read in variable "dummy" and transfer synchronously
    12. */
    14. char dummy = 0x00;
    15. void interrupt(){
    17. if (INTCON.RBIF == 1){                        // Change interrupt
    18.            PORTB.f0 = !PORTB.f0;              // Its just for checking that program execute this section or not (For each PORTB-Change-Interrupt) It works
    19.            TXREG = PORTA;                     // Assign PORTA to Tx reg
    20.            dummy=PORTB;                       //  MUST Read PORTB, otherwise flag (RBIF) will not clear
    21.            INTCON.RBIF = 0;                   // Clear flag
    22. }
    24. }
    25.   void main()
    26.   {
    27.       TRISA = 0x0F; TRISB.f0=0;                  // [RA0-RA3] = Inputs
    28.       TRISB.f5 = 1;                              // RA5 = Input (Used as IOC (interrupt on change))
    29.       ADCON1 = 0x06;                             // PORTA I/O as Digital I/O
    30.       SPBRG = 0x67;                             // decimal = 103, Baud-rate = 9600 , BRGH = 0
    31.       TXSTA.SYNC=1; RCSTA.SPEN=1; TXSTA.CSRC=1; // Master clock from BRG, Synchronous mode, Enable Serial ports
    32.       TXSTA.TXEN=1;                            // Transmission Enable
    33.       INTCON=0xC8;                             // {Global interrupts , PORTB Change interrupt} = Enable
    35.       while(1);
    36.   }

    Receiver (Slave code)

    Code (Text):
    1. //     USRT Recive module ( Synchronous Receiving) (Slave Mode)
    3. char dummy=0x00;
    4. void interrupt(){
    6. if (INTCON.RCIF == 1){           // Byte Received ?
    8.            dummy = RCREG;        // Read the Byte
    9.            PORTB = ~PORTB;       // Used for checking whether this ISR is executing after every transmission or NOT ? (IT DOESN'T)
    10.            INTCON.RCIF = 0;      // Clear Flag
    11. }
    13. }
    14.   void main()
    15.   {
    17.       TRISB = 0x00;                // PORTB = Output
    18.       TXSTA.SYNC=1; RCSTA.SPEN=1; //  Enable Synchronous mode , Enable Serial ports
    19.       TXSTA.CSRC=0;               //  Clock source =  Master device
    20.       PIE1.RCIE=1;                // Recieve interrupt Enable
    21.       RCSTA.CREN=1;               // Continous receive enable bit
    22.       INTCON.GIE=1; INTCON.PEIE=1; // Global and Peripheral interrupts Enable
    23.       PORTB = 0x00;                // Clear PORTB
    24.       while(1);                    // Do nothing
    25.   }
    Last edited: Nov 24, 2015
  2. Jim Brooks

    New Member

    May 19, 2014
    Your Schematic show TX to TX and RX to RX they shoud be TX to RX
  3. Papabravo


    Feb 24, 2006
    Something does not compute. In synchronous mode you need transmit data and transmit clock on one module. On the other module you need receive data and receive clock.

    On the schematic you must connect:
    1. transmit clock to receive clock
    2. transmit data to receive data
    It is not clear from your symbols which is which, but they are possibly correct. In the firmware the pins must be correctly configured for this to work. I think pin 25 is the clock and pin 26 is the data. Is that correct?

    Also I don't see any configuration for RC6 and RC7 or the the synchronous clock.

    Synchronous communication is half duplex with two wires, that is the data only moves in one direction.
    Last edited: Nov 24, 2015
  4. Papabravo


    Feb 24, 2006
    Correct for asynchronous mode -- not for synchronous mode.
  5. Jim Brooks

    New Member

    May 19, 2014
    Sorry my mistake I should have read the post more carefully
  6. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    Even after you rewire both Tx lines to the others Rx lines I would be very surprised any simulator could simulate the reception of data out of one device and into another like this, though I am most familiar with the sim in MPLAB which is quite elementary.

    Check the Proteus manual to see how good simulated outputs are at driving other pins.

    You may need to test transmit and receive separately in sim while they work flawlessly on the real chips, which is why I prefer to build the dang thing and use an in circuit debugger to test the code.

    Even the lowly PICkit can do in circuit debugging, though I am unsure if MicroC is capable inside MPLAB.
  7. Tajiknomi

    Thread Starter Member

    Mar 18, 2010
    @Papabravo : If i am not wrong, pins connections are fine. In synchronous i have connected the DT to DT and Ck to Ck. I have configured properly (From the Data-sheet) & reviewed my configuration many times so that i can possibly find some configuration error, but i wasn't lucky.
    Configuration -- > Transmitting code : Line {31,32} , Receiving code : Line {18,19,20,21}
    @ErnieM : Today i just thought about maybe Proteus isn't able to cope it (Synchronously). But i don't know yet. I haven't use Sim simulator though, i will try it if it worked in this scenario.

    I am just trying to perform all Serial Communication Protocol in order for better understanding so that in future i maybe able to use these in practical devices. If there any simulation environment other then Proteus which can cope with these situations, I will be glad to hear it.

    P.S : Thanks for your kind replies
    Last edited: Nov 24, 2015