Serial Question + General Review


Closed Thread
Results 1 to 3 of 3

Hybrid View

  1. #1
    Join Date
    May 2008
    Posts
    46

    Red face Serial Question + General Review

    Hey guys.

    Once again I re-iterate my thanks for the assistance you've been able to supply with my projects (I have several going - they're just beginning to merge, which leads me to the following)

    I've built and tested various parts of this - except the serial stuff

    Name:  receivernew.png
Views: 943
Size:  18.0 KB

    Everything I've tested is working fine (or close enough) - again with the exception of the serial.

    I want to use the hwuart for the interrupt and buffer, this pic will never initiate communication only respond to otherwise initiated communication - the other pic has no available hwuart and I'd like to wire it to one pin if possible (ie: send a command, and wait for a command).

    What I have to ask is - will my serial work in that configuration (tx + rx -> single pin)?

    The second favor I ask is that you look over everything (including the code if it's not to much trouble) and tell me what (if anything) you'd do different - I know that some of you would rather not use gosub's in an interrupt but there'd be so much duplicated code without it.

    I only ask this second favor, because I'd rather not be back into it every other day trying to debug something once I put it together

    Code:
    ' Configure the FUSE options for the compiler
    @     device pic16F628A, hs_osc, wdt_off, pwrt_on, lvp_off, protect_off, bod_on, cpd_off, pwrt_off, mclr_off
    
    ' Running a 20Mhz clock
    DEFINE OSC 20
    DEFINE PULSIN_MAX 3000
    
    CMCON        = 7
    VRCON        = 0
    
    ALL_DIGITAL
    
    ' Setup the USART
    DEFINE HSER_RCSTA 90h      ' Receive register to receiver enabled
    DEFINE HSER_TXSTA 20h      ' Transmit register to transmitter enabled
    DEFINE HSER_BAUD 19200     ' Set baud rate
    
    ' Alias our pins           
    BEEP           VAR PORTA.0 ' Buzzer
    RFIN           VAR PORTA.1 ' Remote input
    PROXIMITY_UP   VAR PORTA.3 ' Proximity sensor for UP travel
    PROXIMITY_DOWN VAR PORTA.4 ' Proximity sensor for DOWN travel
    RELAY1         VAR PORTB.4 ' Relay 1 output
    RELAY2         VAR PORTB.5 ' Relay 2 output
    BUTTONA        VAR PORTB.6 ' Primary panel button input
    BUTTONB        VAR PORTB.7 ' Secondary panel button input
    
    ' Define some aliases for USART
    OERR           VAR RCSTA.1 ' Over-run bit
    CREN           VAR RCSTA.4 ' Continuous receive enable bit
    RCIF           VAR PIR1.5  ' Received character interrupt flag bit
    
    ' Set the pin directions
    INPUT RFIN
    INPUT BUTTONA
    INPUT BUTTONB
    
    OUTPUT BEEP
    OUTPUT RELAY1
    OUTPUT RELAY2
    OUTPUT PROXIMITY_DOWN
    OUTPUT PROXIMITY_UP
    
    ' Configure the output pins as low
    LOW BEEP
    LOW RELAY1
    LOW RELAY2
    LOW PROXIMITY_UP
    LOW PROXIMITY_DOWN
    
    ' Turn on weak pull-ups - IMPORTANT: After making relays and beepers low...
    OPTION_REG.7 = 0
    ' We want to interrupt on the falling edge  
    OPTION_REG.6 = 0
    
    ' Set us up some variables
    PBITS        VAR BYTE[24]  ' The bits we've read
    RAW          VAR WORD      ' The raw pulsin value
    ADDRESS      VAR WORD      ' Storage for the address
    DBYTE        VAR BYTE      ' Storage for the data
    LOOPADDRESS  VAR WORD      ' Second loop storage of first loop addres
    LOOPDBYTE    VAR BYTE      ' Second loop storage of first loop data byte
    X            VAR BYTE      ' Loop/TMP var
    Y            VAR BYTE      ' Loop/TMP var
    STATE        VAR BYTE      ' Current state of the device
    
    ' Constants
    STATE_GOING_UP   CON 1     ' Screen is going up
    STATE_GOING_DOWN CON 2     ' Screen is going down
    STATE_STOPPED    CON 8     ' Screen is stopped
    STATE_UP         CON 9     ' Stopped + UP
    STATE_DOWN       CON 10    ' Stopped + Down
    BEEP_WAIT        CON 100   ' Wait 100 MS for the beep
    POST_BEEP_WAIT   CON 100   ' Wait 100 MS after the beep to reverse direction
    
    ' Default state
    STATE = STATE_STOPPED
    
    ON INTERRUPT GOTO sighup
    INTCON = %11010000
    PIE1   = %00100000
    
    ' Reset all the primary RF variables
    TOP:
        ADDRESS = 0 : RAW = 0 : DBYTE = 0
        
    ' This is the real main - almost all the looping comes back here
    MAIN:
        ' Set both buttons for input
        INPUT BUTTONA
        INPUT BUTTONB
        ' Check to see if the individual buttons are toggled
        IF NOT BUTTONA THEN GOSUB subDown
        IF NOT BUTTONB Then GOSUB subUp
        ' Fiddle with the inputs to see if the middle button is pushed
        LOW BUTTONB
        X = BUTTONA ' If it's LOW then there's a good chance the middle button is down
        HIGH BUTTONB
        INPUT BUTTONB
        LOW BUTTONA  
        Y = BUTTONB ' If it's LOW then there's a good chance the middle button is down
        HIGH BUTTONA
        INPUT BUTTONB
        INPUT BUTTONA
        IF NOT Y AND NOT X THEN GOSUB subStop ' Both register as LOW then the middle button is down!
        
        ' Look for one huge low pulse
        PULSIN RFIN, 0, RAW
        ' 2350 is about mean average
        IF RAW < 2340 OR RAW > 2360 THEN MAIN
    
        ' Read 16 address bits and 8 data bits    
        FOR X = 0 TO 23
            PULSIN RFIN, 0, RAW
            ' Check the pulse parameters
            if RAW < 30 OR RAW > 240 THEN MAIN
            PBITS[x] = NCD RAW
        NEXT X
        
        ' Gather the address
        ADDRESS = 65535 ' Maxmimum known ID
        FOR X = 0 to 15
            IF PBITS[x] > 7 THEN ADDRESS.0[X] = 0
        NEXT X
        
        ' Gather the data
        DBYTE = 255 ' Maximum known data value
        Y=0
        FOR X = 16 TO 23
            IF PBITS[X] > 7 THEN DBYTE.0[Y] = 0
            Y = Y + 1
        NEXT X
    
        ' If we've done a loop...
        IF ADDRESS == LOOPADDRESS AND DBYTE == LOOPDBYTE THEN
            SELECT CASE DBYTE
                CASE 3
                    GOSUB subUp
                CASE 12
                    GOSUB subStop
                CASE 192
                    GOSUB subDown
            END SELECT
            LOOPDBYTE = 0
            LOOPADDRESS = 0
        ELSE
            ' Start a loop
            LOOPDBYTE = DBYTE
            LOOPADDRESS = ADDRESS
        ENDIF
    
        GOTO TOP
    END
    
    DISABLE
    
    subUp:
        IF STATE != STATE_GOING_UP THEN
            INTCON = 0            ' Turn off interrupts
            HIGH BEEP             ' Start making noise
            LOW RELAY1            ' Make sure the down relay is off (Don't know what happens otherwise, don't want to know!)
            LOW PROXIMITY_DOWN    ' Turn off the down proximity sensor
            PAUSE BEEP_WAIT       ' Wait a bit
            LOW BEEP              ' STFU :)
            IF STATE.3 != 1 THEN PAUSE POST_BEEP_WAIT
            HIGH RELAY2           ' Turn the up relay on
            HIGH PROXIMITY_UP     ' Turn on the up proximity sensor
            STATE = STATE_GOING_UP
            INTCON = %11010000    ' Turn the interrupts on
        ENDIF
        RETURN
        
    subStop:
        IF STATE.3 != 1 THEN
            INTCON = 0            ' Turn off interrupts
            HIGH BEEP             ' Start making noise
            LOW RELAY1            ' Turn off the down relay
            LOW PROXIMITY_DOWN    ' Turn off the down proximity sensor
            LOW RELAY2            ' Turn off the up relay
            LOW PROXIMITY_UP      ' Turn off the up proximity sensor
            PAUSE BEEP_WAIT       ' Wait a bit
            LOW BEEP              ' STFU :)
            STATE = STATE_STOPPED
            INTCON = %11010000    ' Turn the interrupts on
        ENDIF
        RETURN
    
    subDown:
        IF STATE != STATE_GOING_DOWN THEN
            INTCON = 0            ' Turn off interrupts
            HIGH BEEP             ' Start making noise
            LOW RELAY2            ' Make sure the up relay is off (Don't know what happens otherwise, don't want to know!)
            LOW PROXIMITY_UP      ' Turn off the up proximity sensor
            PAUSE BEEP_WAIT       ' Wait a bit
            LOW BEEP              ' STFU :)
            IF STATE.3 != 1 THEN PAUSE POST_BEEP_WAIT
            HIGH RELAY1           ' Turn the down relay on
            HIGH PROXIMITY_DOWN     ' Turn on the down proximity sensor
            STATE = STATE_GOING_DOWN
            INTCON = %11010000    ' Turn the interrupts on
        ENDIF
        RETURN
    
    sighup:
        X = STATE
        IF INTCON.1 == 1 THEN
            GOSUB subStop
            IF STATE == STATE_GOING_DOWN THEN STATE = STATE_DOWN
            IF STATE == STATE_GOING_UP THEN STATE = STATE_UP
            INTCON.1 = 0
        ENDIF
        WHILE RCIF
            ' Don't use 1-10 this makes it easier to eliminate "echo" noise from tx
            SELECT CASE RCREG
                CASE 127
                    GOSUB subUp
                CASE 128
                    GOSUB subDown
                CASE 129
                    GOSUB subStop
                CASE 130
                    HSEROUT [STATE]
            END SELECT
        WEND
        IF OERR = 1 THEN
            CREN = 0
            CREN = 1
        ENDIF
        RESUME
        
    ENABLE
    Thanks

    Edit: I can't work out how ya'll attach and make a nice preview image...
    Last edited by Freman; - 20th June 2008 at 18:59. Reason: Fixed img I hope.

  2. #2
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Freman View Post
    What I have to ask is - will my serial work in that configuration (tx + rx -> single pin)?
    It can work just fine using serial communications over a single pin.......provided you use the software serial commmands (i.e. SERIN/SERIN2/SEROUT/SEROUT2/DEBUGIN/DEBUG, etc.) and not the hardware or it's commands (i.e. HSERIN/HSERIN2/HSEROUT/HSEROUT2). PBP should/will automatically set the pin to input and/or output as required...should that is.

  3. #3
    Join Date
    May 2008
    Posts
    46


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by skimask View Post
    It can work just fine using serial communications over a single pin.......provided you use the software serial commmands (i.e. SERIN/SERIN2/SEROUT/SEROUT2/DEBUGIN/DEBUG, etc.) and not the hardware or it's commands (i.e. HSERIN/HSERIN2/HSEROUT/HSEROUT2). PBP should/will automatically set the pin to input and/or output as required...should that is.
    I'd rather not use the software equiv in this case as it's quite a busy little chip and I'd really like to have the interrupt and buffering. I know I can use interrupts on portb, but portb is quite busy - especially with constantly turning the WPU on and off

Similar Threads

  1. Wireless serial communication question
    By Ahmadabuomar in forum Serial
    Replies: 3
    Last Post: - 21st December 2009, 03:49
  2. serial LCD/SLCD question
    By MatthewM in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 18th May 2009, 14:56
  3. Replies: 8
    Last Post: - 22nd July 2008, 20:31
  4. AN Question for "word" variable read The serial port
    By redfoen in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 14th December 2007, 17:39
  5. newbie with serial com question...
    By kevlar129bp in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 16th December 2006, 05:34

Members who have read this thread : 0

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