Using A PIC for an IDER
In the course of building HAM repeaters I have built controllers and identifiers. The first CW identifier I built was a discrete diode array. The identifier’s printed circuit board (PCB) was double-sided. The top side of the PCB contained columns and the bottom had rows. As the array was scanned it would send a pulse each time it hit a diode. The diode array’s capacity was about 120 elements. Since a zero has 19 elements, the board couldn’t hold much more than a call sign.
Eprom technologies increased storage capacity and simplified programming, which far surpassed the old diode arrays. Next generation of CW identifiers used an Eprom to hold the message. The Eprom Ider in my circuit box, was originally tested using a manual programmer. The manual programmer consisted of two sets of dip switches and a 555 timer. The first bank of switches loaded the Eprom’s memory address and the second set of switches loaded the data. Once set the chip’s memory was programmed by triggering a 555 timer which applied a write pulse. After testing the Eprom design using the manual programmer, I quickly purchased an Eprom programmer to ease the process of message programming. All these designs were problematic, in that, the message could easily be improperly coded.
With a advent of the microcontroller the next generation of Ider’s fixed the CW characters by using a byte of data (8 bits) and storing them in the program . Once properly encoded he numeric value of a character could be repeated without concern of a missing dit.
Working in Assembly Language lots of data manipulation was done using the computer’s registers. A byte has more than enough space to hold CW characters. By shifting the data around using a register makes encoding Morse Code characters straight forward. Using a 0 to equal a dit and a one to equal dah. A character could be encoded and placed in a register. By shifting the character one bit at a time and decoding either a dit for zero or dah for a one until finally is only a single 1 left in the register. A single one in the register signaled the End of Character. There were two special characters added: 0xFF all ones and the second 0x00 all zeros. 0xFF is End of Message (EOM) and 0x00 is Word Space (WS).
The Assembly code (retlw 0x06 ;a). Is an “A” CW character using the HEX base number. The computer speaks several number systems HEX, BINARY and BASE10, the numbering system we like to use. A HEX number 0x6 is equal to BINAY number 110. If we use the Binary number 110 the first bit the computer encounters is a 0 = dit , next is a 1 = dah and then its left with the stop bit 1. The computer has decoded dit dah which is CW for the letter “A” and then stopped.
Soon there were C compilers available for the PIC microprocessor chips and life became easier for the PIC programmers. But the Character encoding that was done in Assembly programs still works today as we shift bits in C++.
The code below is the PIC Chip assembly language program for the PIC 16F84. The program was finished in 1997 and was published in a QST article Jan. 1998.
(updated 09-18-2008)
;*********************************************************************** ;**** Built Thu Oct 28 11:29:05 2004 ***** ;**** VERSION CWT-2222, 2-23-97 ***** ;**** VERSION CWT-2223, 10-15-2004 **** ;**** MSG Comments added, 09-18-2008 **** ;**** CW IDER BY B. ANDING ********* ; * This program is free software. Licensed for private use only ; * Permission is granted to use, copy, or redistribute this program ; * so long as it is not sold for profit. ; * THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, ; * EITHER EXPRESSED OR IMPLIED. This notice must follow program listing. ; *********************************************************************** LIST P=16F84 radix hex ;======================================= w equ 0 f equ 1 ;======================================= tmr0 equ 0x01 pc equ 0x02 status equ 0x03 porta equ 0x05 portb equ 0x06 shift equ 0x0c tcount equ 0x0d count equ 0x0e ;======================================= START org 0x00 movlw 0x00 tris portb ;set portb write movlw 0xff tris porta ;set porta read clrf portb ;------------------------------------- WAIT clrf count bcf portb,2 ;clear PTT pin btfss porta,1 ;check sw 1 for 1 goto TIMER goto WAIT ;------------------------------------- LTRSPC movlw 0xae ;letter space = 174 movwf tcount ;set count goto SPC return WDSPC movlw 0xcb ;word space = 203 movwf tcount ;set count call SPC movlw 0xcb ;word space = 203 movwf tcount ;set count call SPC goto GETLTR ;------------------------------------- ;This is the "ID" message code which will send the CW message ;As its written it sends the alphabet ;To send my call remove the alphabet code and insert AA5OY ;Then add a EOM to stop message ;see the following example ;ID addwf pc,f ;ID = memory location ; retlw 0x06 ;a = sends A ; retlw 0x06 ;a = sends A ; retlw 0x20 ;5 = sends 5 ; retlw 0x0f ;o = sends O ; retlw 0x1d ;y = sends Y ; retlw 0xff ;EOM = ends message ;--------------------------------------- ID addwf pc,f retlw 0x06 ;a retlw 0x11 ;b retlw 0x15 ;c retlw 0x09 ;d retlw 0x02 ;e retlw 0x14 ;f retlw 0x0b ;g retlw 0x10 ;h retlw 0x04 ;i retlw 0x1e ;j retlw 0x0d ;k retlw 0x12 ;l retlw 0x07 ;m retlw 0x05 ;n retlw 0x0f ;o retlw 0x16 ;p retlw 0x1b ;q retlw 0x0a ;r retlw 0x08 ;s retlw 0x03 ;t retlw 0x0c ;u retlw 0x18 ;v retlw 0x0e ;w retlw 0x19 ;x retlw 0x1d ;y retlw 0x13 ;z retlw 0x3e ;1 retlw 0x3c ;2 retlw 0x38 ;3 retlw 0x30 ;4 retlw 0x20 ;5 retlw 0x21 ;6 retlw 0x23 ;7 retlw 0x27 ;8 retlw 0x2f ;9 retlw 0x3f ;0 retlw 0x00 ;Word Space retlw 0x29 ;/ retlw 0x68 ;SK retlw 0x2a ;AR retlw 0x31 ;BT retlw 0x4c ;? retlw 0xff ;EOM ;------------------------------------- DELAY clrf tmr0 ;set timer clrwdt ; clear watch dog timer movlw b'11010011' ;893hz. option ; load reg AGAIN btfss tmr0,5 ; delay goto AGAIN return ;------------------------------------- GETLTR nop movf count,w call ID ;get next letter incf count,f ;move count to next letter movwf shift ;move letter to shift reg movlw 0x00 ;Word Space = 00 subwf shift,w btfsc status,2 goto WDSPC movlw 0xff ;EOM = 256 subwf shift,w btfsc status,2 goto WAIT ;-------------------------------------- LOOP movf shift,w ;get bit pattern btfsc shift,0 movlw 0xae ;get DAH length = 174 btfss shift,0 movlw 0x3a ;get DIT length = 58 movwf tcount call PULSE rrf shift,f ;ROTATE BIT to LSB bcf shift,7 ;clear MSB movlw 0x01 ;Check for end bit subwf shift,w btfss status,2 ;if end break loop goto LOOP call LTRSPC ; letter spacing goto GETLTR ;get next letter ;---------------------------------- PULSE bsf portb,1 ;set port b call DELAY ; delay bcf portb,1 ; clear port b call DELAY ; delay decfsz tcount,f goto PULSE movlw 0x3a ;element space movwf tcount ;set count SPC nop call DELAY ; delay nop ; silent call DELAY ; delay decfsz tcount,f goto SPC return ;------------------------------------------- TIMER movlw 0x8b ;16C84 =(.8) * 16F84 movwf count ;set count to 139 clrwdt movlw b'11011111' ; set 256 option ; load prescaler in reg. REPT bsf portb,7 ;signal active timer sleep ; delay 2.3 sec. bcf portb,7 ;signal active timer sleep ; delay 2.3 sec. decfsz count,f goto REPT clrwdt clrf count bsf portb,2 ;set PTT pin goto GETLTR ;start IDer ;---------------------------- end
looks good
LikeLike