Project 8 - Morse Decoder
Wrong Listing in Book


New Listing for Project 8 (Morse Decoder):

;******************************************************
;
; Morse Decoder using 16F873
;
; Display on Port B (ASCII)
; Enable on RC7
; R/W on RC6
; Data/Command on RC5
;
; POT on A/D input to RA0 to provide speed
; Input from LM567 on RA2
; Switch on RA4 (Open = characters, Closed = Morse)
;
;*******************************************************

	__config	0x3F79

;PIC Registers
PCL  	EQU	0x02	;Program counter low byte
STATUS	EQU	0x03	;Used for Zero and Carry bits
PORTA	EQU	0x05 	;Inputs from PLL, A/D and Switch
PORTB	EQU	0x06	;Data output to display
PORTC	EQU	0x07	;Control signals to display
PCLATH	EQU	0x0A	;Program counter high byte
ADRES	EQU	0x1E	;A/D data register
ADCON	EQU	0x1F	;A/D control register

;User Registers
MARKREG	EQU  	0x20	;Dot/Dash signal
SPACEREG  EQU	0x21	;Space between dots and dashes

MORSE	EQU	0x24	;Character
MORSELEN	EQU	0x25	;Quantity of dots and dashes

SPEED	EQU	0x28	;From potentiometer setting

T1	EQU	0x2C	;Part of delay loop
T2	EQU	0x2D	;Part of delay loop

;PIC Bits
W	EQU	0
F	EQU	1
ZERO	EQU	2
CARRY	EQU	0
ADON	EQU	0	;Switches A/D convertor on
GO	EQU	2	;Starts A/D conversion

;User Bits
ENABLE	EQU	7	;Strobe to display
RW	EQU	6	;Read/Write to display
DC	EQU	5	;Data/Command to display
INPUT	EQU	2	;Input from PLL
SWITCH	EQU	4	;Character/dot-dash switch

	ORG       0x00

        GOTO	START
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP
	NOP

START	BSF 	3, 5		;Switch to register bank 1
	MOVLW	0xFF	     	;
	MOVWF	PORTA	     	;Set Port A to all inputs
	CLRF	PORTB	     	;Set Port B to all outputs
	CLRF	PORTC	     	;Set Port C to all outputs
	
;Initialise A/D

	MOVLW	0x04		;Analogue on bits 0 and 1 of Port A
	MOVWF	ADCON		;Internal voltage reference
	BCF	3, 5		;Switch back to register bank 0
	MOVLW	0x40		;Set A/D on bit 0
	MOVWF	ADCON		;Left justified 8 bit conversion
	BSF	ADCON, 0	;Start A/D conversion

;Initialise Display

	MOVLW  	0x28		;Initial delay (40mS)
	MOVWF	T2
I2	CALL	DELAY
	DECFSZ	T2, F
	GOTO	I2     		
	MOVLW	0x30 		;Function Set
	CALL	WC
	CALL 	DELAY
	MOVLW	0x0F    	;Display On
	CALL	WC
	CALL 	DELAY
	MOVLW	0x01    	;Clear Display
	CALL	WC
	CALL 	DELAY
	CALL 	DELAY
	CALL 	DELAY
	MOVLW	0x07    	;Entry Mode
	CALL	WC
	CALL 	DELAY
	MOVLW	0x8F		;Set Cursor Position
	CALL	WC
	CALL 	DELAY

;Display initial text	
	MOVLW	0x43    	;Letter C
	CALL	WD
	CALL	DELAY
	MOVLW	0x57    	;Letter W
	CALL	WD
	CALL	DELAY
	MOVLW	0x20    	;Space
	CALL	WD
	CALL	DELAY
	MOVLW	0x44    	;Letter D
	CALL	WD
	CALL	DELAY
	MOVLW	0x65    	;Letter e
	CALL	WD
	CALL	DELAY
	MOVLW	0x63    	;Letter c
	CALL	WD
	CALL	DELAY
	MOVLW	0x6F    	;Letter o
	CALL	WD
	CALL	DELAY
	MOVLW	0x64    	;Letter d
	CALL	WD
	CALL	DELAY
	MOVLW	0x65    	;Letter e
	CALL	WD
	CALL	DELAY
	MOVLW	0x72    	;Letter r
	CALL	WD
	CALL	DELAY
	MOVLW	0x20    	;Space
	CALL	WD
	CALL	DELAY
	MOVLW	0x20    	;Space
	CALL	WD
	CALL	DELAY


;Clear registers

	CLRF  	MARKREG
	CLRF	SPACEREG
	CLRF	MORSE
	CLRF	MORSELEN

;Continuation Routine - Input line high (No Mark)
	
SP1	BTFSS	PORTA, INPUT
	GOTO	MARK
	INCF	SPACEREG, F
	BTFSC	SPACEREG, 7
	GOTO	LONG
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
	GOTO	SP1

;Continuation Routine - Input line low
	
MARK    CLRF   	MARKREG
      	MOVLW   0x06
	SUBWF	SPACEREG, W        ;First, check if very short
	ANDLW	0x80
	BTFSS	STATUS, ZERO
	GOTO	MK1      	   ;Too short
	GOTO	ACTION
MK1	BTFSC	PORTA, INPUT
	GOTO	SPCE
	INCF	MARKREG, F
	MOVLW	0x7F
	BTFSC	MARKREG, 7
	MOVWF	MARKREG
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
	GOTO	MK1

SPCE    CLRF   	SPACEREG
      	MOVLW   0x06
	SUBWF	MARKREG, W        ;First, check if very short
	ANDLW	0x80
	BTFSS	STATUS, ZERO
	GOTO	SP1      	         ;Too short
	GOTO	DOTDASH

DOTDASH	INCF	MORSELEN, F
	MOVF	SPEED, W
	SUBWF	MARKREG, W
	ANDLW	0x80
	BTFSS	STATUS, ZERO
	GOTO	DOT  	         ;Dot
	GOTO	DASH     	         ;Dash

DASH	RLF	MORSE, F	;Move morse character one bit left
	BSF	MORSE, 0	;Set bottom Bit
	BTFSS	PORTA, SWITCH	;Get switch state
	GOTO	SP1		;Character mode so go to SP1
	MOVLW	0x2D		;Create a Dash
	CALL	WD		;Send to display
	CLRF	MORSE		;Delete morse character
	CLRF	MORSELEN
	GOTO	SP1		;Continue waiting for an edge

DOT	RLF	MORSE, F	;Move morse character one bit left
	BCF	MORSE, 0	;Clear bottom Bit
	BTFSS	PORTA, SWITCH	;Get switch state
	GOTO	SP1		;Character mode so go to SP1
	MOVLW	0x2E		;Create a Dot
	CALL	WD		;Send to display
	CLRF	MORSE		;Delete morse character
	CLRF	MORSELEN
	GOTO	SP1		;Continue waiting for an edge

LONG	MOVF	MORSELEN, F	;Move register so it can be tested for zero
	BTFSC	STATUS, ZERO	;Check if morselen is zero
	GOTO	L2		;Yes, so no character waiting to display
	CALL	DECODE		;No so decode and display character
	MOVLW	0x20		;Load space character
	CALL	WD		;Display space character
	CLRF	MORSE		;Clear morse character
	CLRF	MORSELEN	;Zeroise morse length
L2	MOVLW	0x7F		;Load spacereg with 128
	MOVWF	SPACEREG
	GOTO	SP1		;Continue waiting for an edge

ACTION	MOVF	SPEED, W	;Get potentiometer value
	SUBWF	SPACEREG, F	;Subtract from space count
	MOVF	SPACEREG, W	
	ANDLW	0x80		;Get positive/negative bit
	BTFSS	STATUS, ZERO	;Test
	GOTO	MK1		;Short so inter-bit gap (ignore)
	CALL	DECODE		;Long so decode and display character
	MOVF	SPEED, W	;Get potentiometer value (again)
	CLRF	MORSE		;Clear morse character
	CLRF	MORSELEN	;Zeroise length
	SUBWF	SPACEREG, W	;Subtract from space count (again)
	ANDLW	0x80		;Get positive/negative bit
	BTFSS	STATUS, ZERO	;Test
	GOTO	MK1		;Short so gap between characters (wait for next bit)
	MOVLW	0x20		;Long so inter-word gap
	CALL	WD		;Write a space character to the display
	GOTO	MK1		;Wait for next bit

DECODE	CALL	TABLE		;Translate morse to character
	MOVWF	MORSE		;Is it a character?
	MOVF	MORSE, F
	BTFSC	STATUS, ZERO
	GOTO	OUT1		;Bad character so go to out1
	MOVF	MORSE, W	;Good character
	CALL	WD		;Write character to display
OUT1	CLRF	MORSE		;Clear Character
	CLRF	MORSELEN	;Zeroise length
	RETURN

DELAY	MOVLW	0xA6		;166 (x3) = 498uS (A/D settling time)
	MOVWF	T1
D1	DECFSZ	T1, F
	GOTO	D1
	BSF	ADCON, GO	;Start A/D conversion
	MOVLW	0xA5		;165 (x3) = 485uS (A/D conversion time)
	MOVWF	T1
D2	DECFSZ	T1, F
	GOTO	D2
	RRF	ADRES, W	;Read and shift A/D result
	MOVWF	SPEED		;Write to speed register
	RRF 	SPEED, F	;Shift another bit
	MOVLW	0x3F		;Reduce to 6 bits
	ANDWF	SPEED, F
	MOVLW	0x0C		;Add 12 (speed = 12 to 76)
	ADDWF	SPEED, F	;Store in speed register
	RETURN	     	    

WC	MOVWF	PORTB		;Data/Command to port B
	MOVLW	0x00		;Set Data/Command line
	MOVWF	PORTC
	BSF	PORTC, ENABLE	;Set Enable/Strobe bit
	NOP
	BCF	PORTC, ENABLE	;Remove Enable/Strobe bit
	BSF	PORTC, RW	;Set read mode
	RETURN

WD	MOVWF	PORTB		;Data/Command to port B
	MOVLW	0x20		;Set Data/Command line
	MOVWF	PORTC
	BSF	PORTC, ENABLE	;Set Enable/Strobe bit
	NOP
	BCF	PORTC, ENABLE	;Remove Enable/Strobe bit
	BSF	PORTC, RW	;Set read mode
	RETURN


	ORG	0x100
;***********************************************************
;
; Morse to ASCII translation tables
;
; On entry, W contains character length (0 - 6 bits)
; MORSE contains actual morse character
;
;***********************************************************



TABLE	MOVLW	0x01
	MOVWF	PCLATH
	MOVF	MORSELEN, W
	ANDLW	0x07
	ADDWF	PCL, F
	RETLW	0x00
	GOTO	TABLE1
	GOTO	TABLE2
	GOTO	TABLE3
	GOTO	TABLE4
	GOTO	TABLE5
	GOTO	TABLE6
	RETLW	0x00
	
TABLE1	MOVF	MORSE, W
	ANDLW	0x01
	ADDWF	PCL, F
	RETLW	0x45		;E
	RETLW	0x54		;T

TABLE2	MOVF	MORSE, W
	ANDLW	0x03
	ADDWF	PCL, F
	RETLW	0x49		;I
	RETLW	0x41		;A
	RETLW	0x4E		;N
	RETLW	0x4D		;M

TABLE3	MOVF	MORSE, W
	ANDLW	0x07
	ADDWF	PCL, F
	RETLW	0x53		;S
	RETLW	0x55		;U
	RETLW	0x52		;R
	RETLW	0x57		;W
	RETLW	0x44		;D
	RETLW	0x4B		;K
	RETLW	0x47		;G
	RETLW	0x4F		;O

TABLE4	MOVF	MORSE, W
	ANDLW	0x0F
	ADDWF	PCL, F
	RETLW	0x48		;H
	RETLW	0x56		;V
	RETLW	0x46		;F
	RETLW	0xFF		;..--
	RETLW	0x4C		;L
	RETLW	0xFF		;.-.-
	RETLW	0x50		;P
	RETLW	0x4A		;J
	RETLW	0x42		;B
	RETLW	0x58		;X
	RETLW	0x43		;C
	RETLW	0x59		;Y
	RETLW	0x5A		;Z
	RETLW	0x51		;Q
	RETLW	0xFF		;---.
	RETLW	0xFF		;----

TABLE5	MOVF	MORSE, W
	ANDLW	0x1F
	ADDWF	PCL, F
	RETLW	0x35		;5
	RETLW	0x34		;4
	RETLW	0xFF		;...-.
	RETLW	0x33		;3
	RETLW	0xFF		;..-..
	RETLW	0xFF		;..-.-
	RETLW	0xFF		;..--.
	RETLW	0x32		;2
	RETLW	0x3D		;WAIT (=)
	RETLW	0xFF		;.-..-
	RETLW	0x7F		;EOM (<-)
	RETLW	0xFF		;.-.--
	RETLW	0xFF		;.--..
	RETLW	0xFF		;.--.-
	RETLW	0xFF		;.---.
	RETLW	0x31		;1
	RETLW	0x36		;6
	RETLW	0x3D		;BREAK (=)
	RETLW	0x2F		;/
	RETLW	0xFF		;-..--
	RETLW	0xFF		;-.-..
	RETLW	0x7E		;CALL (->)
	RETLW	0x3C		;(<)
	RETLW	0xFF		;-.---
	RETLW	0x37		;7
	RETLW	0xFF		;--..-
	RETLW	0xFF		;--.-.
	RETLW	0xFF		;--.--
	RETLW	0x38		;8
	RETLW	0xFF		;---.-
	RETLW	0x39		;9
	RETLW	0x30		;0

TABLE6	MOVF	MORSE, W
	ANDLW	0x3F
	ADDWF	PCL, F
	RETLW	0xFF		;......
	RETLW	0xFF		;.....-
	RETLW	0xFF		;....-.
	RETLW	0xFF		;....--
	RETLW	0xFF		;...-..
	RETLW	0x7F		;EOM(<-)
	RETLW	0xFF		;...--.
	RETLW	0xFF		;...---
	RETLW	0xFF		;..-...
	RETLW	0xFF		;..-..-
	RETLW	0xFF		;..-.-.
	RETLW	0xFF		;..-.--
	RETLW	0x3F		;?
	RETLW	0xFF		;..--.-
	RETLW	0xFF		;..---.
	RETLW	0xFF		;..----
	RETLW	0xFF		;.-....
	RETLW	0xFF		;.-...-
	RETLW	0xFF		;.-..-.
	RETLW	0xFF		;.-..--
	RETLW	0xFF		;.-.-..
	RETLW	0x2E		;STOP
	RETLW	0xFF		;.-.--.
	RETLW	0xFF		;.-.---
	RETLW	0xFF		;.--...
	RETLW	0xFF		;.--..-
	RETLW	0xFF		;.--.-.
	RETLW	0xFF		;.--.--
	RETLW	0xFF		;.---..
	RETLW	0xFF		;.---.-
	RETLW	0xFF		;.----.
	RETLW	0xFF		;.-----
	RETLW	0xFF		;-.....
	RETLW	0xFF		;-....-
	RETLW	0xFF		;-...-.
	RETLW	0xFF		;-...--
	RETLW	0xFF		;-..-..
	RETLW	0xFF		;-..-.-
	RETLW	0xFF		;-..--.
	RETLW	0xFF		;-..---
	RETLW	0xFF		;-.-...
	RETLW	0xFF		;-.-..-
	RETLW	0xFF		;-.-.-.
	RETLW	0xFF		;-.-.--
	RETLW	0xFF		;-.--..
	RETLW	0xFF		;-.--.-
	RETLW	0xFF		;-.---.
	RETLW	0xFF		;-.----
	RETLW	0xFF		;--....
	RETLW	0xFF		;--...-
	RETLW	0xFF		;--..-.
	RETLW	0x2C		;COMMA
	RETLW	0xFF		;--.-..
	RETLW	0xFF		;--.-.-
	RETLW	0xFF		;--.--.
	RETLW	0xFF		;--.---
	RETLW	0xFF		;---...
	RETLW	0xFF		;---..-
	RETLW	0xFF		;---.-.
	RETLW	0xFF		;---.--
	RETLW	0xFF		;----..
	RETLW	0xFF		;----.-
	RETLW	0xFF		;-----.
	RETLW	0xFF		;------

	
	END



Click here to return to the PIC Basics Main Page

Click here for the Index of Errors and Ommissions