Best way to use USART/HSERIN


Closed Thread
Results 1 to 18 of 18

Hybrid View

  1. #1

    Default Best way to use USART/HSERIN

    I'm working on a project where there will be one PIC as a master controller to adjust LED brightness & motor control. I want to link this master PIC to the motor/LED chips via USART in a chain (all by wire on a PCB - no other components involved) and send the mode/speed changes down using a hard-coded ID; each chip down the line will check the ID and if it matches it's own then it acts on it, else it just passes it down the line.

    My question is this - how best to set up HSERIN in a situation like this? Should I use something like this in a Main loop:

    Code:
    Main:
        HserIN [WAIT("OK"),ID]
        IF ID="3" THEN 
            gosub updateLEDs
        ELSE
            HserOUT [data]
        ENDIF
    
        goto Main
    Or would it be better to use Darrel's Instant Interrupts with the Rx interrupt?

    This will be my first time using HSERIN/HSEROUT apart from using it for LCD debugging.
    Last edited by RossWaddell; - 11th February 2013 at 22:00.

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,605


    Did you find this post helpful? Yes | No

    Default Re: Best way to use USART/HSERIN

    Hi,
    Why do you need to daisychain them like [Master Out] -> [Slave In - Slave Out] -> [Slave In - Slave Out] ?
    Why not just wire the output of the master to the inputs of the slaves? That way the delay between the master and all the slaves will be equal and there will be less overhead in each of the slaves.

    Also, your code seems to read the ID but then it doesn't read the actual data.
    I'd probably send equally sized packets each time, perhaps something like sync, ID, 8 bytes of data, checksum. The slave then waits for the sync, grabs x number of bytes into an array, evaluates the checksum and if OK checks the ID. If ID matches it acts on the data otherwise it does nothing.

    Using interrupts or not highly depends on what else your program needs to do. If it just needs to sit there and wait for serial data, act on that data and then go back to waiting then you should be fine without using interrupts. But if your program needs to do other things and receive the serial data in the background then you probably need to use interrupts - and DT-Ints is a great way to do it.

    /Henrik.

  3. #3


    Did you find this post helpful? Yes | No

    Default Re: Best way to use USART/HSERIN

    Thanks very much, Henrik. I didn't put the whole code in but what you suggest is what I was thinking.

    I didn't think I could hook up the Tx on the master controller to all the Rx pins on the other PICs, but that makes life a lot easier so I'll give it a go.

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: Best way to use USART/HSERIN

    I've been using the PIC16F88 chip which has the 7 sequential pins I need for the code seen in this post. The problem is those 7 pins (PORTB.1-7) include the Rx pin, and I can't seem to find another chip which has 7 sequential pins where the USART Rx pin is somewhere else.

    Should I use SERIN instead to communicate between PICs, or is there a PIC which has 7 sequential pin outputs (none of which are the USART Rx pin)?

  5. #5


    Did you find this post helpful? Yes | No

    Default Re: Best way to use USART/HSERIN

    Spending a little more time on the Microchip selector site, I think PIC16F687 might do the trick - 20 pin DIP, 18 I/O pins with Rx on RB5 and RC0-7 available.

  6. #6


    Did you find this post helpful? Yes | No

    Default Re: Best way to use USART/HSERIN

    Coming back to this thread after recovering from some encoder/code porting issues from last week, I'm still trying to figure out the best way to send/receive data from 1 Master chip to 3-4 slaves via USART. I've read over many threads here regarding HSEROUT/HSERIN and the permutations & combinations leave me confused.

    As of last night, I've got a PIC12F1840 sending the following on the Tx pin based on a rotary encoder turn (there's an IOC ISR to determine the direction of turn which sets RotEncDir):
    Code:
    DEFINE OSC 16                ' Set oscillator 16Mhz
    
    DEFINE HSER_TXSTA 20h        ; Set transmit status and control register
    DEFINE HSER_BAUD  2400       ; Set baud rate
    DEFINE HSER_RCSTA 90h
    DEFINE HSER_CLROERR 1        ; Clear overrun error upon
                                 ; execution of every HSERIN
                                 ; command
    
    .
    .
    .
    
    Main:
        TOGGLE LED_0
    
        If ValueDirty = 1 THEN
            ' Send RotEncDir to receiving chip
            '    Chip Id,Itm Id,     <modifier>, "~"
            HSEROUT ["2",   "3", SDEC RotEncDir, TxEndChar]  ' use 'SDEC' if RotEncDir can be -1 for CCW
                
            ValueDirty = 0               ' Clear the flag
    
            #IFDEF USE_LCD_FOR_DEBUG
                HSEROUT [LCD_INST, LCD_CLR]
                pause 5
                '    Chip Id,Itm Id,     <modifier>,  "~"
                HSEROUT ["2",   "3", SDEC RotEncDir, TxEndChar]  ' use 'SDEC' if RotEncDir can be -1 for CCW
            #ENDIF
        ENDIF
     
        pause 500
     
        GOTO Main
    The output on my LCD shows this for a CW turn:
    Code:
    231~
    and this for CCW (RotEncDir actually gets set to 0 but I change it to -1 as on the slave I want to just add this value:
    Code:
    23-1~
    The first number represents the slave chip which is the intended target of the serial data (I'll have 2-3 slaves in this project). The second number represents what to change on that chip with the rotary encoder info. The next part is either '1' for CW or '-1' for CCW (I could go back to using '0' for CCW if that makes the overall serial data easier to interpret on the slaves).
    • Should I have a sync character at the start of the serial data so that on the slave I can determine if new serial data is sent before processing the first message (or there's an error)?
    • Should I convert the HSEROUT line to multiple lines?

    For the slaves, I've decided I need to use a Rx interrupt as I have other code running in the Main loop.
    Code:
    DEFINE OSC 16                ' Set oscillator 16Mhz
    
    DEFINE HSER_TXSTA 20h        ; Set transmit status and control register
    DEFINE HSER_BAUD  2400       ; Set baud rate
    DEFINE HSER_RCSTA 90h
    DEFINE HSER_CLROERR 1        ; Clear overrun error upon
                                 ; execution of every HSERIN
                                 ; command
    .
    .
    .
    ' ***************************************************************
    ' ASM Interrupt Definitions
    ' ***************************************************************
    
    ASM
    INT_LIST  macro    ; IntSource,           Label,  Type, ResetFlag?
            INT_Handler     RX_INT,        _UsartRx,   PBP,  yes
        endm
        INT_CREATE     ; Creates the interrupt processor
    ENDASM
    
    ' Enable interrupt
    @ INT_ENABLE   RX_INT      ; USART Rx interrupt
    
    .
    .
    .
    • Do I need to make the RX_INT a low priority interrupt, or is that only important if there are other time-sensitive interrupts (I am using SPWM_INT.bas for one slave)?
    • As Henrik suggests above, should I make the serial data entirely consistent in terms of number of bytes to make the parsing here easier? If that's true, then I probably need to revert to using '0' for CCW rotary encoder changes.
    • The code below is from DT on another thread but I can't see how the whole serial data (e.g. "231~" for slave chip #2 to increment item #3 by 1) will be pieced together.
    • Does the ISR get 1 byte every time? i.e. the first time it goes into the above ISR, 'SerialData' will be "2" and then the next iteration will have "3"?
    • Should the ISR have the ResetFlag set or not? I've seen both.
    Code:
    '*********** 'ISR for RX_INT interrupt *************************************
    Getbytes:       
        HSERIN [Serialdata]                    ' Get the serial data
        IF Serialdata = SyncByte THEN          ' if it's a Sync byte,
            IF Sync THEN ERROR = 1            '  last command was corrupted
            Sync = 1                          '  indicate Sync was rcvd
            ForMe = 0                          '  ID has not been rcvd
        ELSE
            IF Sync THEN
                IF !ForME THEN                ' if we haven't rcvd the ID
                    IF Serialdata = ID THEN    '  and this byte matches the ID
                        ForMe = 1              '    indicate ID rcvd
                    ELSE
                        Sync = 0              ' Not my packet
                        ForMe = 0              '  reset receive state   
                    ENDIF                      '  and wait for next Sync
                ELSE
                    CmdBuf = serialdata        ' store the command
                    IF CmdRcvd THEN LATE = 1  '  last command not finished
                    CmdRcvd = 1                '  indicate a command was rcvd
                    Sync = 0                  '  reset receive state
                    ForMe = 0                 
                ENDIF
            ENDIF
        ENDIF
    @ INT_RETURN
    All slaves Rx pin will be connected to the master's Tx pin so each slave needs to determine if the serial data is for them or not (which the above code does).
    Last edited by RossWaddell; - 18th March 2013 at 19:01.

Similar Threads

  1. USART to PC
    By tonyfelloni in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 15th October 2008, 00:09
  2. Usart
    By lew247 in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 2nd June 2008, 23:41
  3. Sharing a USART
    By Ron Marcus in forum Serial
    Replies: 1
    Last Post: - 7th September 2005, 14:48
  4. 9 bit addressable USART
    By barkerben in forum General
    Replies: 9
    Last Post: - 4th January 2005, 22:57

Members who have read this thread : 3

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts