[SOLVED] PIC18f4520 serial communication problem from one laptop to another.

Status
Not open for further replies.

djc

Advanced Member level 1
Joined
Jan 27, 2013
Messages
402
Helped
3
Reputation
6
Reaction score
2
Trophy points
1,298
Location
India
Visit site
Activity points
4,554
Hello,
Sometimes back i wrote a code for serial communication using PIC18F4520 and mikroc pro. I tested it using USART terminal provided with mikroc. It is working fine. means controller is able to accept and send the data. Then i tasted it on another laptop with same USART terminal. It worked fine. Both these laptop are having Windows 7 32 bit system. Then i tested it on windows 8 with same USART terminal software. Here it failed to work. Means no data is being accepted or sent by microcontroller. I then tested it with another hyperterminal software on same laptop. But it didn't work. I then tested on another laptop which has windows 7 64 bit system. But it didn't work. Here is the code for serial communication interrupt,
Code:
void interrupt(){

         if(PIR1.RCIF){
            MAX_CONTROL=0;
            if ((RCSTA.OERR )&& (RCIE_bit==1)){
            RCSTA.CREN = 0;
            Nop();
            Nop();
            RCSTA.CREN = 1;
            garbage=RCREG;
            garbage=RCREG;
            }
             else{

                                                    input_string[index]=RCREG;
                                                    if(input_string[index]==59){
                                                             flag=1;
                                                    }
                                                    index++;
                                                    if((index>12) && (input_string[12] != 59)) index=0;
                                                    

            }
          PIR1.RCIF=0;
         }
       if(flag==1){
                                  if((input_string[0]== 82) && (input_string[1]==59)){
                                   MAX_CONTROL = 1;
                                                     Delay_ms(1);
                                                     UART1_Write(FND_0+65);
                                                     UART1_Write(FND_1+65);
                                                     UART1_Write(FND_2+48);
                                                     UART1_Write(FND_3+48);
                                                     UART1_Write(FND_4+65);
                                                     UART1_Write(FND_5+65);
                                                     UART1_Write(FND_6+48);
                                                     UART1_Write(FND_7+48);
                                                     UART1_Write(FND_8+48);
                                                     UART1_Write(FND_9+48);
                                                     UART1_Write_Text("\r\n");
                                                     Delay_ms(1);
                                   MAX_CONTROL = 0;
                                  }
                                  if((input_string[0]== 87) && (input_string[11]==59)){
                                                      write=1;
                                  }
                                  index=0;
                                  flag=0;
         }
       if(sent==1){
                                                      MAX_CONTROL = 1;
                                                      UART1_Write_Text("\r\nOK");
                                                      Delay_ms(1);
                                                      MAX_CONTROL = 0;
                                                      sent=0;
       }


      if(INTCON.TMR0IF){
                    TMR0L = TIMER_START_VALUE;
                    TMR0H = TIMER_START_VALUE_1;
                    TMR0IF_bit = 0;
                    }

                    if(prg_key==1){
                    blink++;
                    if(blink>500) blink=0;
                    last++;
                    }
      
}
Can anybody please tell me that why it is working on one computer and why not on another one?
 

Hi,

from your description it seems the microcontroller works (somehow), but the problem is the laptop and/or the software.

Maybe a timing problem.

You should show us your PC software.
I won´t be surprised if you use wait loops instead of timers...


Klaus
 

@easyrider
Yes. It is working. I tried to minimize the interrupt routine. Like i tried to implement 'UART1_Write(FND_0+65);' routine in main. Tried to send whole 10 bytes in main routine, along with 'if(send==1)' condition. However it didn't work in main routine but it worked in interrupt.

@klausst
Software is USART terminal provided with mikroc pro for PIC. No wait loop is used in interrupt. Two different flags for interrupt and timers are getting checked.

- - - Updated - - -

.
Here is the software of USART.
 

I side with Easyrider83 on this one. I am very suprised it works at all. There are far too many delays as each byte is received for it possibly to send them and be ready for the next byte to arrive.

Consider that the time to send a byte is at least as long as the time it takes to receive one. If you try to send 11 bytes and also use delays inside the ISR I predict you will lose at least 95% of incoming bytes unless they have very long delays between them. You need to move all the 'UART_Write' instructions out of the ISR and remove all the delays and Nop(); instructions.

Brian.
 

KlausST, what do you think, how it can work?
Thanks god, it is just a toy, not the controller of cooling system in nuklear plant.
I recommend autor to learn how to use interrupts and how to work with uart to prevent such issues in a future.
 

Hi,

@Easirider83.
I just had a short view on the code. I really didn´t check if it is able to run..

I just referred to the OP´s saying "it´s working fine":
I tested it using USART terminal provided with mikroc. It is working fine. means controller is able to accept and send the data. Then i tasted it on another laptop with same USART terminal. It worked fine.

I´m with you: Thanks god its no: elevator control, airbag control.....


Klaus
 

Is that the only reason why it is running on one computer and not on another?

@brian
i tried to move UART_Write routine in main, however it is not working in main. Thats why i had to move it in interrupt. I will try to make some more changes.
 

In PC where it is not working Oprn Control Panel and Open Device Manager. In that expand COM Ports and then select the COM port used for communication and then open its properties and set baudrate properly as used in mikroC Code.
 

Ignoring the obvious timing issue, I'm not sure what your code is supposed to do. I've copied it below with the formatting changed and some minor corrections but the underlying problem is still the other functions inside the ISR. Please confirm the code below is what you intended before I look further.

Brian.

Code:
void interrupt()
{
 if(PIR1.RCIF)
 {
  MAX_CONTROL=0;
  if ((RCSTA.OERR )&& (RCIE_bit==1))
  {
   RCSTA.CREN = 0;
   RCSTA.CREN = 1;
   garbage=RCREG;
   garbage=RCREG;
  }
  else
  {
   input_string[index]=RCREG;
   if(RCREG == ';') flag=1;
   index++;
   if((index>12) && (input_string[12] != ';')) index=0;
  }
  PIR1.RCIF=0;
 }

 if(flag==1)
 {
  if((input_string[0]== 'R') && (input_string[1]== ';'))
  {
   MAX_CONTROL = 1;
   Delay_ms(1);
   UART1_Write(FND_0+'A');
   UART1_Write(FND_1+'A';
   UART1_Write(FND_2+'0';
   UART1_Write(FND_3+'0');
   UART1_Write(FND_4+'A');
   UART1_Write(FND_5+'A');
   UART1_Write(FND_6+'0');
   UART1_Write(FND_7+'0');
   UART1_Write(FND_8+'0');
   UART1_Write(FND_9+'0');
   UART1_Write_Text("\r\n");
   Delay_ms(1);
   MAX_CONTROL = 0;
  }
  
  if((input_string[0]== 'W') && (input_string[11]== ';')) write=1;

  index=0;
  flag=0;

  if(sent==1)
  {
   MAX_CONTROL = 1;
   UART1_Write_Text("\r\nOK");
   Delay_ms(1);
   MAX_CONTROL = 0;
   sent=0;
  }

  if(INTCON.TMR0IF)
  {
   TMR0L = TIMER_START_VALUE;
   TMR0H = TIMER_START_VALUE_1;
   TMR0IF_bit = 0;
  }

  if(prg_key==1)
  {
   blink++;
   if(blink>500) blink=0;
   last++;
  }

}
void main() 
{

}
 

Re: MikroC Project check plz

Don't want to harp on about the broken interrupt code.

Possible reasons why the PC terminal is behaving different on two computers:
- trivial explanation. You don't manage to open the right COM port with correct baud rate.
- similar problem level. The terminal software has different settings on both computers.
- less obvious. You are using USB-to-UART bridges with different latency settings in the driver parameters (can happen e.g. with FTDI).
 

Modified interrupt routine.
Code:
void interrupt(){

         if(PIR1.RCIF){
            MAX_CONTROL=0;
                                                    input_string[index]=RCREG;
                                                    if(input_string[index]==59) flag=1;
                                                    index++;                               
            PIR1.RCIF=0;
         }

         if(INTCON.TMR0IF){
                    TMR0L = TIMER_START_VALUE;
                    TMR0H = TIMER_START_VALUE_1;
                    TMR0IF_bit = 0;
                    }

                    if(prg_key==1){
                    blink = ~blink;
                    last++;
                    }
 }
Used different hyperterminal program on computer which was not working. As of now it's working. It was rather more of hyperterminal issue.
 

Also, don't forget to declare variables used in interrupt as 'volatile' to prevent optimisation and data corruption in heap.
Now it looks better for sure.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…