⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyer-3.0.18.asm

📁 PIC16F628A制作的自动键程序,供无线电爱好者参考.
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	retlw b'01010100'	;S		27
	retlw b'00000000'
	retlw b'11000000'	;T		28
	retlw b'00000000'
	retlw b'01011100'	;U		29
	retlw b'00000000'
	retlw b'01010111'	;V		30
	retlw b'00000000'
	retlw b'01111100'	;W		31
	retlw b'00000000'
	retlw b'11010111'	;X		32
	retlw b'00000000'
	retlw b'11011111'	;Y		33
	retlw b'00000000'
	retlw b'11110101'	;Z		34
	retlw b'00000000'

	endif ;include_cw_table_long

; Subroutines -------------------------------------------------------------

check_paddles

	banksel PORTA
	pagesel $

	ifdef include_paddle_reverse_code
	btfsc paddle_reverse
	goto check_paddles_reverse
	endif ;include_paddle_reverse_code

	btfss dit		; if dit is not keyed, skip next
	bsf dit_buffer	; set dit_buffer
	btfss dah		; if dah is not keyed, skip next
	bsf dah_buffer	; set dah_buffer
    goto squeeze_check

	ifdef include_paddle_reverse_code
check_paddles_reverse	
	btfss dit		; if dit is not keyed, skip next
	bsf dah_buffer	; set dah_buffer
	btfss dah		; if dah is not keyed, skip next
	bsf dit_buffer	; set dit_buffer
	endif ;include_paddle_reverse_code

squeeze_check
	ifdef include_iambic_mode_code
	btfsc iambic_b_mode				; don't do squeeze check if we're in iambic b mode
	return
	endif ;include_iambic_mode_code
	btfsc dit		; if both dit and dah are squeezed, set the squeeze_detected flag
	return
	btfsc dah
    return
    bsf squeeze_detected

    return

; ------------------


send_w_BCD_in_cw

	; this sends the lower nibble of w (BCD binary coded decimal) in CW

	movwf temp_memory
	addwf temp_memory, F 		; double it so we're in the right spot in cw_table
	movfw temp_memory			; put it in W for lookup table		
	call cw_table
	movwf cw_char_to_send+0
	movfw temp_memory
	addlw 0x01					; add 1 to get next byte in table
	call cw_table
	movwf cw_char_to_send+1
	errorlevel -306
	pagesel send_cw
	call send_cw
	errorlevel +306
	return
	
; ------------------

	ifdef include_funky_beeps_code

beep
	movwf temp_w						; store w temporarily
	movfw wavesidetone_counter_setting	; store real wavesidetone setting in temp_memory
	movwf temp_memory
	movfw temp_w						; get temp_w and put in for wavesidetone setting
	movwf wavesidetone_counter_setting

	movlw _beep_length
	movwf counter1
	movwf counter2
	
	bsf sidetone
	
beep_loop
	call produce_wavesidetone
	decfsz counter1, F
	goto beep_loop
	decfsz counter2, F
	goto beep_loop
	
	bcf sidetone
	
	movfw temp_memory					; restore real wavesidetone setting
	movwf wavesidetone_counter_setting	
	return
	

; ------------------

high_beep
	ifndef exclude_delays_debug
	movlw _high_beep_tone
	call beep
	endif ;exclude_delays_debug
	return
	
; ------------------

low_beep
	ifndef exclude_delays_debug
	movlw _low_beep_tone
	call beep
	endif ;exclude_delays_debug
	return

; ------------------

beep_boop
	ifndef exclude_delays_debug
	call high_beep
	call low_beep
	endif ;exclude_delays_debug
	return

; ------------------

boop_beep
	call low_beep
	call high_beep
	return

	endif ;include_funky_beeps_code

; ------------------

divide16bit

	; dividend / divisor = quotient
	; this code from Mark Sullivan www.markworld.com (thanks for saving me hours of work ! :-)
	
	banksel PORTA
	pagesel $

	movlw d'16'
	movwf count
	clrf quotient+0	;quotient
	clrf quotient+1
	clrf remainder+0	;remainder
	clrf remainder+1
udiv1
	bcf	STATUS,C
	rlf	dividend+1,F
	rlf	dividend+0,F
	rlf	remainder+1,F
	rlf	remainder+0,F
	movf divisor+0,W
	subwf remainder+0,W
	btfss STATUS,Z
	goto udiv2
	movf divisor+1,W
	subwf remainder+1,W
	btfss STATUS,C
	goto udiv4
	movwf remainder+1
	movf divisor+0,W
	subwf remainder+0,F
	goto udiv3
udiv2
	btfss STATUS,C
	goto udiv4
	movf divisor+1,W
	subwf remainder+1,F
	btfss STATUS,C
	decf remainder+0,F
	movf divisor+0,W
	subwf remainder+0,F
udiv3
	bsf	STATUS,C
udiv4
	rlf	quotient+1,F
	rlf	quotient+0,F
	decfsz count,F
	goto udiv1
	retlw 0

; ------------------

	ifdef include_freq_counter_code

bcd2binary

	; BCD to 16 bit binary converter
	; adapted from Microchip AN526
	; http://www.microchip.com
	; thanks, Microchip !

	;input parameters:
	;bcd2binary+0 : MSB
	;bcd2binary+1 : LSB

	;output:
	;BCD0 = most significant digits
	;BCD1
	;BCD2 = least significant digits

	;each BCD register contains and upper and lower nibble BCD digit

	banksel PORTA
	pagesel $

	clrf bcd2binary_binary_out+0
	movf BCD0,W
	andlw 0x0F
	movwf bcd2binary_binary_out+1
	call mpy10a          ; result = 10a+b
	swapf BCD1,W
	call mpy10b          ; result = 10[10a+b]
	movf BCD1,W
	call mpy10b          ; result = 10[10[10a+b]+c]
	swapf BCD2,W
	call mpy10b          ; result = 10[10[10[10a+b]+c]+d]
	movf BCD2,W
	andlw 0x0F
	addwf bcd2binary_binary_out+1, F
	btfsc STATUS,C
	incf bcd2binary_binary_out+0, F       ; result = 10[10[10[10a+b]+c]+d]+e
	return               ; BCD to binary conversion done

	; subroutines

mpy10b 
	andlw 0x0F
	addwf bcd2binary_binary_out+1, F
	btfsc STATUS,C
	incf bcd2binary_binary_out+0, F
mpy10a  
	bcf STATUS,C        ; multiply by 2
	rlf bcd2binary_binary_out+1,W
	movwf L_temp
	rlf     bcd2binary_binary_out+0,W        ; (H_temp,L_temp) = 2*N
	movwf   H_temp
	bcf     STATUS,C        ; multiply by 2
	rlf     bcd2binary_binary_out+1, F
	rlf     bcd2binary_binary_out+0, F
	bcf     STATUS,C        ; multiply by 2
	rlf     bcd2binary_binary_out+1, F
	rlf     bcd2binary_binary_out+0, F
	bcf     STATUS,C        ; multiply by 2
	rlf     bcd2binary_binary_out+1, F
	rlf     bcd2binary_binary_out+0, F       ; (bcd2binary_binary_out+0,bcd2binary_binary_out+1) = 8*N
	movf    L_temp,W
	addwf   bcd2binary_binary_out+1, F
	btfsc   STATUS,C
	incf    bcd2binary_binary_out+0, F
	movf    H_temp,W
	addwf   bcd2binary_binary_out+0, F
	return              ; (bcd2binary_binary_out+0,bcd2binary_binary_out+1) = 10*N


	endif ;include_freq_counter_code

; ------------------

binary2bcd

	; 16 bit binary to bcd converter
	; adapted from Microchip AN526
	; http://www.microchip.com
	; thanks, Microchip !

	banksel PORTA
	pagesel $

	bcf     STATUS, C                ; clear the carry bit
	movlw   .16
	movwf   count
	clrf    BCD0		; most significant digit
	clrf    BCD1
	clrf    BCD2		; least significant digit
loop16
	rlf     binary2bcd_binary_in+1, F	; LSB
	rlf     binary2bcd_binary_in+0, F	; MSB
	rlf     BCD2, F
	rlf     BCD1, F
	rlf     BCD0, F
	decfsz  count, F
	goto    adjDEC
	retlw   0
adjDEC
	movlw   BCD2
	movwf   FSR
	call    adjBCD
	movlw   BCD1
	movwf   FSR
	call    adjBCD
	movlw   BCD0
	movwf   FSR
	call    adjBCD
	goto    loop16
adjBCD
	movlw   3
	addwf   INDF, W
	movwf   temp
	btfsc   temp,3          ; test if result > 7
	movwf   INDF
	movlw   30
	addwf   INDF, W
	movwf   temp
	btfsc   temp,7          ; test if result > 7
	movwf   INDF               ; save as MSD
	retlw   0
	
; ------------------

write_eeprom

	pagesel $

	; save EEDATA and EEADR for write verify
	errorlevel -302
	banksel EEDATA
	movfw EEDATA
	banksel PORTA
	movwf write_verify_data
	banksel EEADR
	movfw EEADR
	banksel PORTA
	movwf write_verify_addr
	errorlevel +302

start_write
	errorlevel -302
	banksel INTCON
	bcf	INTCON, GIE		; disable interrupts
	banksel EECON1
	bsf	EECON1, WREN	; enable write
	movlw 0x55			; required write sequence
	movwf EECON2		; required write sequence
	movlw 0xaa			; required write sequence
	movwf EECON2		; required write sequence
	bsf EECON1,WR 		; write
wait_to_complete_write
	btfsc EECON1, WR	; watch for WR flag to clear
	goto wait_to_complete_write
	
	; check if write failed, loop a couple times to try again
	banksel write_verify_addr
	movfw write_verify_addr	; select the address
	banksel EEADR
	movwf EEADR
	banksel EECON1
	bsf EECON1, RD		; read it
	banksel EEDATA
	movfw EEDATA		; get the data
	banksel PORTA
	subwf write_verify_data, W	; compare it
	btfss STATUS, Z		; skip next if its equal
	goto write_again	; otherwise, write it again

write_eeprom_blowout
	banksel INTCON
	bsf INTCON, GIE		; enable interrupts
	banksel EECON1
	bcf EECON1, WREN	; clear write enable flag
	bcf EECON1, EEIF	; clear EE Interrupt flag for the hell of it
	banksel PORTA
	return
	
write_again
	banksel write_verify_data
	movfw write_verify_data		; reload EEDATA and EEADR with the original values
	banksel EEDATA
	movwf EEDATA
	banksel write_verify_addr
	movfw write_verify_addr
	banksel EEADR
	movwf EEADR	
	banksel PORTA
	goto start_write

	errorlevel -302
	
; ------------------	
calculate_cw_unit_values

	banksel PORTA
	pagesel $

	movlw LOW _cw_unit_wpm_factor
	movwf dividend+1
	movlw HIGH _cw_unit_wpm_factor
	movwf dividend+0
	movfw speed_wpm
	movwf divisor+1		; lsb - divisor
	movlw 0x00
	movwf divisor+0		; msb - divisor
	
	call divide16bit
	movf	quotient+1, W	;load LSB of result
	movwf	cw_unit_counter+1
	movf	quotient+0, W	;load MSB of result
	movwf	cw_unit_counter+0

	ifdef include_weighting_code
	movlw LOW _cw_unit_wpm_factor
	movwf dividend+1
	movlw HIGH _cw_unit_wpm_factor
	movwf dividend+0
	movfw speed_wpm_dah
	movwf divisor+1		; lsb - divisor
	movlw 0x00
	movwf divisor+0		; msb - divisor
	
	call divide16bit
	movf	quotient+1, W	;load LSB of result
	movwf	cw_unit_counter_dah+1
	movf	quotient+0, W	;load MSB of result
	movwf	cw_unit_counter_dah+0
	endif ;include_weighting_code

	return

; ------------------
	ifdef include_mode_button_hold_code

	banksel PORTA
	pagesel $

wait_for_mode_switch_release
	btfss mode_switch
	goto wait_for_mode_switch_release
	call pause_100_ms
	call pause_100_ms
	bcf key_tx_active
	return
	
	endif

; ------------------

pause_100_ms


	banksel PORTA ; for good measure

	movlw _100ms_counter1_calibration
	movwf counter1
	movlw _100ms_counter2_calibration
	movwf counter2
	movlw _100ms_counter3_calibration
	movwf counter3

looplooploop
	ifndef exclude_delays_debug
	decfsz counter1, F
	goto looplooploop
	decfsz counter2, F
	goto looplooploop
	decfsz counter3, F
	goto looplooploop
	endif ;exclude_delays_debug
	return
	
; ------------------

pause_w_100ms

	; pause W * 100 milliseconds

	banksel PORTA	; for good measure

	movwf count
	ifndef exclude_delays_debug
loop_decrement
	call pause_100_ms
	decfsz count, F
	goto loop_decrement
	endif ;exclude_delays_debug
	return

; ------------------

produce_wavesidetone
	btfss sidetone						; is sidetone on right now ?
	goto wavesidetone_off				; no, go turn the wavesidetone line off
	incf wavesidetone_counter, F
	movfw wavesidetone_counter_setting
	subwf wavesidetone_counter, W
	btfss STATUS, Z
	goto wavesidetone_not_equal
	btfss wavesidetone					; see what state we are in and toggle it
	goto on_and_reset_wavesidetone_ctr	; wavesidetone is off right now, jump up and set it
	nop
	bcf wavesidetone					; wavesidetone is on right now, turn it off
	goto reset_wavesidetone_counter		; jump ahead and reset counter

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -