PDA

View Full Version : Avoid HSEROUT command?



pxidr84
- 25th November 2015, 17:21
Hi,

I'm using a PIC18F2331 running at 40MHz and my program is quite heavy, the µC got a lot of work to do with a lot of interrupts.

I usually use the HSEROUT command for sending 8 variables to my PC via UART, like this :


hserout[a,b,c,d,e,f,i,j]
(values from a to j are bytes)

But I noticied that this command is very time-consuming in my program, and it disturbs some of my high-frequency interrupts.

So I'm considering to NOT use that HSEROUT command, but manually fill the TXREG buffer :


If PIR1.4 = 1 Then
TXREG = a ' Send character to transmit register
endif

But how I can send all my byte-sized variables (a,b,c,d,e,f,i,j) at the same time with this method?

Thanks

HenrikOlsson
- 25th November 2015, 20:46
Hi,
As long as the HSEROUT statement itself isn't IN an interrupt routine I don't see HOW it can disturb any interrups (as long as you're not using ON INTERRUPT of course but I suspect you're NOT).

But to answer your question, if you can put all your variables after each other, ie in an array, then a simple FOR-LOOP will do but really, I don't see it being any better than HSEROUT but man have I been wrong before :-)

/Henrik.

pxidr84
- 25th November 2015, 21:41
Hi,
As long as the HSEROUT statement itself isn't IN an interrupt routine I don't see HOW it can disturb any interrups (as long as you're not using ON INTERRUPT of course but I suspect you're NOT).

But to answer your question, if you can put all your variables after each other, ie in an array, then a simple FOR-LOOP will do but really, I don't see it being any better than HSEROUT but man have I been wrong before :-)

/Henrik.

Hi Henrik,

I use the DT instant interrupts, i've one main loop, one high-speed high priority interrupt (running at 13kHz and doing some calculations) and one low-priority interrupt (running at 100Hz).

The HSEROUT command is in the main loop.

But still, when it sends data at a high rate, the low-priority interrupt is disturbed. I'm running at 2400bps.

Art
- 26th November 2015, 02:07
You’re not taking advantage of hardware serial at all unless you send a byte at a time.
Otherwise it’s blocking just like software serial. A for next loop sending hardware serial will also block just the same.



atoj var byte[8]
index var byte
serbuff var byte
to send continuously:

mainloop:

‘ your program

if index > 7 then
index = 0’
endif

if index < 8 then
serbuff = atoj[index]
hserout[serbuff]
index = index + 1
endif

goto mainloop



Don’t write into the buffer while index is less than 8.

richard
- 26th November 2015, 02:38
I'm with henrik on this

As long as the HSEROUT statement itself isn't IN an interrupt routine I don't see HOW it can disturb any interrupts
if you were to use an interrupt routine to output for your 8 bytes of data then that would impact on your other interrupts , pbp style irqs done with dt_ints have some pretty heavy overheads

when art says

You’re not taking advantage of hardware serial at all unless you send a byte at a time
that's not strictly correct , hserout is interruptible using dt_ints

Art
- 26th November 2015, 03:21
Don’t know why it would interfere with an interrupt, but I mean this


led off
hserout[a,b,c,d,e,f,i,j]
led on

is no better than doing the same thing with software serial.
The led won’t turn on until all eight bytes are sent.


led off
hserout[byte]
led no

Where as the above doesn’t even have to wait for the single byte to send serially.

If you were going to interrupt this:


sendingserial = 1
hserout[a,b,c,d,e,f,i,j]
sendingserial = 0

You’d have to be sure your interrupt doesn’t change any vars a-j while sendingserial = 1 or you’d end up
with a composite of what was supposed to be two commands (i.e. you don’t know where it’s up to).

pxidr84
- 26th November 2015, 09:33
Don’t know why it would interfere with an interrupt, but I mean this


led off
hserout[a,b,c,d,e,f,i,j]
led on

is no better than doing the same thing with software serial.
The led won’t turn on until all eight bytes are sent.


led off
hserout[byte]
led no

Where as the above doesn’t even have to wait for the single byte to send serially.

If you were going to interrupt this:


sendingserial = 1
hserout[a,b,c,d,e,f,i,j]
sendingserial = 0

You’d have to be sure your interrupt doesn’t change any vars a-j while sendingserial = 1 or you’d end up
with a composite of what was supposed to be two commands (i.e. you don’t know where it’s up to).

You say that I should use a low priority interrupt for sending all my bytes?

Art
- 27th November 2015, 05:53
I don’t know if you are sending serial in the interrupt or main program, and assumed it’s in the main program.
Having said that, I can’t think of a reason you need to do serial in the interrupt, but there might be a reason.
I’m saying sending a slab like that will ruin the illusion of doing things simultaneously like programs do,
and that there’s no recovering from it.

Think if you did this:


hserout[a,b,c,d,e,f,i,j]

Then later you wanted the same program to also receive a serial command that could arrive at any time. You’re screwed.
For example if a GPS sent it’s data sentence to your chip while in the middle of your program sending that eight byte slab.

But you can easily have a fully duplex serial port with PBP HSEROUT.
You can be sending the eight byte slab at the same time as receiving something,
and once implemented you barely have to think about it.



atoj var byte[8]
rxbuffer[8]
index var byte
rxindex var byte
serbuff var byte
rxbuff var byte

mainloop:

‘ your program

if index > 7 then ‘ data packet was sent, so send another.
index = 0’
endif

if rxbuff = enterkey then ‘ check for end of incoming command
rxindex = 0
‘do something with received command
endif


if index < 8 then
serbuff = atoj[index]
hserout[serbuff]
index = index + 1
endif

if rxindex < 8 then
hserin[rxbuff,shortesttimeout,donelabel]
donelabel:
rxbuffer[rxindex] = rxbuff
rxindex = rxindex + 1
endif

goto mainloop

pxidr84
- 27th November 2015, 08:36
I don’t know if you are sending serial in the interrupt or main program, and assumed it’s in the main program.
Having said that, I can’t think of a reason you need to do serial in the interrupt, but there might be a reason.
I’m saying sending a slab like that will ruin the illusion of doing things simultaneously like programs do,
and that there’s no recovering from it.

Think if you did this:


hserout[a,b,c,d,e,f,i,j]

Then later you wanted the same program to also receive a serial command that could arrive at any time. You’re screwed.
For example if a GPS sent it’s data sentence to your chip while in the middle of your program sending that eight byte slab.

But you can easily have a fully duplex serial port with PBP HSEROUT.
You can be sending the eight byte slab at the same time as receiving something,
and once implemented you barely have to think about it.



atoj var byte[8]
rxbuffer[8]
index var byte
rxindex var byte
serbuff var byte
rxbuff var byte

mainloop:

‘ your program

if index > 7 then ‘ data packet was sent, so send another.
index = 0’
endif

if rxbuff = enterkey then ‘ check for end of incoming command
rxindex = 0
‘do something with received command
endif


if index < 8 then
serbuff = atoj[index]
hserout[serbuff]
index = index + 1
endif

if rxindex < 8 then
hserin[rxbuff,shortesttimeout,donelabel]
donelabel:
rxbuffer[rxindex] = rxbuff
rxindex = rxindex + 1
endif

goto mainloop


Thanks Art, it works quite well ;)
I've no more latency done by the HSEROUT command.

Thanks!