Code:
' code by Melanie converted to be used with 16f676 by grounded
' added 4mhz external clock for this project to correct problems
' using microCode Studio and it's serial communicator
' -------------------------------------------------------------
'
' CPU Hardware Layout
' -------------------
' pin changed to use with 16f676
' PortA.0 - RX cable via 1K5 Resistor to PC pin 3 on 9-Pin D Connector
' PortA.1 - TX cable via 1K5 Resistor to PC pin 2 on 9-Pin D Connector
'
' PortC.0 - LED1 to VDD via Resistor
' PortC.1 - LED2 to VDD via Resistor
' PortC.2 - LED3 to VDD via Resistor
' PortC.3 - LED4 to VDD via Resistor
' PortC.4 - LED5 to VDD via Resistor
' Don't forget to connect Vss to PC pin 5 on 9-pin D Connector
pic16f676
' FUSES SET IN INC FILE
' _XL_OSC, WDT_ON, MCLR_OFF,
' CPD_OFF, BOD_OFF, PWRT_ON,PROTECT_OFF
DEFINE OSC 4 'EXTERNAL CLOCK SPEED 4MH.added for this project
pause 2000 'DELAY TO LET STABILIZE AFTER POWER UP
CMCON = 7 'COMPARATOR OFF
VRCON = 0 'VOLTAGE REF. DISABLE
ANSEL = 0 'DIGITAL
OPTION_REG=0 'DEFAULT
WPUA = 0 'NO WEAK PULLUPS
INTCON=0 'INTERUPPTS OFF
' Debug (Communication) Defines (Transmit)
' ----------------------------------------
DEFINE DEBUG_REG PORTA 'CHANGED FROM B FOR 16F676
DEFINE DEBUG_BIT 1
DEFINE DEBUG_BAUD 300
DEFINE DEBUG_MODE 1
'
' DEBUG (Communication) Defines (Receive)
' ----------------------------------------
DEFINE DEBUGIN_REG PORTA 'CHANGED FROM B
DEFINE DEBUGIN_BIT 0
DEFINE DEBUGIN_BAUD 300
DEFINE DEBUGIN_MODE 1
'
Data @0,2,"ON",0,0,0,0,0
Data 3,"OFF",0,0,0,0
Data 5,"BLINK",0,0
Data 5,"SWEEP",0,0
Data 4,"BEER",0,0,0
Data 0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,0,0
'
' RAM Assignments and Variables
' -----------------------------
BadFlag var BIT ' Flag for Bad Command
CounterA var BYTE ' Just a Counter
CounterB var BYTE ' Just a Counter
CounterC var BYTE ' Just a Counter
CounterW var WORD ' Word-sized Counter
Command var BYTE ' Holds the Command action to execute
CommsBuffer var BYTE [10] ' Max Comms Command Line size
CommsPointer var BYTE ' Pointer to data in Comms Buffer
LEDStatus var BYTE
DataA var BYTE ' Usage as Data Byte
Xvariable var BYTE ' 1st Numeric Variable
Yvariable var BYTE ' 2nd Numeric Variable
'
' Program Constants
' -----------------
BufMax con 10 ' Max size of data Buffer
CommandMax con 10 ' Max number of COMMANDS to be processed
'
' Start - Initialise Processor
' ============================
TRISA=%00000001
TRISC=%00000000 'changed from B to C for 16f676
Xvariable=0:Gosub LEDsOFF ' All LEDs OFF
'
' Clear Buffer ready for start of New Command Line
' ------------------------------------------------
RestartLine:
For CounterA=1 to BufMax
CommsBuffer[CounterA-1]=0
Next CounterA
CommsPointer=0 ' Set Pointer to Start of Buffer
'
' Communications (Closed) Loop
' ----------------------------
ReadLoop:
DEBUGIN [DataA]
If DataA<32 then
If DataA=8 then ' Process BACKSPACE Key
If CommsPointer>0 then ' ---------------------
CommsPointer=CommsPointer-1 ' Rewind one position
CommsBuffer(CommsPointer)=0 ' Erase character in Buffer
DEBUG $08,$20,$08 ' Echo Erase sequence to PC
Goto ReadLoop
endif
endif
If DataA=13 then goto ENTERKey
Goto ReadLoop
endif
If DataA>126 then goto ReadLoop
DEBUG DataA ' Only Echo Printable Characters
If DataA>96 then ' Convert all alphabetics to UPPERCASE
If DataA<123 then DataA=DataA-32
endif
CommsBuffer(CommsPointer)=DataA ' Save to Buffer
CommsPointer=CommsPointer+1 ' Bump Pointer
If CommsPointer<10 then goto ReadLoop
' Loop for next character
'
' Process [ENTER] Key
' -------------------
' also execute if Command Buffer exceeded
ENTERKey:
'
' This section Parses the Command Line
' ====================================
'
' Look for Command WORD
' (scan through available Command vocabulary)
' -------------------------------------------
Gosub LSpace ' Remove Leading Blanks
Gosub REnd ' Locate Command Word End
If CounterA=0 then goto EchoCRLF
' Nothing to Process
For Command=1 to CommandMax
BadFlag=0
CounterB=(Command-1)*8
Read CounterB,DataA ' Get Preset Command word Length
If DataA=CounterA then ' If Length correct, process entire word
For CounterC=1 to CounterA
CounterB=CounterB+1
Read CounterB,DataA
If CommsBuffer(CounterC-1)<>DataA then BadFlag=1
Next CounterC
If BadFlag=0 then goto GoodCommand
endif
Next Command
'
' Bad Command Word
' ----------------
BadMove:
DEBUG REP $00\8,13,10,"Bad!"
' Tell User No Cigar
EchoCRLF:
DEBUG 13,10 ' New Line
Goto RestartLine ' Loop Round and Do again
'
' Parse for First Numeric Variable (if any)
' -----------------------------------------
GoodCommand:
Gosub ShuffleData ' Advance Command Line to start of next Word (if any)
Gosub REnd ' Locate End of next word
Gosub GetNumericWord ' Get numeric value
If BadFlag=1 then goto BadMove ' Invalid Data
Xvariable=DataA ' Save 1st Numeric Variable
'
' Now check for 2nd Numeric Variable (if any) on the Command Line
' ---------------------------------------------------------------
Gosub ShuffleData ' Advance Command Line to start of next (last) Word (if any)
Gosub REnd ' Locate End of word
Gosub GetNumericWord
If BadFlag=1 then goto BadMove ' Invalid Data
Yvariable=DataA ' Save 2nd Numeric Variable
'
' Execute Command
' ---------------
If (Command<4 and Xvariable>5) then
DEBUG REP $00\8,13,10,"No such LED!"
goto EchoCRLF
endif
If Command<3 then
If Yvariable>9 then goto BadMove
If Yvariable>1 then gosub WaitMessage
endif
If Command=3 then
If Yvariable>60 then goto BadMove
If Yvariable>5 then gosub WaitMessage
endif
If Command=4 then
If Xvariable>5 then gosub WaitMessage
endif
'
' ON LED Command
' --------------
If Command=1 then
Gosub LEDsON
If Yvariable>0 then
CounterW=Yvariable*1000
Pause CounterW
Gosub LEDsOFF
endif
endif
'
' OFF LED Command
' ---------------
If Command=2 then
Gosub LEDsOFF
If Yvariable>0 then
CounterW=Yvariable*1000
Pause CounterW
Gosub LEDsON
endif
endif
'
' BLINK LED Command
' -----------------
If Command=3 then
For CounterA=1 to Yvariable
Gosub LEDsON
Pause 200
Gosub LEDsOFF
Pause 200
Next CounterA
endif
'
' SWEEP Command
' -------------
If Command=4 then
CounterB=Xvariable
If CounterB<1 then CounterB=1
For CounterA=1 to CounterB
For Xvariable=1 to 5
Gosub LEDsON
Pause 100
Gosub LEDsOFF
Next XVariable
Next CounterA
endif
'
' BEER Command
' ------------
If Command=5 then DEBUG REP $00\8,13,10,"Yes Please!"
'
' Tell User all executed OK
' -------------------------
DEBUG REP $00\8,13,10,"OK"
Goto EchoCRLF
'
' Subroutine Area
' ===============
'
' Subroutine extracts Numeric Value from Command Line
' ---------------------------------------------------
GetNumericWord:
DataA=0
BadFlag=0
If CounterA>2 then Goto BadWord
If CounterA>0 then
CounterB=CommsBuffer(0)
If CounterB<48 then goto BadWord
DataA=CounterB-48
If DataA>9 then goto BadWord
If CounterA=2 then
CounterB=CommsBuffer(1)
If CounterB<48 then goto BadWord
CounterB=CounterB-48
If CounterB>9 then goto BadWord
DataA=DataA*10+CounterB
endif
endif
Return
BadWord:
BadFlag=1
Return
'
' Shuffle Data to remove processed word
' -------------------------------------
ShuffleData:
For CounterB=0 to 9
CounterC=CounterA+CounterB
If CounterC<=9 then
CommsBuffer(CounterB)=CommsBuffer(CounterC)
else
CommsBuffer(CounterB)=0
endif
Next CounterB
'
' Subroutine removes leading SPACES (Blanks) from Buffer
' ------------------------------------------------------
LSpace:
If CommsBuffer(0)=32 then
For CounterA=1 to 9
CommsBuffer(CounterA-1)=CommsBuffer(CounterA)
Next CounterA
CommsBuffer(9)=0
Goto LSpace
endif
Return
'
' Subroutine Locates end of Dataword in Comms Buffer
' --------------------------------------------------
' CounterA on exit End Point
REnd:
For CounterA=0 to 9
If CommsBuffer(CounterA)=32 then goto REndExit
If CommsBuffer(CounterA)=0 then goto REndExit
Next CounterA
CounterA=10
REndExit:
Return
'
' Subroutine tells User to Wait
' -----------------------------
WaitMessage:
DEBUG REP $00\8,13,10,"Wait..."
Return
'
' Subroutine DISABLES LEDs
' ------------------------
LEDsOFF:
If Xvariable=0 then
LEDStatus=$1F
else
LEDStatus.0(Xvariable-1)=1
endif
PortC=LEDStatus '*****CHANGED TO C FROM A
Return
'
' Subroutine ENABLES LEDs
' -----------------------
LEDsON:
If Xvariable=0 then
LEDStatus=$0
else
LEDStatus.0(Xvariable-1)=0
endif
PortC=LEDStatus '******* CHANGED TO C FROM A
Return
End
Bookmarks