📄 pwm_ctrl.psm
字号:
;
;
; Routine to convert ASCII data in 's0' to an equivalent HEX value.
;
; If character is not valid for hex, then CARRY is set on return.
;
; Register used s0
;
ASCII_to_hex: ADD s0, B9 ;test for above ASCII code 46 ('F')
RETURN C
SUB s0, E9 ;normalise 0 to 9 with A-F in 11 to 16 hex
RETURN C ;reject below ASCII code 30 ('0')
SUB s0, 11 ;isolate A-F down to 00 to 05 hex
JUMP NC, ASCII_letter
ADD s0, 07 ;test for above ASCII code 46 ('F')
RETURN C
SUB s0, F6 ;convert to range 00 to 09
RETURN
ASCII_letter: ADD s0, 0A ;convert to range 0A to 0F
RETURN
;
;
;
;**************************************************************************************
; Text messages
;**************************************************************************************
;
;
; Send Carriage Return to the UART
;
send_CR: LOAD UART_data, character_CR
CALL send_to_UART
RETURN
;
; Send a space to the UART
;
send_space: LOAD UART_data, character_space
CALL send_to_UART
RETURN
;
;
;
;Send a back space to the UART
;
send_backspace: LOAD UART_data, character_BS
CALL send_to_UART
RETURN
;
;
; Send 'PicoBlaze Servo Control' string to the UART
;
send_welcome: CALL send_CR
CALL send_CR
LOAD UART_data, character_P
CALL send_to_UART
LOAD UART_data, character_i
CALL send_to_UART
LOAD UART_data, character_c
CALL send_to_UART
LOAD UART_data, character_o
CALL send_to_UART
LOAD UART_data, character_B
CALL send_to_UART
LOAD UART_data, character_l
CALL send_to_UART
LOAD UART_data, character_a
CALL send_to_UART
LOAD UART_data, character_z
CALL send_to_UART
LOAD UART_data, character_e
CALL send_to_UART
CALL send_space
LOAD UART_data, character_P
CALL send_to_UART
LOAD UART_data, character_W
CALL send_to_UART
LOAD UART_data, character_M
CALL send_to_UART
CALL send_space
LOAD UART_data, character_C
CALL send_to_UART
LOAD UART_data, character_o
CALL send_to_UART
LOAD UART_data, character_n
CALL send_to_UART
LOAD UART_data, character_t
CALL send_to_UART
LOAD UART_data, character_r
CALL send_to_UART
LOAD UART_data, character_o
CALL send_to_UART
LOAD UART_data, character_l
CALL send_to_UART
CALL send_CR
CALL send_CR
RETURN
;
;
;Send 'KCPSM3>' prompt to the UART
;
send_prompt: CALL send_CR ;start new line
LOAD UART_data, character_K
CALL send_to_UART
LOAD UART_data, character_C
CALL send_to_UART
LOAD UART_data, character_P
CALL send_to_UART
LOAD UART_data, character_S
CALL send_to_UART
LOAD UART_data, character_M
CALL send_to_UART
LOAD UART_data, character_3
CALL send_to_UART
;
;Send '>' character to the UART
;
send_greater_than: LOAD UART_data, character_greater_than
CALL send_to_UART
RETURN
;
;
;Send 'Overflow Error' to the UART
;
send_Overflow_Error: LOAD UART_data, character_O
CALL send_to_UART
LOAD UART_data, character_v
CALL send_to_UART
LOAD UART_data, character_e
CALL send_to_UART
LOAD UART_data, character_r
CALL send_to_UART
LOAD UART_data, character_f
CALL send_to_UART
LOAD UART_data, character_l
CALL send_to_UART
LOAD UART_data, character_o
CALL send_to_UART
LOAD UART_data, character_w
CALL send_to_UART
send_space_Error: CALL send_space
;
;Send 'Error' to the UART
;
send_Error: LOAD UART_data, character_E
CALL send_to_UART
LOAD UART_data, character_r
CALL send_to_UART
CALL send_to_UART
LOAD UART_data, character_o
CALL send_to_UART
LOAD UART_data, character_r
CALL send_to_UART
JUMP send_CR
;
;
;Send 'OK' to the UART
;
send_OK: CALL send_CR
LOAD UART_data, character_O
CALL send_to_UART
LOAD UART_data, character_K
CALL send_to_UART
JUMP send_CR
;
;
;**************************************************************************************
; Interrupt Service Routine (ISR)
;**************************************************************************************
;
; Interrupts occur at 3.92us intervals and are used to generate the PWM pulses generated
; at a PRF of 1KHz. The 3.92us interrupt rate corresponds with a resolution of 256 steps
; over the 1ms associated with the 1KHz PRF.
;
; The ISR is self contained and all registers used are preserved. Scratch pad memory
; locations are used to determine the desired duty factor for each of 12 channels.
;
; Note that an interrupt is generated every 196 clock cycles. This means that there is
; only time to execute 98 instructions between each interrupt. This ISR is 48 instructions
; long. A further 3 instructions are also consumed by the interrupt process
; (abandoned instruction, virtual CALL to 3FF and the interrupt vector JUMP) and hence
; PicoBlaze has approximately half of its time available for other tasks in the main program.
;
; Although a loop would normal be employed in software to process each of 12 channels,
; the implementation of a loop would increase the number of instructions which needed to
; be executed to such an extent that this 12 channel implementation would not be possible.
; Consequently the code is written out in a linear fashion which consumes more program
; space but which executes faster.
;
ISR: STORE s0, ISR_preserve_s0 ;preserve registers to be used
STORE s1, ISR_preserve_s1
STORE s2, ISR_preserve_s2
;Determine the number of steps currently through the 1ms PWM cycle
FETCH s1, PWM_duty_counter ;read 8-bit counter of steps
ADD s1, 01 ;increment counter (will roll over to zero)
STORE s1, PWM_duty_counter ;update count value in memory for next interrupt.
;Read duty factor for each channel and compare it with the duty counter and set or
;reset a bit in register s2 accordingly.
FETCH s0, PWM_channel11 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel10 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel9 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel8 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
OUTPUT s2, simple_port ;drive pins on connector J4
FETCH s0, PWM_channel7 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel6 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel5 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel4 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel3 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel2 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel1 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
FETCH s0, PWM_channel0 ;read desired setting of pulse width
COMPARE s1, s0 ;set carry flag if duty factor > duty counter
SLA s2 ;shift carry into register s2
OUTPUT s2, LED_port ;drive LEDs
FETCH s0, ISR_preserve_s0 ;restore register values
FETCH s1, ISR_preserve_s1
FETCH s2, ISR_preserve_s2
RETURNI ENABLE
;
;
;**************************************************************************************
; Interrupt Vector
;**************************************************************************************
;
ADDRESS 3FF
JUMP ISR
;
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -