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
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
ThanksCode:' 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
Edit: I can't work out how ya'll attach and make a nice preview image...






Bookmarks