📄 keyer-3.0.18.asm
字号:
; Keyer 3.0.18
; Goody K3NG
; Contributions and updates from W0ANM
; 2004.04.01
; This is a PIC based keyer. Currently supported devices are the 16F628, 16F628A, and 16F648A. This will compile for the
; 16F84 and 16F84A, however I don't test these anymore. The 16F628 doesn't cost much more, switch over to it! :-)
;
; http://www.qrpis.org
; goody @ qrpis . org
; TODO - code practice, random callsigns
; TODO - configurable memory repeat delay and store in eeprom
; TODO - RX mute line (use TX wake line)
; TODO - LCD Support
; TODO - DDS Support
; TODO - Configurable beacon sleep time
; TODO - include_beacon_fox_message
; ************************************** user configurable stuff **********************************************
; processor definition - uncomment one and be sure to set your compiler for the right proc
;#define processor_16f84
;#define processor_16f84a
;#define processor_16f628
;#define processor_16f628a
#define processor_16f648a
; ***************************
; * code inclusion *
; ***************************
; comment out these to reduce the code size or change features
; note that some modules of code depend on others; read the notes
; bytes last updated 2004-09-18
; The Main Stuff
#define include_wavesidetone_code ; cost: ? bytes - additional support of wavesidetone
;#define include_function_button_code ; cost: 160 bytes (includes some dependent code); support for buttons other than mode
;#define include_toggle_sidetone_on_off_code ; cost: 18 bytes - code to turn off sidetone during TX
;#define include_mode_button_hold_code ; cost: 43 bytes - code for mode button hold shortcuts (programming memories, quick speed adj)
#define include_funky_beeps_code ; cost: 17 bytes - code for high and low beeps using wave sidetone; not applicable if using externally keyed sidetone oscillator (requires wavesidetone_code)
;#define include_m_and_h_cmd_code ; cost: 86 bytes - command modes M and H: program and playback memories in command mode
;#define include_eis_mh_cmd_code ; instead of 0,1,2 for memory select, it's e,i,s
; Frequency Counter Code
;#define include_freq_counter_code ; cost: 502 bytes - base frequency counter code
;#define include_freq_counter_button_code ; cost: 24 bytes - support for frequency counter button (requires freq_counter_code, function_button_code)
;#define include_freq_counter_calib_code ; cost: 56 bytes - code for frequency calibration mode, command L (reqs freq_counter_code, function_button_code)
; Optional Features
;#define include_iambic_mode_code ; cost: 16 bytes - support for iambic a mode
;#define include_bug_code ; cost: 33 bytes - bug paddle mode
;#define include_call_cq_code ; cost: 55 bytes - call cq mode
;#define include_beacon_code ; cost: 60 bytes - beacon mode support
;#define include_nnnnn_code ; cost: 23 bytes - this code allows you to go into command mode after five consecutive Ns are sent
;#define include_txwake_line_code ; cost: ? bytes - code for TX_WAKE line
;#define include_tune_mode_code ; cost: 70 bytes - code for tune mode
;#define include_weighting_code ; cost: 77 bytes - command mode W: dah weighting
;#define include_paddle_reverse_code ; cost: 39 bytes - command mode R: reverse paddles
;#define include_needless_feature_code ; cost: 31 bytes - unimportant stuff
;#define include_say_hi_code ; cost: ? bytes - say hi at startup
;#define include_calibration_code ; cost: 34 bytes - this adds another command mode for calibrating the speed counters
;#define include_cw_rx_practice_code ; cost: 113 bytes - command mode P: random five letter group code practice
;#define include_cw_tx_practice_code ; cost: 25 bytes - command mode Q: send code without transmitting
; Experimental / Under Construction
;#define include_9850_dds_code ; experimental / under construction
;#define include_serial_cw_keyboard ; experimental
;#define include_beacon_serial_ctrl_code ; cost: ? bytes - control the beacon using a serial port
;#define include_fox_code ; under construction
; Debug code - turn all of these off for production chips
;#define include_debug_code ; misc debug code - comment out for production chips
;#define include_serial_rx_debug_code
;#define exclude_delays_debug
; *********************************************
; * dependencies - do not change this section *
; *********************************************
; include_serial_port_rx_code required by include_beacon_serial_ctrl_code, include_serial_cw_keyboard
ifdef include_beacon_serial_ctrl_code
#define include_serial_port_rx_code
endif
ifdef include_serial_cw_keyboard
ifndef include_serial_port_rx_code
#define include_serial_port_rx_code
endif
endif
; include_cw_table_long required by include_serial_port_rx_code, include_cw_rx_practice_code
ifdef include_serial_port_rx_code
#define include_cw_table_long
endif
ifdef include_cw_rx_practice_code
ifndef include_cw_table_long
#define include_cw_table_long
endif
endif
; include_rotateBCD012_left required by include_serial_port_rx_code, include_freq_counter_code
ifdef include_serial_port_rx_code
#define include_rotateBCD012_left
endif
ifdef include_freq_counter_code
ifndef include_rotateBCD012_left
#define include_rotateBCD012_left
endif
endif
; ***************************
; * options *
; ***************************
#define _4_mhz_clock
; aliases for pins
#define mode_switch PORTB,0x00 ; momentary switch
; PORTB,0x01 ; Serial Port RX
#define dit PORTB,0x02 ; dit of paddle
#define dah PORTB,0x03 ; dah of paddle
ifndef include_wavesidetone_code
#define sidetone PORTB,0x04 ; keys external sidetone oscillator
else
#define wavesidetone PORTB,0x04 ; square wave sidetone output
endif
#define key PORTB,0x05 ; transmitter cw key
ifdef include_txwake_line_code
#define txwake PORTB,0x06 ; goes high to turn on TX if used as FM CW unit, or T/R relay
endif
ifdef include_function_button_code
#define switch0 PORTA,0x00
#define switch1 PORTA,0x01
#define switch2 PORTA,0x02
endif
#define initial_speed_wpm d'20' ; this is the default wpm speed when the cw_unit it first powered up
#define maxcwspeed d'40' ; this is the max speed
#define initial_memory_repeat_delay d'35' ; this time in between repeating a memory in units of 100mS
; *************** don't adjust anything below this line unless you know what the hell you are doing *************
; eeprom addresses - this defines eeprom memory locations
#define eeprom_addr_speed_wpm 0x00 ; CW speed in binary format
#define eeprom_wavesidetone_setting 0x01 ; sidetone frequency setting
#define eeprom_settings1_location 0x02 ; various user settings, register eeprom_settings1
#define eeprom_freq_calib_high 0x03 ; frequency counter calibration, high byte
#define eeprom_freq_calib_low 0x04 ; frequency counter calibration, low byte
#define eeprom_freq_offset_high 0x05 ; frequency counter offset, lower nibble is BCD2
#define eeprom_freq_offset_low 0x06 ; frequency counter offset, upper nibble is BCD1, lower nibble is BCD0
#define eeprom_memory_location_0 0x07 ; cw memory 0 ( callsign )
#define eeprom_memory_loc_0_cw_units d'28'
; first byte in memory location is a count of cw units stored in that memory
; the remaining bytes are the stored cw units
; a cw unit is two bits and is read MSB to LSB
ifdef processor_16f84
#define eeprom_memory_location_1 0x0F ; cw memory 1
#define eeprom_memory_location_2 0x28 ; cw memory 2
#define eeprom_memory_loc_1_cw_units d'96' ; four cw units can be stored per byte
#define eeprom_memory_loc_2_cw_units d'92'
#define processor_low_end
endif ;processor_16f84
ifdef processor_16f84a
#define eeprom_memory_location_1 0x0F ; cw memory 1
#define eeprom_memory_location_2 0x28 ; cw memory 2
#define eeprom_memory_loc_1_cw_units d'96' ; four cw units can be stored per byte
#define eeprom_memory_loc_2_cw_units d'92'
#define processor_low_end
endif ;processor_16f84a
ifdef processor_16f628
#define eeprom_memory_location_1 0x0F ; cw memory 1
#define eeprom_memory_location_2 0x48 ; cw memory 2
#define eeprom_memory_loc_1_cw_units d'224'
#define eeprom_memory_loc_2_cw_units d'220'
endif ;processor_16f628
ifdef processor_16f628a
#define eeprom_memory_location_1 0x0F ; cw memory 1
#define eeprom_memory_location_2 0x48 ; cw memory 2 ( = eeprom_memory_location_1 + (eeprom_memory_loc_1_cw_units / 4) + 1 )
#define eeprom_memory_loc_1_cw_units d'224'
#define eeprom_memory_loc_2_cw_units d'220'
endif ;processor_16f628a
ifdef processor_16f648a
#define eeprom_memory_location_1 0x0F ; cw memory 1
#define eeprom_memory_location_2 0x48 ; cw memory 2
#define eeprom_memory_loc_1_cw_units d'224'
#define eeprom_memory_loc_2_cw_units d'220'
endif ;processor_16f648a
; timing calibrations - these must be adjusted for clock speed
ifdef _4_mhz_clock
#define _100ms_counter1_calibration 0xff
#define _100ms_counter2_calibration 0x78
#define _100ms_counter3_calibration 0x01
#define _cw_unit_wpm_factor d'20000' ; this adjustment control the time length of one CW unit ( a dit )
#define _beep_length d'20'
#define _high_beep_tone d'20'
#define _low_beep_tone d'55'
#define _initial_wavesidetone_setting d'34' ; this is the default wavesidetone frequency (600Hz)
#define _frequency_counter_calib d'48900' ; higher = shorter sampling duration (1/4 second)
; delay = 15 * 1uS * (65535 - _frequency_counter_calib)
#define _txwake_delay_time d'30000'
#define _txwake_delay_time_straight_key d'400'
endif ;_4_mhz_clock
; processor declarations
ifdef processor_16f84
processor 16f84
include <p16f84.inc>
__config _HS_OSC & _WDT_OFF
#define cblock_start 0x0c
errorlevel -312 ; turn off nagging about device not needing page selection
endif ;processor_16f84
ifdef processor_16f84a
processor 16f84a
include <p16f84a.inc>
__config _HS_OSC & _WDT_OFF
#define cblock_start 0x0c
errorlevel -312 ; turn off nagging about device not needing page selection
endif ;processor_16f84a
ifdef processor_16f628
processor 16f628
include <p16f628.inc>
__config _HS_OSC & _WDT_OFF & _LVP_OFF & _BODEN_OFF
#define cblock_start 0x20
errorlevel -312 ; turn off nagging about device not needing page selection
endif ;processor_16f628
ifdef processor_16f628a
processor 16f628a
include <p16f628a.inc>
__config _HS_OSC & _WDT_OFF & _LVP_OFF & _BODEN_OFF
#define cblock_start 0x20
errorlevel -312 ; turn off nagging about device not needing page selection
endif ;processor_16f628a
ifdef processor_16f648a
processor 16f648a
include <p16f648a.inc>
__config _HS_OSC & _WDT_OFF & _LVP_OFF & _BODEN_OFF
#define cblock_start 0x20
#define multi_memory_page_support
endif ;processor_16f648a
; define registers
cblock cblock_start
speed_wpm:1 ;global
bit_stuff1:1 ;global
bit_stuff2:1 ;global
bit_stuff3:1 ;global
cw_unit_counter:2 ;loop_cw_unit
counter1:1 ;pause_100_ms, loop_cw_unit
counter2:1 ;pause_100_ms, loop_cw_unit
counter3:1 ;pause_100_ms, send_cw
cw_char_to_send:2 ;send_cw(parm)
temp:1 ;send_cw
dividend:2 ;divideby16bit
divisor:2 ;divideby16bit
quotient:2 ;divideby16bit
remainder:2 ;divideby16bit
count:1 ;divideby16bit
binary2bcd_binary_in:2 ;binary2bcd
BCD0:1 ;binary2bcd
BCD1:1 ;binary2bcd
BCD2:1 ;binary2bcd
bcd_low_nibble:1 ;speed_mode
bcd_high_nibble:1 ;speed_mode
write_verify_data:1 ;write_eeprom
write_verify_addr:1 ;write_eeprom
command_mode_loop_count1:1 ; check_mode_button (enhanced)
command_mode_loop_count2:1 ; check_mode_button (enhanced)
command_mode_loop_count3:1 ; check_mode_button (enhanced)
command_mode_buffer1:1 ; check_mode_button (enhanced)
command_mode_buffer2:1 ; check_mode_button (enhanced)
recording_loop_counter1:1 ; program_memory
recording_loop_counter2:1 ; program_memory
cw_unit_count:1 ; program_memory
temp_memory:1 ; program_memory
temp_memory_eeprom_pointer:1 ;program_memory
temp_memory_mask:1 ; program_memory
temp_w:1 ; program_memory.store_temp_memory_to_eeprom
send_cw_temp:1 ; send_cw
memory_number:1 ; program_memory, play_memory
eeprom_memory_locations:3 ; program_memory, play_memory
eeprom_memory_loc_limits:3 ; program_memory
start_of_memory_location:1 ; program_memory, play_memory
porta_temp:1 ; check_function_buttons
eeprom_settings1:1
wavesidetone_counter
wavesidetone_counter_setting
endc
ifdef include_txwake_line_code
cblock
txwakecounter:2
endc
endif ;include_txwake_line_code
ifdef include_nnnnn_code
cblock
ditdah_history1:1 ; global - include_nnnnn_code
ditdah_history2:1 ; global - include_nnnnn_code
ditdah_history_timer1:1 ; global - include_nnnnn_code
endc
endif
ifdef include_weighting_code
cblock
cw_unit_counter_dah:2
cw_unit_counter_dit:2
speed_wpm_dah
endc
endif
ifdef include_cw_rx_practice_code
cblock
randomnum:2
endc
endif
ifdef include_freq_counter_code
cblock
freqcount:3
BCD3:1
frequency_counter_calib:2
freq_offset_binary:2
L_temp:1
H_temp:1
endc
bcd2binary_binary_out equ binary2bcd_binary_in
ifdef include_debug_code
bcd2binary_binary_out_2 equ binary2bcd_binary_in+1 ; for debugger work
freq_offset_binary_2 equ freq_offset_binary+1 ; for debugger work
endif ;include_debug_code
endif ;include_freq_counter_code
#define dit_buffer bit_stuff1,0x00 ; used to store a dit in iambic operation
#define dah_buffer bit_stuff1,0x01 ; used to store a dah
#define key_tx_active bit_stuff1,0x02 ; 0 = do not turn on key_tx line when sending cw
#define sending_dit bit_stuff1,0x03 ; 1 = send dit in send_dit_or_dah
ifdef include_tune_mode_code
#define tune_latch_mode bit_stuff1,0x04 ; 1 = tx is latched on
endif
#define temp_memory_dirty bit_stuff1,0x05 ; used by memory record functions
#define paddle_was_hit bit_stuff1,0x06
ifdef include_function_button_code
#define memory_playback_manual_exit bit_stuff1,0x07
endif
#define send_cw_preemptible bit_stuff2,0x00 ; send_cw routine can be interrupted by user when this flag is set
ifndef include_wavesidetone_code
#define wavesidetone bit_stuff2,0x01
else
#define sidetone bit_stuff2,0x01
endif
#define expert_commands_on bit_stuff2,0x02 ; 1 = expert commands have been activated in command mode
#define bit_temp bit_stuff2,0x03
ifdef include_freq_counter_code
#define command_mode_v_cmd bit_stuff2,0x04
#define command_mode_k_cmd bit_stuff2,0x05
endif
ifdef include_call_cq_code
#define dit_hit bit_stuff2,0x06
endif ;include_call_cq_code
ifdef include_m_and_h_cmd_code
#define command_mode_m_cmd bit_stuff2,0x07
#define command_mode_h_cmd bit_stuff3,0x00
endif ;include_m_and_h_cmd_code
#define squeeze_detected bit_stuff3,0x01
;eeprom_settings1 is used for settings that need to be stored in nonvolatile memory
;they are written to eeprom using call write_eeprom_settings1
#define sidetone_off_during_tx eeprom_settings1,0x00 ; 1 = no sidetone during TX (for internal use in rigs that alread have sidetone)
ifdef include_iambic_mode_code
#define iambic_b_mode eeprom_settings1,0x01 ; 1 = iambic b mode activated
endif
ifdef include_paddle_reverse_code
#define paddle_reverse eeprom_settings1,0x02 ; 1 = paddle reverse mode activated
endif
ifdef include_freq_counter_code
#define eight_digit_mode eeprom_settings1,0x03 ; 1 = 8 digit frequency counter mode
#define offset0 eeprom_settings1,0x04 ; offset0 and 1 stores frequency counter offset mode (table below)
#define offset1 eeprom_settings1,0x05
endif
ifdef include_bug_code
#define bug_mode_on eeprom_settings1,0x06 ; 1 = bug mode activated
endif
; frequency counter offset table
; offset0 offset1
; 0 0 no offset
; 0 1 reading = offset - measurement
; 1 0 reading = measurement - offset
; 1 1 reading = measurement + offset
org 0x00
pagesel main_program_start
errorlevel -306
goto main_program_start
errorlevel +306
; Tables -------------------------------------------------------------
cw_table
; this is a lookup table for sending numbers in CW using send_cw routine
; 00 = termination
; 01 = dit
; 11 = dah
; stream goes MSB -> LSB (MSB first)
; two bytes long
addwf PCL, F
retlw b'11111111' ;0 0
retlw b'11000000'
retlw b'01111111' ;1 1
retlw b'11000000'
retlw b'01011111' ;2 2
retlw b'11000000'
retlw b'01010111' ;3 3
retlw b'11000000'
retlw b'01010101' ;4 4
retlw b'11000000'
retlw b'01010101' ;5 5
retlw b'01000000'
retlw b'11010101' ;6 6
retlw b'01000000'
retlw b'11110101' ;7 7
retlw b'01000000'
retlw b'11111101' ;8 8
retlw b'01000000'
retlw b'11111111' ;9 9
retlw b'01000000'
ifdef include_cw_table_long
retlw b'01110000' ;A 10
retlw b'00000000'
retlw b'11010101' ;B 11
retlw b'00000000'
retlw b'11011101' ;C 12
retlw b'00000000'
retlw b'11010100' ;D 13
retlw b'00000000'
retlw b'01000000' ;E 14
retlw b'00000000'
retlw b'01011101' ;F 15
retlw b'00000000'
retlw b'11110100' ;G 16
retlw b'00000000'
retlw b'01010101' ;H 17
retlw b'00000000'
retlw b'01010000' ;I 18
retlw b'00000000'
retlw b'01111111' ;J 19
retlw b'00000000'
retlw b'11011100' ;K 20
retlw b'00000000'
retlw b'01110101' ;L 21
retlw b'00000000'
retlw b'11110000' ;M 22
retlw b'00000000'
retlw b'11010000' ;N 23
retlw b'00000000'
retlw b'01111101' ;P 24
retlw b'00000000'
retlw b'11110111' ;Q 25
retlw b'00000000'
retlw b'01110100' ;R 26
retlw b'00000000'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -