Will 'hserout' affect a program

Discussion in 'Embedded Systems and Microcontrollers' started by camerart, Jun 6, 2016.

  1. camerart

    Thread Starter Active Member

    Feb 25, 2013
    517
    30
    Hi,
    Can someone tell me, if I add HSEROUTs into a time critical program, will it affect the program please?
    Camerart
     
  2. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,905
    376
    Adding a program line will affect the timing of the program - a bit. How time critical is 'time critical'?

    PS is this PICBASIC?
     
  3. camerart

    Thread Starter Active Member

    Feb 25, 2013
    517
    30
    Hi Albert,
    Yes this is PIC (Oshonsoft) basic.
    I was checking a problem using 4x HSEROUT, which helped me find what it was. I guessed that the HSEROUT was affecting the working. I have taken them out now, and it is working ok,and you have verified my thoughts. As this is a fine problem, I like a second opinion, thanks.
    C.
     
  4. jjw

    Member

    Dec 24, 2013
    173
    31
    Hserout can add a lot of delay in your program depending of the Baud rate and number of characters sent.
    For example at 9600 bd time/character is about 1ms.
     
  5. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,905
    376
    Ah, but HSEROUT uses the hardware UART so the program is not delayed while the serial is sent. What you say would be true if SEROUT was used as that's a software modem.
     
  6. JohnInTX

    Moderator

    Jun 26, 2012
    2,341
    1,024
    One thing to note is that in Hseropen there is no reference to any buffering (FIFO, circular queue - whatever you want to call it). This would imply that even though the hardware UART is used it is not buffered. This would mean that sending a string would entail writing a character to TXBUF then polling TRMT to see when the character has been sent then after it has, writing the next one and so on. So even though the hardware UART is used, the code will still have to wait about (10*1/BaudRate) * NumberOfCharsInString-1 seconds when sending a string. So while using the hardware UART helps the runtime code (software UARTs are a timing pain), the program itself doesn't run much faster since it has to wait for strings to be sent.

    The hot setup is to use a FIFO (first in first out) buffer and and interrupt driven UART handler. The main code flow dumps characters into the buffer (fast) then resumes processing. The UART code loads the first character into TXBUF then enables TXIE. Whenever the UART has completed one character's transmission, the PIC gets interrupted and the service routine grabs the next character from the buffer and drops it onto TXBUF then returns. When the buffer is empty, TXIE is disabled and the UART handler waits for more characters.

    Now the system does not have to wait while the characters are actually being transmitted - the only overhead is what it takes to process the interrupt. I have simplified the description a bit but hopefully you get the idea.

    Without actually seeing the compiled assembler output, I can't know what PICBASIC does but from your description of the delays involved and the lack on any buffer size spec in PICBASIC's UART routines makes me suspect that they are not buffering the UART and you get the delays - at 9600 baud about 1ms per character.

    FWIW the formula above is derived from
    10 bits per character - Start - 8 bit data - Stop. The -1 is because the UART is double buffered i.e. it can hold one character while the previous one is being shifted out.

    You can test/get around some of this by sending one byte messages as part of your debug. Instead of 'Value is negative' send '-'. Instead of Value is positive, send '+'. Takes advantage of the one character hardware buffering.

    Fun, ain't it!
     
    Last edited: Jun 7, 2016
  7. jjw

    Member

    Dec 24, 2013
    173
    31
    It is true if only one character is sent, but what can the program do if several characters are sent? Wait between characters?
    I have not yet looked the asm code that Oshonsoft basic generates, but I guess it puts a character to the tx register, waits until it is sent, puts the next character... and so on.
     
  8. jjw

    Member

    Dec 24, 2013
    173
    31
    I tested a Basic program:
    Code (Text):
    1.    
    2. Hserinit 9600
    3. Hserout "Hello!"
    4. End
    5. -----------------
    6. The assembler output ( for clarity I removed the RX routines and added  comments  <-----):
    7. ; user code start
    8. l0001:
    9. ; 1: Hseropen 9600
    10. ; exact baud rate achieved = 9615.385; Bit period = 104µs; baud rate error =.16%
    11.    bsf STATUS, RP0
    12.    movlw 0x81
    13.    movwf SPBRG
    14.    bsf TRISB, 1
    15.    bsf TRISB, 2
    16.    movlw 0x24
    17.    movwf TXSTA
    18.    bcf STATUS, RP0
    19.    movlw 0x90
    20.    movwf RCSTA
    21. ; 2: Hserout "Hello!"
    22.    movlw 0x48
    23.    Call hs01
    24.    movlw 0x65
    25.    Call hs01
    26.    movlw 0x6c
    27.    Call hs01
    28.    movlw 0x6c
    29.    Call hs01
    30.    movlw 0x6f
    31.    Call hs01
    32.    movlw 0x21
    33.    Call hs01
    34. ; 3: End
    35. l0002: Goto l0002
    36. ; End of user code
    37. l0003: Goto l0003
    38. ; hardware serial communication routines
    39. hs01:
    40.    btfsc PIR1, TXIF            <----  test if UART ready to transmit
    41.    Goto hs02
    42.    Goto hs01                   <----- loop until ready
    43. hs02: movwf TXREG
    44.    Return
    45.  
    So at 9600 baud it takes ~ 1ms / character to be sent.
     
  9. JohnInTX

    Moderator

    Jun 26, 2012
    2,341
    1,024
    Yup. At lines 40-42 you can see it loop while waiting on TXIF to be set indicating that it is waiting on each character. That's why it is slow.
    Lines 22-23 load the character 'H' into the W register then call 'hs01'. That subroutine waits until the transmit register is empty then writes the new char and returns. After the first char, subsequent calls with the next chars have to wait until the previous char has been shifted out.

    Thanks for the .asm.
     
    Last edited: Jun 8, 2016
  10. camerart

    Thread Starter Active Member

    Feb 25, 2013
    517
    30
    Hi all,
    Thanks for your detailed offerings, which prove to be true when run in the circuit. This indicates to me that one has to be careful to keep time critical programs to the minimum, in case they get pushed into into errors.
    Can I also assume that LCDOUT has similar affects?
    C.
     
  11. JohnInTX

    Moderator

    Jun 26, 2012
    2,341
    1,024
    Probably. During init, the LCD will require some long delays. That's not too big a problem but there are delays in operation too. It takes several msec (per the 44780 datasheet) to clear the display or return home (Optrex says its 15.2msec!). Each character takes ~40usec to enter. The code must take these delays into account. Sometimes, the compiler will generate a dumb delay after writing but usually, the busy flag is polled before each operation. But in either case, its common to wait for the operation to complete, burning up CPU time - much like that UART code. I've written interrupt driven buffered LCD routines but I haven't seen a compiler's library that does it. All the compilers I know about wait on the LCD as I described.

    Since clearing the display takes so much time, I usually prefer to just write the new message with appropriate blanks to overwrite the old data rather than using the Clear Display command.

    On a sort of related note, in your circuit be sure to pull the LCD E line down so that you don't send it garbage while the PIC is starting up. Also, if the code polls the busy line, be sure to use a pulldown to pull it low to a NOT BUSY condition. That way, if the LCD fails or is not present, the code won't hang forever waiting on a NOT BUSY that may never happen.

    Have fun.
     
  12. camerart

    Thread Starter Active Member

    Feb 25, 2013
    517
    30
    Hi J,
    I don't need an LCD in this particular program, I was only wondering if an LCD could be used for trouble shooting, and from what you say it can't. Thanks.
    C.
     
  13. AlbertHall

    Well-Known Member

    Jun 4, 2014
    1,905
    376
    Even if you just add a line to toggle an output pin for an LED it will affect the program timing. It all depends on how time critical it is what you can get away with.
     
  14. camerart

    Thread Starter Active Member

    Feb 25, 2013
    517
    30
    Hi A,
    For the occasions where a LED toggle works, I use them, but for this particular test, I wanted to read a quadrature output, to let me know which direction a motor is running. I've done this now.
    Thanks, E.
     
  15. John P

    AAC Fanatic!

    Oct 14, 2008
    1,632
    224
    Or you can poll the TXIF flag without having the interrupt enabled. If it's found to be set and there is data to send, you can load the next character into TXREG. That's all you need to do.

    Yes.
     
  16. camerart

    Thread Starter Active Member

    Feb 25, 2013
    517
    30
    Hi J,
    I would love to be as fluent in programming to do this sort of thing, but sadly I'm not:(
    C.
     
Loading...