;****************************************************** ; ; 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) ; ;******************************************************* ;PIC Registers PCL .EQU $02 ;Program counter low byte STATUS .EQU $03 ;Used for Zero and Carry bits PORTA .EQU $05 ;Inputs from PLL, A/D and Switch PORTB .EQU $06 ;Data output to display PORTC .EQU $07 ;Control signals to display PCLATH .EQU $0A ;Program counter high byte ADRES .EQU $1E ;A/D data register ADCON .EQU $1F ;A/D control register ;User Registers MARKREG .EQU $20 ;Dot/Dash signal SPACEREG .EQU $21 ;Space between dots and dashes MORSE .EQU $24 ;Character MORSELEN .EQU $25 ;Quantity of dots and dashes SPEED .EQU $28 ;From potentiometer setting T1 .EQU $2C ;Part of delay loop T2 .EQU $2D ;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 $00 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 $FF ; 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 $04 ;Analogue on bits 0 and 1 of Port A MOVWF ADCON ;Internal voltage reference BCF 3, 5 ;Switch back to register bank 0 MOVLW $40 ;Set A/D on bit 0 MOVWF ADCON ;Left justified 8 bit conversion BSF ADCON, 0 ;Start A/D conversion ;Initialise Display MOVLW $28 ;Initial delay (40mS) MOVWF T2 I2 CALL DELAY DECFSZ T2, F GOTO I2 MOVLW $30 ;Function Set CALL WC CALL DELAY MOVLW $0F ;Display On CALL WC CALL DELAY MOVLW $01 ;Clear Display CALL WC CALL DELAY CALL DELAY CALL DELAY MOVLW $07 ;Entry Mode CALL WC CALL DELAY MOVLW $8F ;Set Cursor Position CALL WC CALL DELAY ;Display initial text MOVLW $43 ;Letter C CALL WD CALL DELAY MOVLW $57 ;Letter W CALL WD CALL DELAY MOVLW $20 ;Space CALL WD CALL DELAY MOVLW $44 ;Letter D CALL WD CALL DELAY MOVLW $65 ;Letter e CALL WD CALL DELAY MOVLW $63 ;Letter c CALL WD CALL DELAY MOVLW $6F ;Letter o CALL WD CALL DELAY MOVLW $64 ;Letter d CALL WD CALL DELAY MOVLW $65 ;Letter e CALL WD CALL DELAY MOVLW $72 ;Letter r CALL WD CALL DELAY MOVLW $20 ;Space CALL WD CALL DELAY MOVLW $20 ;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 $06 SUBWF SPACEREG, W ;First, check if very short ANDLW $80 BTFSS STATUS, ZERO GOTO MK1 ;Too short GOTO ACTION MK1 BTFSC PORTA, INPUT GOTO SPCE INCF MARKREG, F MOVLW $7F BTFSC MARKREG, 7 MOVWF MARKREG CALL DELAY CALL DELAY CALL DELAY GOTO MK1 SPCE CLRF SPACEREG MOVLW $06 SUBWF MARKREG, W ;First, check if very short ANDLW $80 BTFSS STATUS, ZERO GOTO SP1 ;Too short GOTO DOTDASH DOTDASH INCF MORSELEN, F MOVF SPEED, W SUBWF MARKREG, W ANDLW $80 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 $2D ;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 $2E ;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 $20 ;Load space character CALL WD ;Display space character CLRF MORSE ;Clear morse character CLRF MORSELEN ;Zeroise morse length L2 MOVLW $7F ;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 $80 ;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 $80 ;Get positive/negative bit BTFSS STATUS, ZERO ;Test GOTO MK1 ;Short so gap between characters (wait for next bit) MOVLW $20 ;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 $A6 ;166 (x3) = 498uS (A/D settling time) MOVWF T1 D1 DECFSZ T1, F GOTO D1 BSF ADCON, GO ;Start A/D conversion MOVLW $A5 ;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 $3F ;Reduce to 6 bits ANDWF SPEED, F MOVLW $0C ;Add 12 (speed = 12 to 76) ADDWF SPEED, F ;Store in speed register RETURN WC MOVWF PORTB ;Data/Command to port B MOVLW $00 ;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 $20 ;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 $100 ;*********************************************************** ; ; Morse to ASCII translation tables ; ; On entry, W contains character length (0 - 6 bits) ; MORSE contains actual morse character ; ;*********************************************************** TABLE MOVLW $01 MOVWF PCLATH MOVF MORSELEN, W ANDLW $07 ADDWF PCL, F RETLW $00 GOTO TABLE1 GOTO TABLE2 GOTO TABLE3 GOTO TABLE4 GOTO TABLE5 GOTO TABLE6 RETLW $00 TABLE1 MOVF MORSE, W ANDLW $01 ADDWF PCL, F RETLW $45 ;E RETLW $54 ;T TABLE2 MOVF MORSE, W ANDLW $03 ADDWF PCL, F RETLW $49 ;I RETLW $41 ;A RETLW $4E ;N RETLW $4D ;M TABLE3 MOVF MORSE, W ANDLW $07 ADDWF PCL, F RETLW $53 ;S RETLW $55 ;U RETLW $52 ;R RETLW $57 ;W RETLW $44 ;D RETLW $4B ;K RETLW $47 ;G RETLW $4F ;O TABLE4 MOVF MORSE, W ANDLW $0F ADDWF PCL, F RETLW $48 ;H RETLW $56 ;V RETLW $46 ;F RETLW $FF ;..-- RETLW $4C ;L RETLW $FF ;.-.- RETLW $50 ;P RETLW $4A ;J RETLW $42 ;B RETLW $58 ;X RETLW $43 ;C RETLW $59 ;Y RETLW $5A ;Z RETLW $51 ;Q RETLW $FF ;---. RETLW $FF ;---- TABLE5 MOVF MORSE, W ANDLW $1F ADDWF PCL, F RETLW $35 ;5 RETLW $34 ;4 RETLW $FF ;...-. RETLW $33 ;3 RETLW $FF ;..-.. RETLW $FF ;..-.- RETLW $FF ;..--. RETLW $32 ;2 RETLW $3D ;WAIT (=) RETLW $FF ;.-..- RETLW $7F ;EOM (<-) RETLW $FF ;.-.-- RETLW $FF ;.--.. RETLW $FF ;.--.- RETLW $FF ;.---. RETLW $31 ;1 RETLW $36 ;6 RETLW $3D ;BREAK (=) RETLW $2F ;/ RETLW $FF ;-..-- RETLW $FF ;-.-.. RETLW $7E ;CALL (->) RETLW $3C ;(<) RETLW $FF ;-.--- RETLW $37 ;7 RETLW $FF ;--..- RETLW $FF ;--.-. RETLW $FF ;--.-- RETLW $38 ;8 RETLW $FF ;---.- RETLW $39 ;9 RETLW $30 ;0 TABLE6 MOVF MORSE, W ANDLW $3F ADDWF PCL, F RETLW $FF ;...... RETLW $FF ;.....- RETLW $FF ;....-. RETLW $FF ;....-- RETLW $FF ;...-.. RETLW $7F ;EOM(<-) RETLW $FF ;...--. RETLW $FF ;...--- RETLW $FF ;..-... RETLW $FF ;..-..- RETLW $FF ;..-.-. RETLW $FF ;..-.-- RETLW $3F ;? RETLW $FF ;..--.- RETLW $FF ;..---. RETLW $FF ;..---- RETLW $FF ;.-.... RETLW $FF ;.-...- RETLW $FF ;.-..-. RETLW $FF ;.-..-- RETLW $FF ;.-.-.. RETLW $2E ;STOP RETLW $FF ;.-.--. RETLW $FF ;.-.--- RETLW $FF ;.--... RETLW $FF ;.--..- RETLW $FF ;.--.-. RETLW $FF ;.--.-- RETLW $FF ;.---.. RETLW $FF ;.---.- RETLW $FF ;.----. RETLW $FF ;.----- RETLW $FF ;-..... RETLW $FF ;-....- RETLW $FF ;-...-. RETLW $FF ;-...-- RETLW $FF ;-..-.. RETLW $FF ;-..-.- RETLW $FF ;-..--. RETLW $FF ;-..--- RETLW $FF ;-.-... RETLW $FF ;-.-..- RETLW $FF ;-.-.-. RETLW $FF ;-.-.-- RETLW $FF ;-.--.. RETLW $FF ;-.--.- RETLW $FF ;-.---. RETLW $FF ;-.---- RETLW $FF ;--.... RETLW $FF ;--...- RETLW $FF ;--..-. RETLW $2C ;COMMA RETLW $FF ;--.-.. RETLW $FF ;--.-.- RETLW $FF ;--.--. RETLW $FF ;--.--- RETLW $FF ;---... RETLW $FF ;---..- RETLW $FF ;---.-. RETLW $FF ;---.-- RETLW $FF ;----.. RETLW $FF ;----.- RETLW $FF ;-----. RETLW $FF ;------ .END