📄 fc_ctrl.psm
字号:
;
LCD_write_inst4: AND s4, F8 ;Enable=1 RS=0 Instruction, RW=0 Write, E=0
OUTPUT s4, LCD_output_port ;set up RS and RW >40ns before enable pulse
CALL LCD_pulse_E
RETURN
;
;
;Write 8-bit instruction to LCD display.
;
;The 8-bit instruction should be provided in register s5.
;Instructions are written using the following sequence
; Upper nibble
; wait >1us
; Lower nibble
; wait >40us
;
;Registers used s0, s1, s4, s5
;
LCD_write_inst8: LOAD s4, s5
AND s4, F0 ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
OR s4, LCD_drive ;Enable=1
CALL LCD_write_inst4 ;write upper nibble
CALL delay_1us ;wait >1us
LOAD s4, s5 ;select lower nibble with
SL1 s4 ;Enable=1
SL0 s4 ;RS=0 Instruction
SL0 s4 ;RW=0 Write
SL0 s4 ;E=0
CALL LCD_write_inst4 ;write lower nibble
CALL delay_40us ;wait >40us
LOAD s4, F0 ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
OUTPUT s4, LCD_output_port ;Release master enable
RETURN
;
;
;
;Write 8-bit data to LCD display.
;
;The 8-bit data should be provided in register s5.
;Data bytes are written using the following sequence
; Upper nibble
; wait >1us
; Lower nibble
; wait >40us
;
;Registers used s0, s1, s4, s5
;
LCD_write_data: LOAD s4, s5
AND s4, F0 ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
OR s4, 0C ;Enable=1 RS=1 Data, RW=0 Write, E=0
OUTPUT s4, LCD_output_port ;set up RS and RW >40ns before enable pulse
CALL LCD_pulse_E ;write upper nibble
CALL delay_1us ;wait >1us
LOAD s4, s5 ;select lower nibble with
SL1 s4 ;Enable=1
SL1 s4 ;RS=1 Data
SL0 s4 ;RW=0 Write
SL0 s4 ;E=0
OUTPUT s4, LCD_output_port ;set up RS and RW >40ns before enable pulse
CALL LCD_pulse_E ;write lower nibble
CALL delay_40us ;wait >40us
LOAD s4, F0 ;Enable=0 RS=0 Instruction, RW=0 Write, E=0
OUTPUT s4, LCD_output_port ;Release master enable
RETURN
;
;
;
;
;Read 8-bit data from LCD display.
;
;The 8-bit data will be read from the current LCD memory address
;and will be returned in register s5.
;It is advisable to set the LCD address (cursor position) before
;using the data read for the first time otherwise the display may
;generate invalid data on the first read.
;
;Data bytes are read using the following sequence
; Upper nibble
; wait >1us
; Lower nibble
; wait >40us
;
;Registers used s0, s1, s4, s5
;
LCD_read_data8: LOAD s4, 0E ;Enable=1 RS=1 Data, RW=1 Read, E=0
OUTPUT s4, LCD_output_port ;set up RS and RW >40ns before enable pulse
XOR s4, LCD_E ;E=1
OUTPUT s4, LCD_output_port
CALL delay_1us ;wait >260ns to access data
INPUT s5, LCD_input_port ;read upper nibble
XOR s4, LCD_E ;E=0
OUTPUT s4, LCD_output_port
CALL delay_1us ;wait >1us
XOR s4, LCD_E ;E=1
OUTPUT s4, LCD_output_port
CALL delay_1us ;wait >260ns to access data
INPUT s0, LCD_input_port ;read lower nibble
XOR s4, LCD_E ;E=0
OUTPUT s4, LCD_output_port
AND s5, F0 ;merge upper and lower nibbles
SR0 s0
SR0 s0
SR0 s0
SR0 s0
OR s5, s0
LOAD s4, 04 ;Enable=0 RS=1 Data, RW=0 Write, E=0
OUTPUT s4, LCD_output_port ;Stop reading 5V device and release master enable
CALL delay_40us ;wait >40us
RETURN
;
;
;Reset and initialise display to communicate using 4-bit data mode
;Includes routine to clear the display.
;
;Requires the 4-bit instructions 3,3,3,2 to be sent with suitable delays
;following by the 8-bit instructions to set up the display.
;
; 28 = '001' Function set, '0' 4-bit mode, '1' 2-line, '0' 5x7 dot matrix, 'xx'
; 06 = '000001' Entry mode, '1' increment, '0' no display shift
; 0C = '00001' Display control, '1' display on, '0' cursor off, '0' cursor blink off
; 01 = '00000001' Display clear
;
;Registers used s0, s1, s2, s3, s4
;
LCD_reset: CALL delay_20ms ;wait more that 15ms for display to be ready
LOAD s4, 30
CALL LCD_write_inst4 ;send '3'
CALL delay_20ms ;wait >4.1ms
CALL LCD_write_inst4 ;send '3'
CALL delay_1ms ;wait >100us
CALL LCD_write_inst4 ;send '3'
CALL delay_40us ;wait >40us
LOAD s4, 20
CALL LCD_write_inst4 ;send '2'
CALL delay_40us ;wait >40us
LOAD s5, 28 ;Function set
CALL LCD_write_inst8
LOAD s5, 06 ;Entry mode
CALL LCD_write_inst8
LOAD s5, 0C ;Display control
CALL LCD_write_inst8
LCD_clear: LOAD s5, 01 ;Display clear
CALL LCD_write_inst8
CALL delay_1ms ;wait >1.64ms for display to clear
CALL delay_1ms
RETURN
;
;Position the cursor ready for characters to be written.
;The display is formed of 2 lines of 16 characters and each
;position has a corresponding address as indicated below.
;
; Character position
; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
;
; Line 1 - 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
; Line 2 - C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
;
;This routine will set the cursor position using the value provided
;in register s5. The upper nibble will define the line and the lower
;nibble the character position on the line.
; Example s5 = 2B will position the cursor on line 2 position 11
;
;Registers used s0, s1, s2, s3, s4
;
LCD_cursor: TEST s5, 10 ;test for line 1
JUMP Z, set_line2
AND s5, 0F ;make address in range 80 to 8F for line 1
OR s5, 80
CALL LCD_write_inst8 ;instruction write to set cursor
RETURN
set_line2: AND s5, 0F ;make address in range C0 to CF for line 2
OR s5, C0
CALL LCD_write_inst8 ;instruction write to set cursor
RETURN
;
;
;
;**************************************************************************************
;Interrupt Service Routine
;**************************************************************************************
;
;
;Each interrupt means that there is a new count value to be read.
;However the first 4 interrupts are ignored other than to clear the counter to
;ensure that even the first reading is for one complete period.
;
;After reading the active counter, all calculations are performed and values stored
;in scratch pad memory are updated to reflect the new values.
;
;Registers are preserved and restored by the ISR so main program is unaffected.
;
ISR: STORE s0, preserve_s0 ;preserve registers
STORE s1, preserve_s1
STORE s2, preserve_s2
STORE s3, preserve_s3
STORE s4, preserve_s4
STORE s5, preserve_s5
STORE s6, preserve_s6
STORE s7, preserve_s7
STORE s8, preserve_s8
STORE s9, preserve_s9
STORE sA, preserve_sA
STORE sB, preserve_sB
STORE sC, preserve_sC
STORE sD, preserve_sD
STORE sE, preserve_sE
STORE sF, preserve_sF
;
;Ignore the first 4 interrupts except to clear the counter.
;This will ensure a clean start up after reset.
;
FETCH s0, ISR_count ;test to see if more that 4 interrupts have occurred
COMPARE s0, 04
JUMP Z, normal_isr
ADD s0, 01 ;increment ISR counter until reaching 4
STORE s0, ISR_count
INPUT s0, status_port ;Check which counter to clear
TEST s0, AB_switch ;if bit0 is Low then A is counting
JUMP Z, clear_B_count
clear_A_count: LOAD s0, a_count_reset ;clear the active counter
JUMP clear_counter
clear_B_count: LOAD s0, b_count_reset ;clear the active counter
clear_counter: OUTPUT s0, count_resetport ;reset counter with pulse
LOAD s0, 00 ;end reset pulse to either counter
OUTPUT s0, count_resetport
JUMP restore_reg
;
;Normal ISR Routine
;
;
;Read the new counter value and then clear it ready to start again
;
;
normal_isr: INPUT s0, status_port ;test for active counter
TEST s0, AB_switch ;if bit is low then A is counting
JUMP Z, capture_B_count
capture_A_count: LOAD s0, F0 ;set LEDs to indicate active counter
OUTPUT s0, LED_port
INPUT sC, A_count0_port ;read counter A into [sF,sE,SD,sC]
INPUT sD, A_count1_port
INPUT sE, A_count2_port
INPUT sF, A_count3_port
LOAD s0, a_count_reset ;reset counter A
OUTPUT s0, count_resetport
JUMP counters_read
;
capture_B_count: LOAD s0, 0F ;set LEDs to indicate active counter
OUTPUT s0, LED_port
INPUT sC, B_count0_port ;read counter A into [sF,sE,SD,sC]
INPUT sD, B_count1_port
INPUT sE, B_count2_port
INPUT sF, B_count3_port
LOAD s0, b_count_reset ;reset counter B
OUTPUT s0, count_resetport
counters_read: LOAD s0, 00 ;end reset pulse to either counter
OUTPUT s0, count_resetport
;
STORE sC, count0 ;store new counter value
STORE sD, count1
STORE sE, count2
STORE sF, count3
;
;
;
;Restore registers and end ISR
;
restore_reg: FETCH sF, preserve_sF ;restore registers
FETCH sE, preserve_sE
FETCH sD, preserve_sD
FETCH sC, preserve_sC
FETCH sB, preserve_sB
FETCH sA, preserve_sA
FETCH s9, preserve_s9
FETCH s8, preserve_s8
FETCH s7, preserve_s7
FETCH s6, preserve_s6
FETCH s5, preserve_s5
FETCH s4, preserve_s4
FETCH s3, preserve_s3
FETCH s2, preserve_s2
FETCH s1, preserve_s1
FETCH s0, preserve_s0
RETURNI ENABLE
;
;
;Interrupt vector
;
ADDRESS 3FF
JUMP ISR
;
;
;**************************************************************************************
;End of Program
;**************************************************************************************
;
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -