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 CCS Technical Support

(running) 18F problem receiving data rs232 (USART locked)

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



Joined: 28 Jun 2009
Posts: 4

View user's profile Send private message

(running) 18F problem receiving data rs232 (USART locked)
PostPosted: Sun Jun 28, 2009 4:41 pm     Reply with quote

Hello everybody, I'm a new component in this forum. I need help with comunication PIC -> PC, receipt from a 18F4520 PIC and a PC via RS232. I am programming with CCS C, everything works well in a time 10sec - 1min RDA interruption but then no fire. Still sending data PIC -> PC, but on the contrary ignores the data it receives. It's as if USART locked using the reception. I have simulated Proteus and passes it and then test and then the PIC and it happens as in the simulation.
Code:

#include <18F4520.h>
#device ADC = 10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=19200, parity=N, xmit=PIN_C6, rcv=PIN_C7)

#int_rda
void rda_isr() {
if(kbhit()){

codigo_buffer[indice_rs232] = getc();
indice_rs232 = indice_rs232 + 1;

if (codigo_buffer[0]=='$' && codigo_buffer[9]=='#'){
   indice_rs232 = 0; /
  duty_PWM1 = make16(codigo_buffer[1], codigo_buffer[2]);
  set_pwm1_duty(duty_PWM1); //Actualizo el PWM
}
}
}
}

I do not know what is happening or how to solve. I tried to activate interrupts but still the same.

A greeting and thanks.


Last edited by niuton on Mon Jun 29, 2009 4:03 pm; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 28, 2009 4:59 pm     Reply with quote

You didn't post a complete test program. Are you disabling INT_RDA
interrupts in your program ? If so, it's possible that the UART could
get an overrun error. This would lock up the UART. Add the ERRORS
parameter to the #use rs232() statement to automatically clear an
overrun error. Example:
Quote:

#use rs232(baud=19200, parity=N, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
Guest








PostPosted: Sun Jun 28, 2009 5:25 pm     Reply with quote

Hi,

A couple of things. You can get rid of the kbhit() statement inside your ISR. It's redundant - if the ISR fires, by definition you have a character waiting in the Rx buffer. Also, get rid of everything inside the ISR that is not related to receiving characters and putting them in your receive buffer. Instead, set a Rx_Valid flag (for example) and do all your Make and PWM funtions in Main. This is much better programming style, although I don't believe either is the culprit in your current problem....

Frank
niuton



Joined: 28 Jun 2009
Posts: 4

View user's profile Send private message

PostPosted: Sun Jun 28, 2009 5:38 pm     Reply with quote

Thanks for replying so quickly (PCM_programer and FRANK),

Frank: You're right, I have to change the contents of the RDA and put it in the main.

PCM_programer: I did not disable the interruption RDA.

I have made a VB program that sends data every 50ms to the PIC.

I tried to include the "ERRORS" and somewhat improved but still failing by losing many packages. Do you know any solution?

Code:


#include <18F4520.h>
#device ADC = 10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=19200, parity=N, xmit=PIN_C6, rcv=PIN_C7)

#define ALL_OUT 0
#define ALL_IN 0xff
#define numero 10     

int8  t_Vref = 0, Vref_flag = 0;
int16 tension_V, tension_F;

unsigned int16 duty_PWM1 = 0;

#define MAX_PWM 1000
#define MIN_PWM 0

int1 comenzar=0;     
int1 hay_comando=0; 
int16 muestreo = 0x0BDC;
int8 codigo_buffer[numero],indice_rs232=0;


void read_Vel(void)   
{
   delay_us(10);
   SET_ADC_CHANNEL(2);  //MOTOR "R"
   delay_us(10);
   tension_F = READ_ADC();
}

#int_rda
void rda_isr() {

  if(kbhit()){

    codigo_buffer[indice_rs232] = getc();
    indice_rs232 = indice_rs232 + 1;
   
    if (comenzar == 1 && codigo_buffer[0]=='$' && codigo_buffer[9]=='#'){
     
      indice_rs232 = 0;   
      if (codigo_buffer[1] != 0x46){ 
         
         duty_PWM1 = make16(codigo_buffer[1], codigo_buffer[2]);
         set_pwm1_duty(duty_PWM1);     
      }else
         comenzar = 0;
             
      codigo_buffer[0]=0;
      codigo_buffer[9]=0;     
    }
  }
}

#int_TIMER3
void timer3_isr(void){

   set_timer3(muestreo);

   read_Vel();   
   
         putc('$');     
         putc(tension_F>>8);
         putc(tension_F&0x00FF);
         putc('#');
}

//////////////////////////////////////////
//////////////////////////////////////////
void main() {

delay_ms(333);
disable_interrupts(global);
 
set_tris_d(0x00);//ALL_OUT);
set_tris_b(0x00);//ALL_OUT);

setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_32);

setup_timer_3(T3_INTERNAL|T3_DIV_BY_4);
setup_ccp1 (CCP_PWM); 
setup_ccp2 (CCP_PWM);   
setup_timer_2(T2_DIV_BY_1, 250, 1);

set_pwm2_duty(duty_PWM1);
set_pwm1_duty(duty_PWM1);

enable_interrupts(int_rda);

port_b_pullups(true);

delay_ms(300);
output_high(PIN_B7);
enable_interrupts(global);
set_timer3(0x0BDC);

While(TRUE){
   
  enable_interrupts(INT_TIMER3);
}
}


Last edited by niuton on Sun Jun 28, 2009 6:05 pm; edited 2 times in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 28, 2009 6:04 pm     Reply with quote

Quote:
#int_TIMER3
void timer3_isr(void){

set_timer3(muestreo);

read_Vel();

putc('$');
putc(tension_F>>8);
putc(tension_F&0x00FF);
putc('#');

}

These four characters will take a minimum of 3 character period (0.5 ms
each) to send. During that time, the #int_rda interrupt can't be
handled. The UART receiver will get an overrun error, and it will lock up.
niuton



Joined: 28 Jun 2009
Posts: 4

View user's profile Send private message

PostPosted: Sun Jun 28, 2009 6:14 pm     Reply with quote

PCM programmer You're right, I simulated proteus and note that activates the overflow flag "OERR" that the two FIFO is full.

OERR is activated that when I'm sending four data and receive data from the PC to jump RDA interrupt.

I send the data every 50ms PC-> PIC and 19200baud can transmit and receive 120byte every 50ms according to the calculations.

How can I fix it?

Thank you very much again.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 28, 2009 6:27 pm     Reply with quote

Don't send the 4 characters from within the #int_timer3 routine. Instead,
set a global flag in the #int_timer3 routine. Continuously test this flag
in your while() loop in main(). If the flag is set, then clear it, and send
the 4 characters from code that is inside the while() loop in main().
niuton



Joined: 28 Jun 2009
Posts: 4

View user's profile Send private message

PostPosted: Mon Jun 29, 2009 4:02 pm     Reply with quote

Thank you very much for the help, and running the program.

I saw that the command putc ( 'a') needs 0.5ms to send the character for RS232. Is there another command or routine that takes less time?

thank
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 29, 2009 4:19 pm     Reply with quote

You could use an INT_TBE interrupt routine with a buffer. Then the only
delay presented to the PIC is the interrupt service time. This is probably
about 15 us, with a 20 MHz clock.

See the following example file:
Quote:
c:\Program Files\picc\Examples\Ex_stisr.c
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