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

Receive UART data independently of data length
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Requan



Joined: 11 May 2008
Posts: 74

View user's profile Send private message

Receive UART data independently of data length
PostPosted: Tue Jan 29, 2013 5:33 am     Reply with quote

Hi,
I wrote program to receive data in Uart interrupt independently of data lengh, so:

1) in Uart interrupt i receive single byte and start timer
Code:

#int_rda
void serial_isr()

   buffer[index]=fgetc(RS485);
   if(++index == BUFFER_SIZE)
   {
      index = 0;
   }
   set_timer1(40538); 
                                 
  clear_interrupt(int_TIMER1);
  enable_interrupts(int_TIMER1);
}

2) Each time when program received byte timer is reset, when uart finish receive data, then timer will overflow and analize data:
Code:

#int_TIMER1
void TIMER1_isr()
{
   disable_interrupts(int_TIMER1);
 
   for(int i = 0;i < index; i++)
   {
      Modbus.Buffer[i] = buffer[i];
   }
   ModbusCalcCrc(0,index - 2);

   if((Modbus.Buffer[index - 1] == Modbus.CRC_Hi) && (Modbus.Buffer[index - 2] == Modbus.CRC_Lo ))
   {
     if((Modbus.Buffer[0]==SlaveID)) //check address
      {
         int8 ReceivedFunctionCode = 0;
         ReceivedFunctionCode =  Modbus.Buffer[1];
         Modbus.StartAddress = make16(Modbus.Buffer[2],Modbus.Buffer[3]);
         Modbus.RegisterQty  = make16(Modbus.Buffer[4],Modbus.Buffer[5]);
         
         if(ReceivedFunctionCode == 0x03)   
         {
            TakeDataToBuffer(Modbus.StartAddress, Modbus.RegisterQty);
            ModbusReadRegisters_Response(SlaveID,Modbus.StartAddress, Modbus.RegisterQty);
         }
         
      }
   }
  index = 0;
}


When new data will receive by uart timer will start again.

It works but sometimes PIC will hang. I now for sure because in main loop i blinking diode (and diode stop blinking(:
Code:

#include <18F14K22.h>
#fuses HS, PUT,NOPLLEN,NOPCLKEN,NOWDT
#use rs232(baud=9600, xmit=PIN_B7, rcv=PIN_B5,bits=8,parity=N,stop=1,ENABLE = PIN_C0, ERRORS,stream = RS485)

void main()
{
   
   enable_interrupts(global);
   enable_interrupts(int_rda);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
   disable_interrupts(int_TIMER1);                          // Clear timer1 overflow Interrupt Flag bit

   ModbusInit();
   while(TRUE)   
   {
      output_high(LedOK);
      delay_ms(50);
      output_low(LedOK);
      delay_ms(50);
   }
}


Do You know what i missed?
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Tue Jan 29, 2013 6:28 am     Reply with quote

sorry but i do not see the purpose of the timer1 interrupt.

managing the received bytes can be done in MAIN by testing buffer contents , w/o ints at all -
and the management of the timer interrupt inside the RDA isr looks problematic with high speed data reception, to me.
Requan



Joined: 11 May 2008
Posts: 74

View user's profile Send private message

PostPosted: Tue Jan 29, 2013 6:39 am     Reply with quote

Arrow asmboy
Thanks for reply.

This is test version of my program. In Main loop i will have some thinks to do and don't want to check all time, if all data will available or not.
Timer interrupt solve this problem because when it will be overflow, it will equal that all data was received.

Best Regards,
Martin
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Tue Jan 29, 2013 6:49 am     Reply with quote

and your clock frequency is ??
Requan



Joined: 11 May 2008
Posts: 74

View user's profile Send private message

PostPosted: Tue Jan 29, 2013 7:03 am     Reply with quote

sorry, 20Mhz
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Jan 29, 2013 7:16 am     Reply with quote

There are a CCS supplied examples of Modbus on PICs such as ex_modbus_slave.c. They all use a CCS Modbus driver, modbus.c. It works. Please look at the examples and if at all possible use the driver. It will save you massive amounts of time and hassle.

Its very difficult to do your own due to the tight timing requirements of Modbus.
Requan



Joined: 11 May 2008
Posts: 74

View user's profile Send private message

PostPosted: Thu Jan 31, 2013 7:49 am     Reply with quote

Quote:

There are a CCS supplied examples of Modbus on PICs such as ex_modbus_slave.c. They all use a CCS Modbus driver, modbus.c. It works. Please look at the examples and if at all possible use the driver. It will save you massive amounts of time and hassle.

My application works well with factory HMI panels, i don't have problem with modbus.

I think it is very good idea to receive data at background without checking all time if data is complite or not and of course independently of data lenght (we dont need to use CR or LF).
Few years ago i apply it on different compiler and it worked without any problem, so i think that it is compiler problem. I start regret that we decided to bought CCS compilers, because it has some things that should work but it does not. Sad
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Thu Jan 31, 2013 2:13 pm     Reply with quote

Quote:

so i think that it is compiler problem. I start regret that we decided to bought CCS compilers, because it has some things that should work but it does not.


Wow !!
it would help ME to know exactly what you found the compiler problem to BE.

And also merely a few things that the CCS compiler does not do correctly.

I ask because of having very good results with CCS when Hitech C was very very BAD and hard to use in my case.

perhaps if you share your critical specifics , others may benefit from your
deductive reasoning and sleuthing. And I am always willing to learn from somebody more experienced smarter than I on such arcane issues.
Requan



Joined: 11 May 2008
Posts: 74

View user's profile Send private message

PostPosted: Fri Feb 01, 2013 8:55 am     Reply with quote

Code:

Wow !!
it would help ME to know exactly what you found the compiler problem to BE.

And also merely a few things that the CCS compiler does not do correctly.

I ask because of having very good results with CCS when Hitech C was very very BAD and hard to use in my case.

perhaps if you share your critical specifics , others may benefit from your
deductive reasoning and sleuthing. And I am always willing to learn from somebody more experienced smarter than I on such arcane issues.

Hitech is simply and bad...
so try to do in CCS what i decribe above.
I did on different compilator on PIC and also without problem on ATMEL (also c environment) only on CCS i couldn't and even support can't help me, so base on it i regret to purchases CCS. I am know that i am not a CCS expert so i am ready to learn from more experience user as You. I am looking forward on results of Your tests...
temtronic



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

View user's profile Send private message

PostPosted: Fri Feb 01, 2013 9:28 am     Reply with quote

The line below was cut from the CCS C Help file(press F11 when project is open)....in the FAQ section...How do I get getc() to timeout after a specified time?

#use rs232(UART1,baud=9600,timeout=500) //timeout = 500 milliseconds, 1/2 second

when using 'getc()' it will timeout after 1/2 second if a character fails to come in 'UART1'.

CCS also supplies several other examples/code snippets of getting data from RS232 (aka serial lines) and timing out. When used with an ISR and ring buffer (as CCS supplies !) it forms a solid reliable 'background' method of getting data. Even at 115k200 their software works fine.

hth
jay
Requan



Joined: 11 May 2008
Posts: 74

View user's profile Send private message

PostPosted: Tue Feb 05, 2013 11:36 am     Reply with quote

Arrow temtronic
Thanks for as always priceless advice.

I agree with You that all UART CCS examples works fine, but all these examples require checking receiving data all time in main loop by program.

Best Regards,
Martin
Ttelmah



Joined: 11 Mar 2010
Posts: 19335

View user's profile Send private message

PostPosted: Tue Feb 05, 2013 12:03 pm     Reply with quote

Not really. If you use the EX_SISR, then the only requirement is that the buffer is checked more frequently than the time it'd take to overflow. If you add flow control, this can be infinite if required......

Best Wishes
jeremiah



Joined: 20 Jul 2010
Posts: 1322

View user's profile Send private message

PostPosted: Tue Feb 05, 2013 12:08 pm     Reply with quote

A couple things:

1. You are declaring variables after code. This should not be done. The compiler won't complain, but I can tell you from experience, there can be bugs introduced by doing this. So your "i" variable in your for loop and your "ReceivedFunctionCode" variable should probably be moved to the top of your isr.

2. where is "index" declared? I cannot find it for some reason.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Feb 05, 2013 3:55 pm     Reply with quote

Requan wrote:
Quote:

There are a CCS supplied examples of Modbus on PICs such as ex_modbus_slave.c. They all use a CCS Modbus driver, modbus.c. It works. Please look at the examples and if at all possible use the driver. It will save you massive amounts of time and hassle.

My application works well with factory HMI panels, i don't have problem with modbus.
if you didn't have problems, then you wouldn't be here at this forum. Cool
With comments like this you are not making friends. What RF_Developer tries to tell you is that it is better to use proven code than to roll your own.

Quote:
I think it is very good idea to receive data at background without checking all time if data is complite or not and of course independently of data lenght (we dont need to use CR or LF).
Yes, the idea is good. What worries a bit is that we can't check how much time the Timer1 interrupt will take. Interrupts should be as quick as possible to avoid unexpected interaction between interrupts. Some of the called functions have names that suggest a major amount of computation time...

Quote:
Few years ago i apply it on different compiler and it worked without any problem, so i think that it is compiler problem. I start regret that we decided to bought CCS compilers, because it has some things that should work but it does not. Sad
You do know how to get attention (in a negative way).
The CCS compiler does have its weaknesses, but 99 out of 100 times it is the programmer who made an error. Whenever I see a programmer blaming failure on the compiler then you really have to come with hard evidence or I wiill assume you are trying to blame the compiler to hide your own incompetence.

A few notes:
1) Forum guidelines say you have to post your compiler version number in every new thread. I just checked most of your postings; you never once mentioned your compiler version number, not even when I asked for it. Without that number this is a useless discussion. Perhaps you are using one of the known unstable alpha test versions.

2) You say the code hangs because the LED stops blinking. Is this the only debugging tool you have? Professional software development requires you to use a debugging tool like ICD3, then you can 'look into' the processor and see what it is doing instead of guessing what you do now.
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Tue Feb 05, 2013 4:49 pm     Reply with quote

While the example handler for modbus is admittedly verbose and perhaps overly general purpose, it still gives a very clear and well thought out approach to doing the job you are failing at. I'd read it again , if i were you.

From the start I have had an uneasy feeling about what goes on in your timer ISR, and about what you are trying to do IN said a timer ISR in the first place.
we have.........
Quote:

ModbusCalcCrc(0,index - 2);


gives me a very uneasy feeling that if that function is what i think it is-
you are spending a lot of time with other INTS disabled .
maybe too much

i for one would NEVER put a crc calc into an ISR.

perhaps its just me being very conservative, but i suggest reducing code in ANY ISR to be as deterministic, and fast executing as possible.

Why ? E X P E R I E N C E ! !
Very Happy Very Happy Very Happy Very Happy
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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