;================================================ ; 1Chip PIC IDer 2003/03/27 JG1PJB T.Kuwahara ; 原典 : http://www.tfs.net/~petek/rockets/RDF/beacon2.txt ; 原典に倣いこのプログラムの商用利用を禁じます ; ; ; 原典著作権表示 ;======== pic beacon 2 980702 petek ============ ; (c) 1997 1998 by Peter Kerckhoff ; permission granted to copy for non-commercial use only ; all other rights reserved ; ; 981004 changed sleep mode to lower current draw ;================================================ ; ; header information, specify device type, hex numbers list p=12c509a radix hex ; configuration word for programming (msb -> lsb) ; MCLRE = 0 (internal reset) ; CP = 1 (code protection off) ; WDTE = 0 (watch dog timer disabled) ; FOSC1, FOSC0 = 10 (internal 4MHz oscillator) __config b'01010' ; register equates w equ 0x00 caryf equ 0x00 f equ 0x01 pc equ 0x02 zerof equ 0x02 status equ 0x03 osccal equ 0x05 port equ 0x06 regbase equ 0x07 send equ regbase ; the morse data to send msgreg equ regbase+1 ; msg string pointer didah equ regbase+2 ; on time for di's and dah's delay1 equ regbase+3 ; delay rtn counters delay2 equ regbase+4 ; d100 equ regbase+5 ; d250 equ regbase+6 ; tonep equ regbase+7 ; tone period (set by jumpers) pert equ regbase+8 ; tone duration math equ regbase+9 ; for literal add, subtract sw0 equ 0x00 ; tone select inputs sw1 equ 0x01 ; pwr equ 0x02 ; transmitter power onoff equ 0x03 ; on/off input line ook equ 0x04 ; OOK output line tone equ 0x05 ; tone output ;-------------------------------------------------- ; the 12c509a uses an automatic reset vector of 0x00 ; location 0x1ff is used for the internal 4MHz calibration ; value and should not be used or changed org 0x00 ;-------------------------------------------------- ; OPTION register settings (msb -> lsb) ; enable wake-up on pin change (GPUWU = 0) ; disenable weak pullups (GPPU = 1) ; timer0 clock source internal (TOCS = 0) ; timer0 edge select l->h (TOSE = 0) ; prescaler assigned to timer0 (PSA = 0) ; prescaler select of 1:2 (PS2-PS0 = 000) ; gp0 - (in ) select line 0 (lsb) ; gp1 - (in ) select line 1 (msb) ; gp2 - (out) output power to transmitter, 1= on ; gp3 - (in ) on/off, 1= on, 0= off (sleep) ; gp4 - (out) OOK output, 0= off ; gp5 - (out) tone output, 0=off start movwf osccal ; OSC calibration setting movlw b'01000000' ; option settings option movlw b'11001011' ; port configure tris port ; upon power up, wait 2 seconds, then play the ID message. ; during play the ID message on/off input bit set loop the ; program checks for the to off, if so, the processor goes ; to sleep, minimizing current draw ; play the ID message while keeping time and checking for ; the on/off command, the frequency of the ID message tone ; is determined by the jumper (switch) settings the following ; code segment sets the half-period time for the tone rtn-- ; sw1 sw0 frequency ; 0 0 Low ; 0 1 Middle1 ; 1 0 Middle2 ; 1 1 High ; ; note that 0=jumper installed, 1= NO jumper movlw d'41' ; setup literal add movwf math movlw d'82' ; preset for 2kHz btfss port,sw1 ; test msb movlw d'164' ; lower frequency btfss port,sw0 ; test lsb addwf math,w ; lsb=0 movwf tonep ; save period count ; now do a similar thing but for the 100mS delay constant movlw d'198' ; delay const for 2kHz btfss port,sw1 movlw d'99' movwf math ; save partial result clrw ; set w to zero btfss port,sw0 movlw d'50' ; set for subtraction subwf math,w ; math-w => w movwf pert ; save 100mS constant ; main loop, repeat the ID message bsf port,pwr ; turn the transmitter on long call w100mS ; wait 2 seconds call w100mS ; for the transmitter to call w100mS ; stabilize call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS call logmsg ; sends the ID message btfss port,onoff ; test on/off bit goto gnite ; leave if off goto long ; repeat the ID messeage ;---------------------------------------------------- ; logmsg ; main routine, this routine sends the ID message stored ; at msg in morse logmsg clrf msgreg ; clear the message counter playl movf msgreg,w ; get the message counter call msg ; used to point to msg character ; returned is morse equivalent play movwf send ; save the morse character movlw mEND ; is it the end flag? subwf send,w btfss status,zerof goto morout ; no, so play it return ; yes, end, leave ;---------------------------------------------------- ; morout ; enter with the morse character to be transmitted ; in the send register, this routine will toggle ; an output line, simulating a morse code transmission ; ; check for a control word delay flag first, then do ; either the delay or start sending the cw morout movlw mSpace ; is it a space (between words) subwf send,w btfss status,zerof goto morlop ; not a space, go send didah call w100mS ; space, wait 1400mS call w100mS ; for 6wpm (30cpm) cw call w100mS ; 1000mS here and another call w100mS ; 400mS at mordn call w100mS call w100mS call w100mS call w100mS call w100mS call w100mS goto mordn ; send the cw from the information stored in the send register ; Shift the eight bit register to the left, if the carry bit ; is 0 then send a di, if the carry bit is a 1 send a dah. ; When the send register = 1000 0000 then all bits have been ; sent. morlop movlw 0x02 ; setup for di (2 x 100mS) bcf status,caryf ; make sure carry bit is clear rlf send,f ; shift to get bit to send btfsc status,caryf ; skip next instruction for di's iorlw 0x06 ; 3 x di = dah (6 x 100mS) movwf didah ; save didah time morwat movf pert,w ; get 100mS constant movwf d100 bsf port,ook ; turn on OOK output wmors bsf port,tone ; turn on tone bit (high period) movf tonep,w ; get period constant movwf d250 whigh decfsz d250,f ; high period delay goto whigh bcf port,tone ; low period for tone bit movf tonep,w ; get period constant movwf d250 wlow decfsz d250,f ; low period delay goto wlow decfsz d100,f ; loop for 100mS goto wmors decfsz didah,f ; fall thru for di's goto morwat ; or do again twice for dah's bcf port,ook ; turn off OOK output call w100mS ; delay between di-dahs call w100mS ; 200mS for 6wpm (30cpm) movlw b'10000000' ; check for end of data subwf send,w btfss status,zerof ; not equal, not end goto morlop ; so continue with this character mordn call w100mS ; delay between characters call w100mS ; 200 + 400 = 600mS for 6wpm (30cpm) call w100mS call w100mS incf msgreg,f ; move to next character (pointer) goto playl ; loop for rest of message ;---------------------------------------------------- ; gnite ; all outputs low, and go to sleep mode gnite bcf port,ook ; set outputs low bcf port,pwr bcf port,tone movlw b'11111111' ; port configure tris port ; to all input bits movf port,w ; read all port bits sleep ; go to sleep ;----------------------------------------------------- ; w100mS ; 100 mS delay rtn w100mS movlw d'100' ; 1 cycle movwf delay2 ; 1 cycle ; gets kinda funky here ; as there is a 1mS rtn ; built into the 100mS ; rtn (saving a sub call ; and stack space!) d100ms movlw d'197' ; 1 cycle ---+ movwf delay1 ; 1 cycle | d1ms2 goto $+1 ; 2 cycles (x 197) | decfsz delay1,f ; 1 cycle (x 197) | goto d1ms2 ; 2 cycles (x 197) | ; 3 + 197 x 5 = 988 | goto $+1 ; = 990 | goto $+1 ; = 992 ---+ decfsz delay2,f ; 1 cycle goto d100ms ; 2 cycles, = 995 ; setup cycles 2 + 1 for fall thru = 3 ; interior cycles = 100 x 995 = 99500 ; = 99503 uS (99.503 mS) ; the calling rtn eats up 2 more and the return eats ; two cycles, = 99507uS, need to eat up 493 uS to ; give a precise 100mS delay ; also gives us an approximate 500uS delay w500uS movlw d'122' ; 1 cycle movwf delay1 ; 1 cycle d101ms nop ; 1 cycle x 122 decfsz delay1,f ; 1 cycle x 122 goto d101ms ; 2 cycles x 122 ; 2 + 1 + 4 x 122 = 491 uS goto $+1 ; waste 2 more cycles ; for 493 uS, add in ; the call (2uS) and ; return (2uS) for return ; a grand total of 100mS ;=========================================================== ; message area ; ; call the rtns with the message character number in ; w, returned is the morse coded in w ; ; the four messages are msg01, msg02, msg03, and msg04 ; use the following examples for coding up the message ; patterns. Fundamentally the code starts with a ; addwf to move to the correct retlw command. The ; return commands pass back the coded morse. To use ; a letter, preceed the letter with a 'm'. ; ; for example, to transmit CQ as message 1... ; ; msg01 addwf pc,f ; retlw mC ; retlw mQ ; retlw mSpace (optional space) ; retlw mEND (required end) ; ; the morse is transmitted in 12wpm (100mS for a dit) ; dashes are 3 times as long as a dit. Between dits ; and dahs is silence a dit in length. A silence 3 ; dits in length is automatically inserted between ; letters. A silence of 7 dits in length can be added ; between words by using the mSpace character ; ; messages programmed msg addwf pc,f retlw mV retlw mV retlw mV retlw mSpace retlw mD retlw mE retlw mSpace retlw mJ retlw mG retlw m1 retlw mP retlw mJ retlw mB retlw mSpace retlw mJ retlw mG retlw m1 retlw mP retlw mJ retlw mB retlw mSpace retlw mJ retlw mG retlw m1 retlw mP retlw mJ retlw mB retlw mEND ; equates for morse characters ; specify the coded characters by using 'm' followed ; by the letter you want to send the coded form of ; morse is based in... 0 = dit, 1 = dash, roll out ; the bits, when 0x80 remains the code is done ; this Morse Code storage rtn was published in _BYTE_ ; October 1976, pg. 36 in an article by L. Krakauer mA equ 0x60 mB equ 0x88 mC equ 0xa8 mD equ 0x90 mE equ 0x40 mF equ 0x28 mG equ 0xd0 mH equ 0x08 mI equ 0x20 mJ equ 0x78 mK equ 0xb0 mL equ 0x48 mM equ 0xe0 mN equ 0xa0 mO equ 0xf0 mP equ 0x68 mQ equ 0xd8 mR equ 0x50 mS equ 0x10 mT equ 0xc0 mU equ 0x30 mV equ 0x18 mW equ 0x70 mX equ 0x98 mY equ 0xb8 mZ equ 0xc8 m0 equ 0xfc m1 equ 0x7c m2 equ 0x3c m3 equ 0x1c m4 equ 0x0c m5 equ 0x04 m6 equ 0x84 m7 equ 0xc4 m8 equ 0xe4 m9 equ 0xf4 mPeriod equ 0x56 mComma equ 0xce mQuest equ 0x32 mEqual equ 0x8c mColon equ 0xe2 mSemi equ 0xaa mSlash equ 0x94 mDash equ 0x86 mSpace equ 0x01 ; space between words mEND equ 0x00 ; end of the info end