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

📄 keyer-3.0.18.asm

📁 PIC16F628A制作的自动键程序,供无线电爱好者参考.
💻 ASM
📖 第 1 页 / 共 5 页
字号:
on_and_reset_wavesidetone_ctr
	bsf wavesidetone					; turn on wavesidetone line
reset_wavesidetone_counter
	clrf wavesidetone_counter
	goto end_of_wavesidetone			;-------------------------------------------
wavesidetone_off
	bcf wavesidetone
	nop									; time padding with nops
	nop									; this evens things out so each run through this
	nop									;    soubroutine should be the same amount of time
	nop									;    regardless of the state or branches
	nop
wavesidetone_not_equal
	nop
	nop
	nop
	nop
	nop
	nop
	nop
end_of_wavesidetone

	return


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

loop_cw_unit

	; this subroutine loops for one CW unit (i.e. a dit)
	; if the sidetone line has been set high it will produce a square wave sidetone signal on the wavesidetone line
	; during the looping, the dit and dah paddles are checked and dit_buffer and dah_buffer set if either are pressed
	; this enables dit and dah insertion for iambic operation

	; initialize counters with calculated values
	movfw cw_unit_counter+0
	movwf counter1	;MSB
	movfw cw_unit_counter+1
	movwf counter2	;LSB
	
	ifdef include_paddle_reverse_code
	btfsc paddle_reverse				; are we in reverse paddle mode?
	goto loop_cw_unit_reverse_paddle	; yes, go to subroutine for reverse paddle mode
	endif

loop_de_loop_init
	movlw d'3'
	movwf counter3

loop_de_loop

	btfss sending_dit				; skip next line if we are sending dit
	goto check_for_dit				; if we are sending dit, check dah paddle
	btfss dah						; check the dah paddle, if = 1, skip over next line
	bsf dah_buffer					; dah is keyed, set buffer
	goto skip_over_check_for_dit	; skip over check_for_dit
	
check_for_dit						; we're sending a dah, check the dit paddle
	btfss dit						; if dit is not keyed, skip over next line
	bsf dit_buffer					; set the dit buffer
	nop
skip_over_check_for_dit

	call produce_wavesidetone

	decfsz counter3,F
	goto loop_de_loop
	decfsz counter2, F
	goto loop_de_loop_init
	decfsz counter1, F
	goto loop_de_loop_init
	
		
	return


	ifdef include_paddle_reverse_code

loop_cw_unit_reverse_paddle
	
loop_de_loop_init_rev
	movlw d'3'
	movwf counter3
loop_de_loop_rev
	btfss sending_dit		; skip next line if we are sending dit
	goto check_for_dit_rev		; if we are sending dit, check dah paddle
	btfss dit				; check the dit paddle, if = 1, skip over next line
	bsf dah_buffer			; dah is keyed, set buffer
	goto skip_over_check_for_dit_rev			; skip over check_for_dit
	
check_for_dit_rev				; we're sending a dah, check the dit paddle
	btfss dah				; if dah is not keyed, skip over next line
	bsf dit_buffer			; set the dit buffer
	nop
skip_over_check_for_dit_rev

	call produce_wavesidetone

	decfsz counter3,F
	goto loop_de_loop_rev
	decfsz counter2, F
	goto loop_de_loop_init_rev
	decfsz counter1, F
	goto loop_de_loop_init_rev
		
	return

	endif ;include_reverse_paddle_code

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

loop_6_cw_units
	call loop_cw_unit
	call loop_cw_unit
	call loop_cw_unit
	call loop_cw_unit	
	call loop_cw_unit
	call loop_cw_unit
	return
	
; ------------------


send_dit_or_dah

	; send a dit or dah
	; parms:
	;
	;	sending_dit
	;		1 = send dit
	;		0 = send dah
	;	key_tx_active
	;		1 = key tx line
	;		0 = do not key tx line
	;
	; notes:
	;
	;	- sidetone line is always keyed (unless sidetone_off_during_tx is true and key_tx_active is true)

	ifdef include_toggle_sidetone_on_off_code
	btfsc sidetone_off_during_tx
	btfss key_tx_active
	endif
	bsf sidetone		; turn on sidetone
	btfsc key_tx_active	; if key_tx is clear, jump - don't key tx line
	bsf key				; key tx line
	btfss sending_dit	; are we sending a dit ?
	goto send_a_dah		; if not, jump to send_a_dah
	call loop_cw_unit	; loop for one unit, a dit
	goto clear_lines	; get out and clear all the lines
	
send_a_dah

	ifdef include_weighting_code
	movfw cw_unit_counter+1			; store the regular counter values
	movwf cw_unit_counter_dit+1	
	movfw cw_unit_counter+0
	movwf cw_unit_counter_dit+0
	movfw cw_unit_counter_dah+1		; switch in the dah values for weighting
	movwf cw_unit_counter+1
	movfw cw_unit_counter_dah+0
	movwf cw_unit_counter+0
	endif ;include_weighting_code
	
	call loop_cw_unit	; key for three lengths (dah)
	call loop_cw_unit
	call loop_cw_unit	
	
	ifdef include_weighting_code
	movfw cw_unit_counter_dit+1		; put regular counter values back
	movwf cw_unit_counter+1
	movfw cw_unit_counter_dit+0
	movwf cw_unit_counter+0		
	endif ;include_weighting_code
	
