as i heard, the value that triggers interrupt is in buffer. should i use it? does it have any disadvantage?

thank you so much!

temtronic

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

Posted: Fri Jan 19, 2018 6:00 am

It should work fine, with two small changes
1) you can delete the
disable_interrupts(INT_RDA);
line of code as the CCS compiler already does that !
2) you need to actually read the UART data. this will clear the buffer.
3) also add 'errors' to the use rs232(...options...)

There may be a problem though. EVERY character coming into the PIC will trigger the ISR,so your variable will be reset EVERY time. It would be better to have a specific character(say 'P') to trigger the variable reset. That way you have control of the process.

Jay

Ttelmah

Joined: 11 Mar 2010Posts: 14081

Posted: Fri Jan 19, 2018 9:16 am

The point about reading the byte, is that the interrupt cannot be cleared until it has been read. So you _must_ read the byte, otherwise if you ever re-enable INT_RDA, the chip will immediately interrupt...

Code:

byte surekli=1;
#int_RDA
void RDA_isr()
{
int8 dummy;
dummy=getc(); //now allows the interrupt to be cleared
//Do you really want to disable the interrupt?.
//Why?.
//Chip won't respond to another character if it is disabled.
disable_interrupts(INT_RDA);
surekli = 0;
} //The compiler will automatically clear the interrupt, but can't do so
//unless the character has been read.

doguhanpala

Joined: 05 Oct 2016Posts: 97

Posted: Fri Jan 19, 2018 10:39 am

Hello everyone,

Thank you for your answers.

temtronic

1) you can delete the
disable_interrupts(INT_RDA);
line of code as the CCS compiler already does that ! (thank you, read this from an old book about ccs, updated it the way you said it)

2) you need to actually read the UART data. this will clear the buffer.

I added a variable for this.

3) also add 'errors' to the use rs232(...options...) i dont know what this does but i saw it on this forum so i am using it

"There may be a problem though. EVERY character coming into the PIC will trigger the ISR,so your variable will be reset EVERY time. It would be better to have a specific character(say 'P') to trigger the variable reset. That way you have control of the process. "

I did not do that because i have read that using "if else" or loops in an interrupt routine is not good. as you suggested that i am assuming it is not that bad?

Ttelmah

Quote:

//Do you really want to disable the interrupt?. //Why?.

I use the code for a stepper motor driver module. Slave pic is 16f628 and master is 18f2550. The problem is i have to use 1 pin to communicate those 2 pics.

I want to be able to send a specific step number and also do a infinite go. But when the motor moves the infinite go function, i cannot stop it. I tried to use the interrupt to be able to stop the motors.

Why i want to disable? I dont want code to go isr on every comm attempt. Sorry for my english.

I'm not saying you need the disable_interrupts(INT_RDA) line.
Normally you don't need it. But I am saying that the compiler
doesn't automatically put that line in.

temtronic

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

Posted: Fri Jan 19, 2018 4:53 pm

hmm.. I was always under the impression the compiler did the 'housework'...to keep ISR 'neat and tidy'....
sigh, too many PICs, too little time

Ttelmah

Joined: 11 Mar 2010Posts: 14081

Posted: Sat Jan 20, 2018 1:59 am

Yes, it does do the housework.

However 'since when' would disabling a receive data interrupt be part of this?. You want to receive data....

The hardware disables the global interrupt, when you enter the ISR, and re-enables it when you leave. The compiler clears the receive interrupt (if it can - the caveat about not reading the data). Only thing left is to read the data.

To doguhanpala

The point about 'ERRORS', is that the PIC USART has the 'feature', that if it overflows, it goes to a 'stalled' state, with 'overrun error' flagged. This stops further reception till cleared. 'ERRORS' adds the housekeeping, to automatically clear this if it happens.

doguhanpala

Joined: 05 Oct 2016Posts: 97

Posted: Sat Jan 20, 2018 5:02 am

Thank you all for your answers. I have another question.

This is the transmit code from 18f2550. It sends an 16 bit integer in 2 parts. After sending the bytes, the pin waits for high to understand if the process completed.

This is the receive code. I am not adding all functions they are very similiar. The code waits for step number high and low. It makes them 16 bit. After that i use that integer on for loops. When the loop is done, the code calls "bitir()" in order to inform 18f2550.

I don't see the char 'd'. Is there a way to make hardware uart pins act like IOs even if they are used as uart?

Ttelmah

Joined: 11 Mar 2010Posts: 14081

Posted: Sat Jan 20, 2018 11:46 am

TTL serial, idles high. The line is permanently going to be high when the UART (soft or hard), is sitting not sending. You can't use this as an identifier.
Pulling the line low for 2mSec, sends two characters of 0.

Your approach is fundamentally flawed.

Simply send a character that is identified as a 'header' Something like a line feed or a '$' sign.

Follow this with your byte for 'what you want to do'. Now you seen to be relying on this being 1, 2, 3 etc.. You do understand the difference between a value of 1, and the character '1'. Which are you sending?.

