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.

communication rs485 problem interruption in slave reception pic16f1805

Status
Not open for further replies.

mmmary

Newbie level 5
Joined
May 25, 2016
Messages
9
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
81
Hi , i'm doing a project with pic16f1805 , i use a library rs485 from micro c for pic , i need to use interruption in reception of data i simulate with proteus the data is transmitting from master but the 's no interrupt for receive .please can someone help me this is my code : .
Code:
char Dummy ;
char dat[10];
char cnt [10] ;
int i,j ;
sbit  rs485_rxtx_pin at RB6_bit;                  // set transcieve pin
sbit  rs485_rxtx_pin_direction at TRISB6_bit;
bit etat ;
 bit etat_1;
 bit etat_2;


 


void interrupt (void)
{
   if (INTCON.IOCIF==1)
  {
  if ((PORTA.f2==1 )  && (IOCAF.IOCAF2 ==1))

   {PORTC.f6= 1;
   PORTC.f7= 0;
   etat=1;
   Dummy=PORTA ;
     IOCAF.IOCAf2=0 ;

    }
     if ((PORTA.f3==1 )  && (IOCAF.IOCAF3 ==1))

   {PORTC.f7= 1;
   PORTC.f6= 0;
   etat_1=1;
   Dummy=PORTA ;
     IOCAF.IOCAf3=0 ;

    }


   if ((PORTA.f0==1 )   && (IOCAF.IOCAF0 ==1))

   {PORTC.f3= 1;
   PORTC.f4= 0;
   Dummy=PORTA ;
     IOCAF.IOCAf0=0 ;

    }

      if ((PORTA.f1==1 )   && (IOCAF.IOCAF1 ==1))

   {PORTC.f3= 0;
   PORTC.f4= 1;
   Dummy=PORTA ;
     IOCAF.IOCAf1=0 ;

    }
    
    if ((PORTB.f4==1 )  && (IOCBF.IOCBF4 ==1))

   {PORTC.f7= 0;
   PORTC.f6= 0;
   etat_2=1;
   Dummy=PORTB ;
     IOCBF.IOCBf4=0 ;

    }


      INTCON.IOCIF=0;

       }

 else if ( ( PIR1.RCIF==1) )
         {   
          Dummy=RCREG;

         RS485Slave_Receive(dat);
          
            if (dat[5])
            { dat[5]=0;}
          
         if    (( dat[4] )        )
          {
              dat[4]=0;

              switch (dat[2])
            {
            case 1 : 0x01 ;
                   PORTC.F6=1;
                    PORTc.F5=1;

            case 2 : 0x02 ;
                   PORTC.F7=1;


            case 3  : 0x03 ;
                   PORTC.F6=0;
                   PORTC.f7=0;

  }

            }



            PIR1.RCIF=0;
         
         }


}





void main() {


ANSELA=ANSELB=ANSELC=0;
   CM1CON0.C1ON= CM2CON0.C2ON=0;
  TRISC=0b00000111;
  TRISA=0b00000111;
  TRISB=0b00010000;
     INTCON.GIE=1;
     INTCON.IOCIE=1;
     INTCON.IOCIF=0;
     IOCAP=0b00001111 ;
     IOCAP.IOCAP1=1;
      IOCBP=0b00010000 ;
      PORTC.F0=0;
  PORTC.F2=0;
    PORTC.F3=0;
    PORTC.F4=0;
    PORTC.F5=0;
    PORTC.F6=0;
    PORTC.F7=0;
 
 
  RCIE_bit = 1;                        // enable interrupt on UART1 receive
  TXIE_bit = 0;                        // disable interrupt on UART1 transmit
  PEIE_bit = 1;                        // enable peripheral interrupts
  GIE_bit = 1;
  RCIF_bit = 0;
 
   if (PORTA.F1==1)
   {PORTC.F3=0;
   PORTC.F4=1;
      UART1_Init(9600);                    // initialize UART1 module

RS485Slave_Init(160);


   }
   if (PORTA.F0==1)
   {PORTC.F3=1;
   PORTC.F4=0;
  UART1_Init(9600);                    // initialize UART1 module
  Delay_ms(5);
  RS485Master_Init();

   }
 do {
   if (etat==1)
  {
  dat[0] = 0xAA;
  dat[1] = 0xF0;
  dat[2] = 0x0F;
  dat[3]=0         ;
  dat[4] = 0;                          // ensure that message received flag is 0
  dat[5] = 0;                          // ensure that error flag is 0
  dat[6] = 0;

  RS485Master_Send(dat,1,160);



  
  PORTC.f5=1;
  Delay_ms (100);
  PORTC.F5=0  ;
  Delay_ms (100);
    }
       
       if (etat_1==1)
  {
  dat[0] = 0xAA;
  dat[1] = 0xF0;
  dat[2] = 0xFF;
  dat[3]=0         ;
  dat[4] = 0;                          // ensure that message received flag is 0
  dat[5] = 0;                          // ensure that error flag is 0
  dat[6] = 0;

  RS485Master_Send(dat,1,160);




  PORTC.f5=1;
  Delay_ms (100);
  PORTC.F5=0  ;
  Delay_ms (100);
    }
       
       
       if (etat_2==1)
  {
  dat[0] = 0xAA;
  dat[1] = 0xF0;
  dat[2] = 0x0F;
  dat[3]=0         ;
  dat[4] = 0;                          // ensure that message received flag is 0
  dat[5] = 0;                          // ensure that error flag is 0
  dat[6] = 0;

  RS485Master_Send(dat,1,160);




  PORTC.f5=1;
  Delay_ms (100);
  PORTC.F5=0  ;
  Delay_ms (100);
    }

       
         


 }  while(1) ;

}
 