clear_lines
	bcf sidetone	; deactivate sidetone
	bcf key			; deactivate key line
	call loop_cw_unit	; loop while unkeyed for inter-cw_unit spacing

	ifdef include_nnnnn_code			; this code blows, so I keep it turned off.
										; only use if you're too cheap to buy a mode switch
	; keep a history of dits and dahs
	;   history is stored in a word consisting of ditdah_history1 and 2
	;   each bit is one cw_unit : 0 = dit, 1 = dah
	;                                     m             l     m             l
	;                                     s             s     s             s
	;                                     b             b     b             b     
	;   cw_units are pushed like this --> ditdah_history1 --> ditdah_history2
	btfss key_tx_active		; are we actually keying the tx ?
	return					; if not, blow out and do not add to history
	bsf STATUS, C			; set the carry bit, 1 = dah
	btfsc sending_dit		; did we just send a dit ?
	bcf STATUS, C			; if so, clear the carry bit, 0 = dit
	rrf ditdah_history1, F	; place bit into history register
	rrf ditdah_history2, F	; carry over into the second byte
	movlw 0xff
	movwf ditdah_history_timer1
	endif ;include_nnnnn_code
	
	return


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

	ifdef include_freq_counter_code

store_freq_offset_in_eeprom

	errorlevel -302
	movlw eeprom_freq_offset_high
	banksel EEADR
	movwf EEADR
	banksel freq_offset_binary
	movfw freq_offset_binary+0
	banksel EEDATA
	movwf EEDATA
	banksel PORTA
	call write_eeprom

	movlw eeprom_freq_offset_low
	banksel EEADR
	movwf EEADR
	banksel freq_offset_binary
	movfw freq_offset_binary+1
	banksel EEDATA
	movwf EEDATA
	banksel PORTA
	call write_eeprom

	return

	errorlevel +302

	endif ;include_freq_counter_code

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

initialize_eeprom_first_time

	errorlevel -302
	movlw eeprom_addr_speed_wpm		; address 0x00 last wpm speed
	banksel EEADR
	movwf EEADR
	movlw initial_speed_wpm
	banksel EEDATA
	movwf EEDATA
	banksel PORTA
	call write_eeprom
	
	
	; write wavesidetone freq to eeprom
	movlw eeprom_wavesidetone_setting
	banksel EEADR
	movwf EEADR
	movlw _initial_wavesidetone_setting
	banksel EEDATA
	movwf EEDATA
	banksel PORTA
	call write_eeprom

	;clean out memory locations
	movlw eeprom_memory_location_0
	banksel EEADR
	movwf EEADR
	movlw 0xff
	banksel EEDATA
	movwf EEDATA
	banksel PORTA
	call write_eeprom
	movlw eeprom_memory_location_1
	banksel EEADR
	movwf EEADR
	banksel PORTA
	call write_eeprom
	movlw eeprom_memory_location_2
	banksel EEADR
	movwf EEADR
	banksel PORTA
	call write_eeprom
	errorlevel +302

	ifdef include_freq_counter_code
	
	errorlevel -302
	movlw eeprom_freq_calib_high
	banksel EEADR
	movwf EEADR
	movlw high _frequency_counter_calib
	banksel EEDATA
	movwf EEDATA
	banksel PORTA
	call write_eeprom

	movlw eeprom_freq_calib_low
	banksel EEADR
	movwf EEADR
	movlw low _frequency_counter_calib
	banksel EEDATA
	movwf EEDATA
	banksel PORTA
	call write_eeprom

	call store_freq_offset_in_eeprom

	errorlevel +302

	endif ;include_freq_counter_code


	; clear eeprom_settings1 location
	clrf eeprom_settings1
	call write_eeprom_settings1
	
	ifndef exclude_delays_debug
	ifdef include_funky_beeps_code
	call beep_boop
	call beep_boop
	call beep_boop
	endif ;include_funky_beeps_code
	endif ;exclude_delays_debug

	banksel PORTA

	return

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

write_eeprom_settings1

	errorlevel -302
	movlw eeprom_settings1_location
	banksel EEADR
	movwf EEADR
	banksel eeprom_settings1
	movfw eeprom_settings1
	banksel EEDATA
	movwf EEDATA
	banksel PORTA
	call write_eeprom
	errorlevel +302

	banksel PORTA

	return

; ------------------
	
initialize

	ifndef exclude_delays_debug
	movlw d'2'			; pause to make sure everything is settled down on power up
	call pause_w_100ms
	endif ;exclude_delays_debug

	;bcf OPTION_REG,NOT_RBPU

	errorlevel -302
	ifndef processor_low_end
	banksel CMCON
	movlw 0x07			; setup Port A for I/O, not comparator mode
	movwf CMCON
	endif ;processor_low_end
	errorlevel +302

	; initialize IO Ports
	errorlevel -302
	banksel TRISA
	movlw B'00010111'
	movwf TRISA
	movlw B'00001101'	; 1 = input, 0 = output
	movwf TRISB
	errorlevel -302
	banksel PORTA
	bcf dit_buffer
	bcf dah_buffer
	bcf key
	bcf sidetone
	ifdef include_txwake_line_code
	bcf txwake
	endif
	bsf key_tx_active
	
	ifdef include_nnnnn_code
	clrf ditdah_history1
	clrf ditdah_history2
	endif

	; see if eeprom has been written to before
	movlw 0x00
	errorlevel -302
	banksel EEADR
	movwf EEADR
	banksel EECON1
	bsf EECON1, RD		; read address 0x00
	banksel EEDATA
	btfsc EEDATA,0x07					; is bit 7 set high ?
	call initialize_eeprom_first_time	; if so, we got a new chip here
	banksel PORTA
	errorlevel +302	

	; read the last wpm stored in eeprom
	movlw eeprom_addr_speed_wpm
	call read_eeprom
	movwf speed_wpm
	ifdef include_weighting_code
	movwf speed_wpm_dah
	endif
	
	call calculate_cw_unit_values

	; setup eeprom memory locations
	movlw eeprom_memory_location_0
	movwf eeprom_memory_locations+0
	movlw eeprom_memory_location_1
	movwf eeprom_memory_locations+1
	movlw eeprom_memory_location_2
	movwf eeprom_memory_locations+2

	movlw eeprom_memory_loc_0_cw_units
	movwf eeprom_memory_loc_limits+0
	movlw eeprom_memory_loc_1_cw_units
	movwf eeprom_memory_loc_limits+1
	movlw eeprom_memory_loc_2_cw_units
	movwf eeprom_memory_loc_limits+2

	;read eeprom_settings1 from eeprom
	movlw eeprom_settings1_location
	call read_eeprom
	movwf eeprom_settings1

	movlw eeprom_wavesidetone_setting
	call read_eeprom
	movwf wavesidetone_counter_setting
	clrf wavesidetone_counter

	ifdef include_interrupt_code
	; set up interrupt stuff
	errorlevel -302
	banksel OPTION_REG
	bcf OPTION_REG, T0CS	; TIMER0 clock source set to internal clock (clock / 4)
	bcf OPTION_REG, PSA		; assign prescaler to TIMER0 clock
	bsf OPTION_REG, PS0		; set TIMER0 prescaler to 111 ( / 256 )
	bsf OPTION_REG, PS1
	bsf OPTION_REG, PS2
	banksel TMR0
	movlw d'150'
	movwf TMR0
	banksel INTCON
	bsf INTCON, T0IE		; enable TIMER0 overflow interrupt
	bsf INTCON, GIE			; enable interrupts
	errorlevel -302
	banksel PORTA
	endif

	ifdef include_cw_rx_practice_code
	movlw 0x30				; seed random number generator
	movwf randomnum+0
	movlw 0x45
	movwf randomnum+1
	endif


	ifdef include_freq_counter_code
	movlw eeprom_freq_calib_high
	call read_eeprom
	movwf frequency_counter_calib+0
	movlw eeprom_freq_calib_low
	call read_eeprom
	movwf frequency_counter_calib+1

	; read freq_offset from EEPROM
	movlw eeprom_freq_offset_high
	call read_eeprom
	movwf freq_offset_binary+0
	movlw eeprom_freq_offset_low
	call read_eeprom
	movwf freq_offset_binary+1

	endif ;include_freq_counter_code



	ifdef include_serial_port_rx_code
	errorlevel -302
	banksel TRISB
	bsf TRISB,0x01		; make RB1 an input 
	banksel TXSTA
;    bsf TXSTA,BRGH		; high speed bit generator
    bcf TXSTA,BRGH		; low speed bit generator
	movlw d'25'			; 9600 baud with 4Mhz clock / 2400 with low speed bit generator
	banksel SPBRG
	movwf SPBRG
	banksel TXSTA
	bcf TXSTA,SYNC		; asyncronous mode
	;bcf STATUS,RP0		; select bank 0
	banksel RCSTA
	bsf RCSTA,SPEN
	bsf RCSTA,CREN		; enable serial receive
read_rx_fifo_loop
	call pause_100_ms
	banksel PIR1
	btfss PIR1,RCIF		; do we have something in the buffer?
	goto read_rx_fifo_loop_exit				; no, blow out of here
	banksel RCREG
	movfw RCREG			; pull byte out of the serial rx FIFO
	goto read_rx_fifo_loop
read_rx_fifo_loop_exit
	errorlevel +302

⌨️ 快捷键说明

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