Then send the value as hex, rather than as direct binary. Problem with direct binary is it makes it hard to identify other values.

doguhanpala

Joined: 05 Oct 2016Posts: 97

Posted: Sun Jan 21, 2018 6:20 am

Ttelmah wrote:

TTL serial, idles high. The line is permanently going to be high when the UART (soft or hard), is sitting not sending. You can't use this as an identifier.
Pulling the line low for 2mSec, sends two characters of 0.

Your approach is fundamentally flawed.

Interestingly, the code works when i use software uart. When the motors do their job 16f sends low, and 18f gets it. after that i see the 'd' on screen. When i use hardware uart. It gets stuck on while loop.

Ttelmah wrote:

Simply send a character that is identified as a 'header' Something like a line feed or a '$' sign.

My problem is, i cannot understand the process on 16f is complete or not. I want to block the comm, if the process is not complete and motors are still moving. So i need to do something after the process.

Ttelmah wrote:

Follow this with your byte for 'what you want to do'. Now you seen to be relying on this being 1, 2, 3 etc.. You do understand the difference between a value of 1, and the character '1'. Which are you sending?.

Then send the value as hex, rather than as direct binary. Problem with direct binary is it makes it hard to identify other values.

I know the difference between value 1 and char '1'(this is 50 as i recall?). I chose to send value but not for a specific reason. I said, well send value man. Actually which one i send is not important to me, i can edit the code both sides(rcv and xmit) and send char. unfortunately it still does not solve my problem.

My guess, when i use software uart and call the function input state, the port starts to behave like io port? Sounds idiotic but my only guess

Thank you for your aswer and explanation.

Ttelmah

Joined: 11 Mar 2010Posts: 14081

Posted: Sun Jan 21, 2018 9:41 am

The problem is that because you rely on detecting values like 1, 2, 3. These can happen inside the data you are sending, since by sending 'raw' values any value is possible. The hardware UART will still be receiving the low as a character. Just because you have the interrupt disabled, does _not_ stop the UART from receiving. So it will have received a zero at this point, and will in fact have set it's error flags, since it will see a malformed character, and this has not been read, resulting in both a framing error and an overrun. The soft UART will not, since you are not actually calling it till after the line goes high again, and it does not have error checking.

If you just want to ignore data till a task is complete, then just set a flag.
Have your INT_RDA, simply throw any character received if the 'busy' flag is set. Once this goes off, start listening to the data again.

If you must use your current approach, then disable the UART (setup_uart(FALSE);), rather than disabling the interrupt.

doguhanpala

Joined: 05 Oct 2016Posts: 97

Posted: Mon Jan 22, 2018 7:36 am

Ttelmah wrote:

The problem is that because you rely on detecting values like 1, 2, 3. These can happen inside the data you are sending, since by sending 'raw' values any value is possible. The hardware UART will still be receiving the low as a character. Just because you have the interrupt disabled, does _not_ stop the UART from receiving. So it will have received a zero at this point, and will in fact have set it's error flags, since it will see a malformed character, and this has not been read, resulting in both a framing error and an overrun. The soft UART will not, since you are not actually calling it till after the line goes high again, and it does not have error checking.

Thank you for suggestions Ttelmah. I edited the code to this. Used char instead of vaue itself.

this time the code works correctly '1' time. i send the values,see the 'abc' on screen. motors go, the transmit code waits for low and prints the 'd'. if i press 'a' again, i see the abcd on screen. the setup_uart(FALSE) does not work on second time.

Quote:

If you just want to ignore data till a task is complete, then just set a flag.
Have your INT_RDA, simply throw any character received if the 'busy' flag is set. Once this goes off, start listening to the data again.

I can block the receiver side from getting any data. The real problem is i want to block the transmit side from sending any data till the task is complete. so i tried the setup_uart approach.

Ttelmah

Joined: 11 Mar 2010Posts: 14081

Posted: Mon Jan 22, 2018 8:02 am

Code:

delay_ms(1);
setup_uart(FALSE)

What is going to happen if a character has already arrived in this mSec?.
You stop the UART which can already holding a character.

Then at the transmit, 'putc' for a hardware UART, returns as soon as a character is loader _to_ transmit. It hasn't actually been sent yet.

So, when sending, you need to wait for the transmit buffer to empty. On the receive switch off the UART as soon as you have read the characters you want.

doguhanpala

Joined: 05 Oct 2016Posts: 97

Posted: Thu Jan 25, 2018 5:57 am

Ttelmah wrote:

Code:

delay_ms(1);
setup_uart(FALSE)

What is going to happen if a character has already arrived in this mSec?.
You stop the UART which can already holding a character.

Then at the transmit, 'putc' for a hardware UART, returns as soon as a character is loader _to_ transmit. It hasn't actually been sent yet.

So, when sending, you need to wait for the transmit buffer to empty. On the receive switch off the UART as soon as you have read the characters you want.