I note that you call the RS485 initialisation library function after you have set the RXIE bit to 1.
Are you sure that the function is not clearing the RXIE bit? In other words, can you see the actual source code for the function?
Alternatively, can use use a debugger to set a breakpoint before and after the function call to verify that the RXIE bit stays set afterwards?
Also I'm not sure that you are using the interrupt correctly. The EUSART interrupt will be called after EACH character is received. Looking at the ISR code it would appear that you are expecting to be able to process a number of characters with the call to 'RS485Slave_Receive' function. This puts a (possibly) blocking function in an ISR which is generally considered a bad idea.
Instead you should create a simple state machine (or similar) in the ISR that handles each character as it is received and puts it into a buffer. When the buffer is complete (however you determine that) then you set a flag or your own (a volatile global variable is a common choice) that you test in the main loop. When the main loop sees the flag set, it can then process the complete buffer.
Finally that MCU has LAT registers for each PORT which are needed to get around the RMW probelm. Therefore you sould always follow the golden rule to "read from the PORT, write to the LAT".
Susan
 

ok i correct it ,
the interruption is working
Code:
 else if ( ( PIR1.RCIF==1) &&(PORTA.F1==1) )
         {
        for ( i=0;i<8;i++)
       { buf[i]=RCREG  ;    }


          cnt=1;
        
         PIR1.RCIF=0;

         }



but in the main the simulation is not correct , RC7 and RC6 both lights one after the other or I only send that data to turn rc6, I did not understand the problem
Code:
  if (cnt ==1)
            {

               if (buf[5])
              {dat[5]=0;}
       if (buf[4])
       {    dat[4]=0;

            if (buf[2]==0xF0)               {              PORTC.F7=1;

               PORTC.F6=0;

               etat_1=0;

              }

else  if (buf[2]==0x0F)               {              PORTC.F6=1;
               PORTC.F7=0;


                }
else  if (buf[2]==0xFF)               {              PORTC.F6=0;
               PORTC.F7=0;

                etat_2=0;
                }
                   buf[2]==0x00;
                  }
               cnt=0;
             }
 

I may have already told you the solution.
I can't relate the latest code snippet back to the original code so I assume that you have re-written some part of the app.
I suspect this is the 'read-modify-write' (RMW) I mentioned above. I suggest that you look this up on the Internet as it is quite a common problem but with a very simple solution.
Fundamentally, while your code relates to setting a single bit on the port, what the hardware does is to read the whole port, internally update the specified bit and then write back the whole port. If the physical hardware has a load on it that slows down the voltage on the pin (even by fractions of a uSec) then when you read the port, you can actually read the wrong value.
For example assume PORT 1 has bit RA1 low and bit RA4 high (I know the compiler syntax used by the free Microchip XC series of compilers - however the intention is clear):
Code:
PORTAbits.RA1 = 1;   // The intent is to change Port A1 bit from low to high
PORTAbits.RA4 = 0;   // The intent is to change Port A4 bit from high to low
          // To do this ALL of the PORT bits will be read by the hardware. If the A1 bit is physically still low
          // then this will read the bit as low, not high
          // When the PORT bits are all written back, then A1 will again be low
You need to set port bits using the LAT register and not directly with the PORT register.
Code:
LATAbits.LATA1 = 1;  // This will set A1 bit high
LATAbits.LATA4 = 0;  // This will set A4 bit low
  // Again, the hardware will read the whole of the LATA register but as the value is NOT affected by
  // the external hardware, it will now see A1 as high. Therefore when it writes back the whole of the 
  // LATA register, all of the bits will be in the correct state. The physical pin A1 will eventually transition to high
The reason for this is that the LAT register is not affected by whatever is physically connected to the pin and so will read back the correct value.
Susan
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top