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

📄 keyer-3.0.18.asm

📁 PIC16F628A制作的自动键程序,供无线电爱好者参考.
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	endif ;include_serial_port_code
	
	banksel PORTA
	
	bcf send_cw_preemptible
	bcf squeeze_detected

	retlw	0

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


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

	ifdef include_serial_cw_keyboard

check_serial_cw_keyboard
	btfsc PIR1,OERR		; did we overrun the buffer?
	goto handle_overrun
	btfsc PIR1,FERR		; did we have a frame error?
	goto handle_frame_error
	btfss PIR1,RCIF		; do we have something in the buffer?
	return				; no, blow out of here
	movfw RCREG			; pull byte out of the serial rx FIFO

	ifdef include_serial_rx_debug_code
	; debug code - send received byte in decimal CW
	movwf binary2bcd_binary_in+1
	clrf binary2bcd_binary_in+0
	call binary2bcd
	call rotate_BCD012_left
	call rotate_BCD012_left
	call send_BCD2_in_cw
	call rotate_BCD012_left
	call rotate_BCD012_left
	call send_BCD2_in_cw
	call rotate_BCD012_left
	call rotate_BCD012_left
	call send_BCD2_in_cw
	return
	else

	sublw d'49'					; convert ascii code to cw table lookup 0-9
	movwf temp_memory			; double it
	addwf temp_memory, F
	movfw temp_memory
	call cw_table				; get the first byte of code
	movwf cw_char_to_send+0
	movfw temp_memory
	addlw 0x01					; increment it to get the next byte
	call cw_table
	movwf cw_char_to_send+1
	errorlevel -306
	pagesel send_cw
	call send_cw
	errorlevel +306
	return
	
	endif ;include_serial_rx_debug_code

handle_overrun
	movfw RCREG
	ifdef include_debug_code
	call low_beep
	endif
	return

handle_frame_error
	bcf RCSTA,CREN
	bsf RCSTA,CREN
	ifdef include_debug_code
	call low_beep
	endif
	return


	endif ;include_serial_port_rx_code

; ------------------
	
check_straight_key_mode

	; this checks if the dah paddle is keyed or mode button is pressed, if so, we loop in straight key mode forever
	btfss mode_switch 
	goto go_into_straight_key_mode
	btfsc dah  	; if dah = 0 go to straight_key_loop
	retlw 0		;   otherwise, return
go_into_straight_key_mode
	bsf sending_dit
	movlw d'60'
	movwf speed_wpm
	call calculate_cw_unit_values
	
	ifdef include_txwake_line_code	
	bcf txwake
	endif ;include_txwake_line_code

straight_key_loop		
	call loop_cw_unit
	btfss mode_switch
	goto key_on
	btfsc dit   		; if dit = 0 jump to key_on
	goto key_off		; else go to key_off
key_on
	ifdef include_txwake_line_code
	;call reset_txwake_timer
	movlw HIGH _txwake_delay_time_straight_key
	movwf txwakecounter+0
	movlw LOW _txwake_delay_time_straight_key
	movwf txwakecounter+1
	bsf txwake
	endif
	bsf key				; key the TX
	ifdef include_toggle_sidetone_on_off_code
	btfss sidetone_off_during_tx
	endif ;include_toggle_sidetone_on_off_code
	bsf sidetone		; key the sidetone
	goto straight_key_loop
key_off
	ifdef include_txwake_line_code
	bcf dit_buffer
	bcf dah_buffer
	pagesel check_txwake_clear_time
	errorlevel -306
	call check_txwake_clear_time
	errorlevel +306
	endif
	bcf key			; unkey the TX
	bcf sidetone	; unkey the sidetone
	goto straight_key_loop			
	
	retlw 0

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

send_buffer

	btfss dit_buffer	; if dit_buffer is set, skip next line
	goto check_dah_buffer
	ifdef include_txwake_line_code
	bsf txwake
	endif
	bcf dit_buffer
	bsf sending_dit
	call send_dit_or_dah

	ifdef include_iambic_mode_code
    btfsc iambic_b_mode
    goto check_dah_buffer
	btfss squeeze_detected
    goto check_dah_buffer
	btfss dit
	goto check_dah_buffer
	btfss dah
	goto check_dah_buffer
	bcf squeeze_detected
	bcf dit_buffer
	bcf dah_buffer
	endif ;include_iambic_mode_code

	
check_dah_buffer
	btfss dah_buffer	; if dah_buffer is set, skip next line
	return
	ifdef include_txwake_line_code
	bsf txwake
	endif
	bcf dah_buffer
	bcf sending_dit

	ifdef include_bug_code		; HACK ALERT: special hack to accomodate bug mode
	btfss bug_mode_on
	goto no_bug_mode
	movfw speed_wpm				; temporarily store the current wpm
	movwf temp_memory
	movlw d'60'					; jack up the wpm to 60 so loop is responsive
	movwf speed_wpm
	call calculate_cw_unit_values
	bsf sending_dit
bug_loop
	ifdef include_toggle_sidetone_on_off_code
	btfss sidetone_off_during_tx
	endif ;include_toggle_sidetone_on_off_code
	bsf sidetone
	bsf key
	call loop_cw_unit
	btfss dah
	goto bug_loop				; loop as long as dah is on
	bcf sidetone
	bcf key	
	movfw temp_memory			; restore original wpm
	movwf speed_wpm
	call calculate_cw_unit_values
	bcf dah_buffer
	return
no_bug_mode
	endif ;include_bug_code
	
	call send_dit_or_dah

	ifdef include_iambic_mode_code
    btfsc iambic_b_mode
    return
	btfss squeeze_detected
    return
	btfss dit
	return
	btfss dah
	return
	bcf squeeze_detected
	bcf dit_buffer
	bcf dah_buffer
	endif ;include_iambic_mode_code


	return
; ------------------

decrement_wpm
	
	movfw speed_wpm
	sublw d'4'			; 5 wpm lower limit
	btfsc STATUS, C		;if 4 - speed_wpm > 0, return and do not decrement
	return
	decf speed_wpm, F
	ifdef include_weighting_code
	decf speed_wpm_dah, F
	endif
	call calculate_cw_unit_values
	return

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

increment_wpm

	movfw speed_wpm
	sublw maxcwspeed	; max wpm upper limit
	btfss STATUS, C		;if maxcwspeed - speed_wpm < 0, return and do not increment
	return
	incf speed_wpm, F
	ifdef include_weighting_code
	incf speed_wpm_dah, F
	endif
	call calculate_cw_unit_values
	return

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

send_cw

	; sends two bytes of CW
	; parms:
	;	cw_char_to_send:2

	; 00 = terminator = end of character or string, return
	; 01 = dit
	; 11 = dah
	; 10 = intercharacter spacing - pause for two more cw_units lengths and go on
	
	; cw_char_to_send+0 is sent first, cw_char_to_send+1 is sent second; MSB is the first sent

	movlw cw_char_to_send-1	; setup pointer, set to first byte - 1
	movwf FSR
	movlw 0x02				; loop through twice
	movwf count

loop_initialize
	incf FSR, F
	movlw b'11000000'		; initialize send_cw_temp
	movwf send_cw_temp

cw_byte_decode

	btfss send_cw_preemptible
	goto no_send_cw_preemptible
	call check_for_button_hit		; see if a button was hit for us to exit out
	sublw 0x01
	btfsc STATUS,Z
	goto send_cw_button_hit_loop
no_send_cw_preemptible
	movfw send_cw_temp
	movwf temp				;make a copy of send_cw_temp
	movfw INDF
	andwf send_cw_temp, W
	btfsc STATUS, Z			; if 0, we have a terminator, exit
	goto loop_2_cw_units_and_exit
	subwf send_cw_temp, W
	btfsc STATUS, Z ; if 0, we have a dah
	goto send_cw_dah_byte
	; check for 10
	movlw b'10101010'	; create a bit mask 
	andwf temp, F		; and it with the temp register so we get 10 in the right position
	movfw INDF		; get a fresh byte of cw again
	subwf temp, W		; subtract
	btfsc STATUS, Z		; if we have zero, this is 10 - an intercharacter space
	goto loop_two_cw_units ; zero set = 10 
	bsf sending_dit		; zero not set = 01 - send a dit
	call send_dit_or_dah
	goto cw_byte_decode_next
send_cw_dah_byte
	bcf sending_dit
	call send_dit_or_dah	
cw_byte_decode_next		; get things ready to read the next two bits to the right
	bcf STATUS, C		; rotate bits to the right twice
	rrf send_cw_temp, F		; to select the next two bits
	rrf send_cw_temp, F
	btfss STATUS, C		; if a bit gets into carry flag, we're at zero and we're done
	goto cw_byte_decode	; otherwise, go back for more with this byte
	decf count, F		; we're done with this byte, decrement the count
	btfss STATUS, Z		; did count hit zero ?
	goto loop_initialize
	
loop_2_cw_units_and_exit
	; loop two cw_units lengths so we have proper inter character spacing
	call loop_cw_unit
	call loop_cw_unit
	
	return
	
loop_two_cw_units
	call loop_cw_unit
	call loop_cw_unit
	goto cw_byte_decode_next


send_cw_button_hit_loop
	call loop_check_for_button_hit
	ifdef include_function_button_code
	bsf memory_playback_manual_exit
	endif
	return

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

send_BCD2_in_cw

	swapf BCD2,F			; send upper nibble
	movfw BCD2
	andlw b'00001111'
	call send_w_BCD_in_cw
	swapf BCD2,F			; send lower nibble
	movfw BCD2
	andlw b'00001111'
	call send_w_BCD_in_cw
	
	return
	
;-------------

announce_speed_wpm

	; convert speed_wpm to BCD
	movlw 0x00
	movwf binary2bcd_binary_in+0
	movfw speed_wpm
	movwf binary2bcd_binary_in+1
	call binary2bcd

	call send_BCD2_in_cw

	return

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

speed_mode

	; this mode allows you to change the sending speed
	; dit paddle speeds up
	; dah paddle slows down
	; mode button or paddle squeeze exits
	

	bsf sending_dit

	movlw 0x04
	call pause_w_100ms	
	
dit_loop
	call send_dit_or_dah	; sound a dit
	
	btfss dit				; dit is pressed, dah is not
	btfss dah
	goto skip_increment_wpm
	call increment_wpm
	goto dit_loop
skip_increment_wpm
	btfss dah				; dah is pressed, dit is not
	btfss dit
	goto skip_decrement_wpm
	call decrement_wpm
	goto dit_loop
skip_decrement_wpm
	
	btfss mode_switch		; if switch is pressed, get out of loop
	goto loop_while_pressed2
	btfss dit				; if both paddles are pressed, this also exits
	btfsc dah
	goto dit_loop
	
loop_while_pressed2			; wait for mode_switch, dit and dah to be released
	call pause_100_ms
	btfss mode_switch
	goto loop_while_pressed2
	btfss dit
	goto loop_while_pressed2
	btfss dah
	goto loop_while_pressed2

	movlw 0x05
	call pause_w_100ms

	call write_speed_wpm_to_eeprom

	movlw 0x05
	call pause_w_100ms	

	bcf dit_buffer
	bcf dah_buffer
	
	return

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


write_speed_wpm_to_eeprom

	movlw eeprom_addr_speed_wpm
	errorlevel -302
	banksel EEADR
	movwf EEADR
	banksel speed_wpm
	movfw speed_wpm
	banksel EEDATA
	movwf EEDATA
	errorlevel +302
	banksel PORTA
	
	call write_eeprom

	return

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

	
	ifdef include_tune_mode_code

tune_mode

	; this mode is used for tuning up a rig
	; left paddle intermittently turns on TX
	; right paddle latches TX
	; mode switch or paddle squeeze exits

	bcf tune_latch_mode
	movlw 0x02
	call pause_w_100ms
	bsf sending_dit
	call send_dit_or_dah
	movfw speed_wpm		; temporarily store the current wpm
	movwf temp_memory
	movlw d'60'			; jack up the wpm to 60 so loop is responsive
	movwf speed_wpm
	call calculate_cw_unit_values

tune_mode_loop
	
	call loop_cw_unit
	btfss dit				; is dit pressed ?
	goto tune_dit_pressed	; if so, go to tune_dit_pressed
	btfss dah				; is dah pressed ?
	goto tune_dah_pressed	; if so, go to tune_dah_pressed
	btfsc tune_latch_mode	; are we in latch mode ?
	goto tune_mode_check_for_exit	; if so jump over
	bcf key					; we're not in latch mode and dit is not pressed
	bcf sidetone			;  so clear key and sidetone
	ifdef include_txwake_line_code
	bcf txwake
	endif
	
tune_mode_check_for_exit
	btfss mode_switch		; if switch is pressed, get out of loop
	goto tune_mode_loop_while_pressed
	btfss dit				; if both paddles are pressed, this also exits
	btfsc dah
	goto tune_mode_loop
	
tune_mode_loop_while_pressed			; wait for mode_switch, dit and dah to be released


	bcf key						
	bcf sidetone
	ifdef include_txwake_line_code
	bcf txwake
	endif

	call pause_100_ms
	btfss mode_switch
	goto tune_mode_loop_while_pressed
	btfss dit
	goto tune_mode_loop_while_pressed
	btfss dah
	goto tune_mode_loop_while_pressed



	movfw temp_memory			; restore original wpm
	movwf speed_wpm
	call calculate_cw_unit_values

⌨️ 快捷键说明

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