View previous topic :: View next topic |
Author |
Message |
Requan
Joined: 11 May 2008 Posts: 74
|
Receive UART data independently of data length |
Posted: Tue Jan 29, 2013 5:33 am |
|
|
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
|
|
Posted: Tue Jan 29, 2013 6:28 am |
|
|
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
|
|
Posted: Tue Jan 29, 2013 6:39 am |
|
|
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
|
|
Posted: Tue Jan 29, 2013 6:49 am |
|
|
and your clock frequency is ?? |
|
|
Requan
Joined: 11 May 2008 Posts: 74
|
|
Posted: Tue Jan 29, 2013 7:03 am |
|
|
sorry, 20Mhz |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Tue Jan 29, 2013 7:16 am |
|
|
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
|
|
Posted: Thu Jan 31, 2013 7:49 am |
|
|
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. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Jan 31, 2013 2:13 pm |
|
|
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
|
|
Posted: Fri Feb 01, 2013 8:55 am |
|
|
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: 9243 Location: Greensville,Ontario
|
|
Posted: Fri Feb 01, 2013 9:28 am |
|
|
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
|
|
Posted: Tue Feb 05, 2013 11:36 am |
|
|
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: 19539
|
|
Posted: Tue Feb 05, 2013 12:03 pm |
|
|
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: 1354
|
|
Posted: Tue Feb 05, 2013 12:08 pm |
|
|
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
|
|
Posted: Tue Feb 05, 2013 3:55 pm |
|
|
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.
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. | 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
|
|
Posted: Tue Feb 05, 2013 4:49 pm |
|
|
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 ! !
|
|
|
|