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 support@ccsinfo.com

Clearing UART Buffer [SOLVED]

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



Joined: 01 Jul 2014
Posts: 41

View user's profile Send private message Send e-mail

Clearing UART Buffer [SOLVED]
PostPosted: Wed Jul 09, 2014 5:14 am     Reply with quote

Hello,

I am using dspic30f6015 in my project.

My code is mainly doing:

1_When data come to UART (RS485 half dublex) enter interrupt.
2_After interrupt occur, disabling interrupt and wait for next 7 byte.
3_After obtaining of total 8 byte data, code doing some duty.
4_When duty has finished clearing interrupt flag and enable interupt again.

Problem:
When code is doing its duty, if there is an data flow over UART even if interrupt disabled when interrupt enabled it enters interrupt.

What i want:
I just want to ignore whole data flow while UART interrupt disabled.

What i tried:
Clear_interrupt before enabling it(NOT WORKED).
Read data in UART buffer 3 times with "int a = getc();"(NOT WORKED)

What i think:
I think problem is because of even interrupt disabled buffer keeps getting data from serial line. i can not disable uart in a function. If i disable uart while code working there are problems occur enabling uart or maybe i set wrong register values in order to disable uart. Can i disable or enable uart in a while loop in main function by setting register values?


My code:
Code:

#USE RS232(stream=RS485,UART1,baud=38400,ENABLE=PIN_G3,parity=N,bits=8,stop=1)  // Set UART1 as RS485 stream
#USE RS232(stream=RS232,UART2,baud=38400,parity=N,bits=8,stop=1)  // Set UART2 as RS232 stream
//
// RS485 receive byte interrupt
#INT_RDA
void isr_rs485_message()
{
   // Receive the RS485 message
   reg_rs485_message = 1; 
}

// Main method
void main()
{
   // Set I/O states of the ports
   //           FEDCBA9876543210
   set_tris_b(0b1111111011111111);
   set_tris_c(0b1111111111111111);
   set_tris_d(0b1111101100111111);
   set_tris_e(0b1111111110000000);
   set_tris_f(0b1111111111111100);
   set_tris_g(0b1111111100110011);
   
   // Turn on debug led
   output_high(LED);
   output_low(RX_Disable);
   output_low(LASER_FLAG);
   // Enable RS485 receive byte interrupt
   enable_interrupts(INT_RDA);
   
   if(debug_mode==1)
   {
      output_high(RX_Disable);   //Receive disabled
      fprintf(RS485,"\n\n\rMODESIS DUZLEMSEL KONUMLAMA SISTEMI\n\r");
      fprintf(RS485,"Konumlama Islemi Icin [0] ---- Yazma Islemi Icin[1]\n\r");
      output_low(RX_Disable);   //Receive enabled
   }
   
   while(true)
   {
      if(reg_rs485_message==1)
      {
         disable_interrupts(INT_RDA);
         reg_rs485_message=0;
         get_data();
         
         // Enable RS232 receive byte interrupt
         clear_interrupt(INT_RDA);
         enable_interrupts(INT_RDA);
   
         if(debug_mode==1)
         {
            output_high(RX_Disable);   //Receive disabled
            fprintf(RS485,"\n________________________________________________________________________\n\r");
            fprintf(RS485,"\nMODESIS DUZLEMSEL KONUMLAMA SISTEMI\n\r");
            fprintf(RS485,"Konumlama Islemi Icin [0] ---- Yazma Islemi Icin[1]\n\r");
            output_low(RX_Disable);   //Receive enabled
         }
      }
   }
}



Last edited by erhane on Wed Jul 09, 2014 6:38 am; edited 1 time in total
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Jul 09, 2014 6:18 am     Reply with quote

A serial receive interrupt, RDA, means one, or possibly more (but only if the interrupt has been disabled for a relatively long time), characters have been received. It does not mean a message has been received, nor that the start of a message has been received.

Its best not to mess about with RDA enables. Just leave them on and deal with characters one by one in the ISR. A serial receive ISR should read the character that's just been received, store it in some buffer - circular, linear, packet based, whatever - and raise some flag if it means something special, like end of line/message/packet, which all mean something worth processing is in the buffer.

Mainline code should simply look for the flag and read from the buffer to get its data.

Too often people think the start of a line/message/packet is the important bit. No, generally its not, its the end when things have to happen. Having an ISR look for the start of a message and then read the whole message in one simply jams up the processor for the whole sending time of the message. And what happens if something goes wrong and too few characters get sent for some reason? The ISR jams up waiting, and the code effectively dies, that's what.

Instead, an ISR should always be ready to receive and deal with a character. That may be as simple as stuffing it into a buffer, or it may be as complex (relatively speaking) as running it through a packet receiving state machine which detects that framing of the data, checks for errors, including checking the CRC and so on and buffers only the actual payload of the packet.

The general rule for ISRs is: Get in quick, do the minimum necessary and get out fast. Don't hang around, don't use delays, don't wait for anything and don't print or otherwise output anything and don't fiddle around with interrupt enables unless you absolutely have to, which in almost all serial receive ISRs is never.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Jul 09, 2014 6:29 am     Reply with quote

let me add one comment to RF_D's EXCELLENT exposition.

The cleanest way to handle clearing the ISR buffer to simply
set the next_char_OUT pointer to the same value as
the next_char_IN pointer VAR. Never mess with the int enables!
as long as the buffer uses unsigned INT8 pointer vars, this approach can't fail.
temtronic



Joined: 01 Jul 2010
Posts: 9197
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jul 09, 2014 6:31 am     Reply with quote

RF_D is 100% correct AND CCS supplies a working example of how to do it !

Called ex_sisr.c, located in the examples folder.

I know it works ! Slightly modified,I have an 18F46K22 using BOTH UARTs at 115k200 for the past couple of years. No need to 'reinvent the wheel' as CCS has done it for you !!


jay
erhane



Joined: 01 Jul 2014
Posts: 41

View user's profile Send private message Send e-mail

PostPosted: Wed Jul 09, 2014 6:38 am     Reply with quote

Thank you all. I will work on it. Your answers enlightened me.
erhane



Joined: 01 Jul 2014
Posts: 41

View user's profile Send private message Send e-mail

PostPosted: Wed Jul 09, 2014 10:48 am     Reply with quote

i want to add something.

i am disabling interrupts because i am driving stepper motors and i have to generate steps like;

while(steps<10000)
{
output_high(pin);
delay_us(10);
output_low(pin);
steps--;
}


If i dont disable interrupts don't this step routine disturb?

What can you suggest about interrupts in pulse generate applications?
Ttelmah



Joined: 11 Mar 2010
Posts: 19433

View user's profile Send private message

PostPosted: Wed Jul 09, 2014 11:29 am     Reply with quote

The stepper should be being driven from an interrupt.....

I've replied in your other thread about this.
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