📄 dac_ctrl.psm
字号:
OUTPUT s0, SPI_control_port ;drive clock Low
SUB s1, 01 ;count bits
JUMP NZ, next_SPI_dac_bit ;repeat until finished
RETURN
;
;
;
;Set a voltage on one of the LTC2624 D/A converter outputs
;
;The D/A converter has 4 channels. Specify which channel is to be set using
;register sC as follows....
; sC Channel Nominal Voltage Range
; 00 A 0 to 3.30v (or VREFAB)
; 01 B 0 to 3.30v (or VREFAB)
; 02 C 0 to 2.50v (or VREFCD)
; 03 D 0 to 2.50v (or VREFCD)
; 0F All channels various as above.
;
;The analogue level is a 12-bit value to be supplied in lower 12-bits of register
;pair [sB,sA]. If this value is called 'k' and is in the range 0 to 4095 (000 to FFF)
;then
; Vout = (k/4096) * VREFx
;Hence it is not possible to reach the absolute level of the reference.
;
;Here are some useful values..
; Voltage A or B C or D
; 0.0 000 000
; 0.5 26D 333
; 0.65 327 A/D reference -1.00v
; 1.0 4D9 666
; 1.5 746 99A
; 1.65 800 A8F converter reference = 3.3/2 = 1.65v
; 2.0 9B2 CCD
; 2.5 C1F FFF
; 2.65 CD9 A/D reference +1.00v
; 3.0 E8C n/a
; 3.3 FFF n/a
;
;Note that the full scale deflection of FFF will result in different output
;voltages due to different reference voltages for each pair of channels.
;
;SPI communication with the DAC only requires a 24-bit word to be transmitted.
;However, the device internally contains a 32-bit shift register. When writing
;a command word, the previous contents are shifted out and can be observed by
;the master (Spartan-3E in this case). If you do not use a 32-bit format, then
;the read back is confusing. Hence this routine uses a 32-bit format by transmitting
;a dummy byte first.
;
; Byte 1 = 00 8 dummy bits
; Byte 2 = 3c Command nibble (3=write and update) and channel selection
; Byte 3 = dd Upper 8-bits of the 12-bit voltage value
; Byte 4 = d0 lower 4-bits of the 12-bit voltage value and 4 dummy bits.
;
;At the end of this communication, the register set [s9,s8,s7,s6] will contain the
;data received back from the D/A converter which should be the previous command.
;
set_dac: CALL SPI_init ;ensure known state of bus and s0 register
XOR s0, SPI_dac_cs ;select low on D/A converter
OUTPUT s0, SPI_control_port
LOAD s2, 00 ;Write dummy byte to DAC
CALL SPI_dac_tx_rx
LOAD s9, s2 ;capture response
LOAD s2, sC ;Select channel for update
AND s2, 0F ;isolate channel bits to be certain of correct command
OR s2, 30 ;Use immediate Write and Update command is "0011"
CALL SPI_dac_tx_rx
LOAD s8, s2 ;capture response
SL0 sA ;data shift bits into correct position
SLA sB ;with 4 dummy bits ('0') in the least significant bits.
SL0 sA
SLA sB
SL0 sA
SLA sB
SL0 sA
SLA sB
LOAD s2, sB ;Write 12 bit value followed by 4 dummy bits
CALL SPI_dac_tx_rx
LOAD s7, s2 ;capture response
LOAD s2, sA
CALL SPI_dac_tx_rx
LOAD s6, s2 ;capture response
XOR s0, SPI_dac_cs ;deselect the D/A converter to execute
OUTPUT s0, SPI_control_port
RETURN
;
;Perform a hard reset of the D/A converter
;
dac_reset: CALL SPI_init ;ensure known state of bus and s0 register
XOR s0, SPI_dac_clr ;pulse the clear signal.
OUTPUT s0, SPI_control_port
XOR s0, SPI_dac_clr
OUTPUT s0, SPI_control_port
RETURN
;
;
;**************************************************************************************
;Software delay routines
;**************************************************************************************
;
;
;
;Delay of 1us.
;
;Constant value defines reflects the clock applied to KCPSM3. Every instruction
;executes in 2 clock cycles making the calculation highly predictable. The '6' in
;the following equation even allows for 'CALL delay_1us' instruction in the initiating code.
;
; delay_1us_constant = (clock_rate - 6)/4 Where 'clock_rate' is in MHz
;
;Registers used s0
;
delay_1us: LOAD s0, delay_1us_constant
wait_1us: SUB s0, 01
JUMP NZ, wait_1us
RETURN
;
;Delay of 40us.
;
;Registers used s0, s1
;
delay_40us: LOAD s1, 28 ;40 x 1us = 40us
wait_40us: CALL delay_1us
SUB s1, 01
JUMP NZ, wait_40us
RETURN
;
;
;Delay of 1ms.
;
;Registers used s0, s1, s2
;
delay_1ms: LOAD s2, 19 ;25 x 40us = 1ms
wait_1ms: CALL delay_40us
SUB s2, 01
JUMP NZ, wait_1ms
RETURN
;
;Delay of 20ms.
;
;Delay of 20ms used during initialisation.
;
;Registers used s0, s1, s2, s3
;
delay_20ms: LOAD s3, 14 ;20 x 1ms = 20ms
wait_20ms: CALL delay_1ms
SUB s3, 01
JUMP NZ, wait_20ms
RETURN
;
;Delay of approximately 1 second.
;
;Registers used s0, s1, s2, s3, s4
;
delay_1s: LOAD s4, 14 ;50 x 20ms = 1000ms
wait_1s: CALL delay_20ms
SUB s4, 01
JUMP NZ, wait_1s
RETURN
;
;
;
;**************************************************************************************
;Interrupt Service Routine (ISR)
;**************************************************************************************
;
;Interrupts occur at a rate of 8KHz.
;
;Each interrupt is the fundamental timing trigger used to set the sample rate and
;it is therefore use to set the D/A outputs by copying the values stored in
;scratch pad memory and outputting them to the D/A converter using the SPI bus.
;
;Because the SPI communication is in itself a predictable process, the sample rate
;is preserved without sample jitter. All variable activities are left to the main
;program.
;
;Each time PicoBlaze transmits a 32-bit command word to the D/A converter, the
;D/A responds with the last command it was sent. So as the end of this service routine
;the register set [s9,s8,s7,s6] will contain the command which has just been sent
;for the setting of channel C.
;
;Set channel A
;
ISR: LOAD sC, 00 ;channel A
FETCH sB, chan_A_msb ;12-bit value
FETCH sA, chan_A_lsb
CALL set_dac
;
;Set channel B
;
LOAD sC, 01 ;channel B
FETCH sB, chan_B_msb ;12-bit value
FETCH sA, chan_B_lsb
CALL set_dac
;
;Set channel C
;
LOAD sC, 02 ;channel C
FETCH sB, chan_C_msb ;12-bit value
FETCH sA, chan_C_lsb
CALL set_dac
;
;Set channel A
;
LOAD sC, 03 ;channel D
FETCH sB, chan_D_msb ;12-bit value
FETCH sA, chan_D_lsb
CALL set_dac
;
LOAD sF, 00 ;clear flag
RETURNI ENABLE
;
;
;**************************************************************************************
;Interrupt Vector
;**************************************************************************************
;
ADDRESS 3FF
JUMP ISR
;
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -