📄 adc_ctrl.psm
字号:
;
;
;**************************************************************************************
;Display voltage level at in the form X.XXX on the LCD at current cursor position
;**************************************************************************************
;
;Value to be displayed must be unsigned (positive) in the
;[s7,s6] register pair. Only the lower 4 digits are displayed.
;
disp_volts: CALL integer16_to_BCD ;convert [s7,s6] to BCD in scratch pad memory
FETCH s5, decimal3
ADD s5, 30 ;convert to ASCII
CALL LCD_write_data
LOAD s5, character_stop
CALL LCD_write_data
FETCH s5, decimal2
ADD s5, 30 ;convert to ASCII
CALL LCD_write_data
FETCH s5, decimal1
ADD s5, 30 ;convert to ASCII
CALL LCD_write_data
FETCH s5, decimal0
ADD s5, 30 ;convert to ASCII
CALL LCD_write_data
LOAD s5, character_space ;ensure next position is cleared
CALL LCD_write_data
RETURN
;
;**************************************************************************************
;Changing amplifier gain using press buttons
;**************************************************************************************
;
;Possible gain values are
; Gain Amplifier
; code
; -1 1
; -2 2
; -5 3
; -10 4
; -20 5
; -50 6
; -100 7
;
gain_increase: DISABLE INTERRUPT ;stop normal operation
FETCH s0, amp_A_gain ;read current gain
ADD s0, 01
COMPARE s0, 08 ;test for too big
JUMP NZ, new_gain_set
LOAD s0, 07 ;maximum gain
JUMP new_gain_set
gain_decrease: DISABLE INTERRUPT ;stop normal operation
FETCH s0, amp_A_gain ;read current gain
SUB s0, 01
JUMP NZ, new_gain_set
LOAD s0, 01 ;minimum gain
new_gain_set: STORE s0, amp_A_gain ;store new value
FETCH s2, amp_B_gain ;form the amplifier control byte
SL0 s2 ;B amplifier set by upper 4 bits
SL0 s2
SL0 s2
SL0 s2
OR s2, s0 ;A amplifier set by lower
CALL set_amp ;set SPI amplifier
;display gain setting on LCD
LOAD s5, 10 ;Line 1 position 0
CALL LCD_cursor
LOAD s5, character_G
CALL LCD_write_data
LOAD s5, character_equals
CALL LCD_write_data
LOAD s5, character_minus
CALL LCD_write_data
FETCH s0, amp_A_gain ;read A gain setting
COMPARE s0, 01 ;determine actual gain value
JUMP NZ, test_A2
LOAD s5, character_1 ;gain is -1
CALL LCD_write_data
LOAD s5, character_space
CALL LCD_write_data
LOAD s5, character_space
CALL LCD_write_data
JUMP wait_no_press
test_A2: COMPARE s0, 02
JUMP NZ, test_A3
LOAD s5, character_2 ;gain is -2
CALL LCD_write_data
LOAD s5, character_space
CALL LCD_write_data
LOAD s5, character_space
CALL LCD_write_data
JUMP wait_no_press
test_A3: COMPARE s0, 03
JUMP NZ, test_A4
LOAD s5, character_5 ;gain is -5
CALL LCD_write_data
LOAD s5, character_space
CALL LCD_write_data
LOAD s5, character_space
CALL LCD_write_data
JUMP wait_no_press
test_A4: COMPARE s0, 04
JUMP NZ, test_A5
LOAD s5, character_1 ;gain is -10
CALL LCD_write_data
LOAD s5, character_0
CALL LCD_write_data
LOAD s5, character_space
CALL LCD_write_data
JUMP wait_no_press
test_A5: COMPARE s0, 05
JUMP NZ, test_A6
LOAD s5, character_2 ;gain is -20
CALL LCD_write_data
LOAD s5, character_0
CALL LCD_write_data
LOAD s5, character_space
CALL LCD_write_data
JUMP wait_no_press
test_A6: COMPARE s0, 06
JUMP NZ, gain_A7
LOAD s5, character_5 ;gain is -50
CALL LCD_write_data
LOAD s5, character_0
CALL LCD_write_data
LOAD s5, character_space
CALL LCD_write_data
JUMP wait_no_press
gain_A7: LOAD s5, character_1 ;gain is -100
CALL LCD_write_data
LOAD s5, character_0
CALL LCD_write_data
LOAD s5, character_0
CALL LCD_write_data
wait_no_press: CALL delay_20ms ;delay to help avoid switch bounce
INPUT s0, switch_port ;check for release of press buttons
TEST s0, 05 ;north and south buttons
JUMP NZ, wait_no_press
JUMP warm_start
;
;**************************************************************************************
;16-bit by 16-bit Signed multiplier
;**************************************************************************************
;
;16 bit signed multiplication using shift and add technique.
;The full precision 32-bit product is returned.
;
;The key to signed multiplication is to think of all bits of the second operand
;[s1,s0] as being positive except for the most significant bit. This means that
;the first operand is added to the result in all cases when there is a '1' in the
;second operand except for the MSB case when the first operand is subtracted if there
;is a '1'.
;
;[s7,s6,s5,s4]=[s3,s2]x[s1,s0]
;
;Registers used s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,sA
;
mult_16x16s: LOAD s7, 00 ;clear accumulator
LOAD s6, 00
LOAD s5, 00 ;Set bit 14 to act as a bit shift counter
LOAD s4, 00
LOAD s8, 00 ;sign extend [s3,s2] to form [s9,s8,s3,s2]
TEST s3, 80 ;test sign of first operand
JUMP Z, m16s_pos
LOAD s8, FF
m16s_pos: LOAD s9, s8 ;[s9,s8,s3,s2]=0000xxxx or FFFFxxxx as required
LOAD sA, 0F ;15 positive shift and add operations to perform
m16s_loop: SR0 s1 ;shift right operand [s1,s0]
SRA s0
JUMP NC, m16s_noadd ;test for a '1'
ADD s4, s2 ;32-bit addition [s7,s6,s5,s4]=[s7,s6,s5,s4]+[s9,s8,s3,s2]
ADDCY s5, s3
ADDCY s6, s8
ADDCY s7, s9
m16s_noadd: SL0 s2 ;multiply first operand by 2
SLA s3
SLA s8
SLA s9
SUB sA, 01
JUMP NZ, m16s_loop ;move to next unsigned bit
TEST s0, 01 ;test sign bit of operand [s1,s0]
JUMP NC, m16s_nosub
SUB s4, s2 ;32-bit subtraction [s7,s6,s5,s4]=[s7,s6,s5,s4]-[s9,s8,s3,s2]
SUBCY s5, s3
SUBCY s6, s8
SUBCY s7, s9
m16s_nosub: RETURN
;
;
;
;**************************************************************************************
;16-bit positive integer to 5 digit decimal conversion
;**************************************************************************************
;
;Convert the 16 bit value in register set [s7,s6]
;into the BCD decimal equivalent located in the scratch pad memory
;locations 'decimal0' to 'decimal4' which must be in ascending locations.
;
;Register set [s9,s8,s7,s6] are preserved.
;
;
;Each digit is formed in turn starting with the least significant.
;
;Registers used s0,s1,s2,s3,s4,s5,s6,s7,s8
;
integer16_to_BCD: LOAD s0, 05 ;5 digits to be formed from value up to 65535
LOAD s8, decimal0 ;pointer for LS-Digit
int_to_BCD_loop: CALL divide_16bit_by_10 ;[s7,s6]=[s7,s6]/10 with remainder in s4
STORE s4, (s8) ;remainder becomes digit value
ADD s8, 01 ;move to next most significant digit
SUB s0, 01 ;one less digit to compute
JUMP NZ, int_to_BCD_loop
RETURN
;
;Divide 16-bit binary integer by 10
;
;The value to be divided is held in register set [s7,s6]
;and this is where the result is returned to.
;
;At then end of the integer division the remainder in the range 0 to 9
;will be in register s4.
;
;Registers used s1,s2,s3,s4,s5,s6,s7
;Other registers are used but are preserved
;
divide_16bit_by_10: LOAD s4, s6 ;copy input value to [s5,s4]
LOAD s5, s7
LOAD s6, 00 ;clear result
LOAD s7, 00
LOAD s2, 00 ;initialise '10' value into msb's of set [s3,s2]
LOAD s3, A0
LOAD s1, 0D ;13 subtract and shift iterations to be performed
div10_loop: SUB s4, s2 ;perform 16-bit subtract [s5,s4]-[s3,s2]
SUBCY s5, s3
JUMP C, div10_restore
SL1 s6 ;shift '1' into result because subtract was possible
JUMP div10_shifts
div10_restore: ADD s4, s2 ;perform 32-bit addition [s5,s4]+[s3,s2]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -