uclock.psm
来自「和picoblaze完全兼容的mcu ip core」· PSM 代码 · 共 1,009 行 · 第 1/4 页
PSM
1,009 行
;KCPSM3 Program - Real Time Clock with UART communication.
;
;Ken Chapman - Xilinx Ltd - October 2003
;
;
;Port definitions
;
constant UART_status_port, $00 ;UART status input
constant tx_half_full, $01 ; Transmitter half full - bit0
constant tx_full, $02 ; FIFO full - bit1
constant rx_half_full, $04 ; Receiver half full - bit2
constant rx_full, $08 ; FIFO full - bit3
constant rx_data_present, $10 ; data present - bit4
;
constant UART_read_port, $01 ;UART Rx data input
;
constant UART_write_port, $01 ;UART Tx data output
;
constant alarm_port, $00 ;Alarm output
constant alarm_control, $01 ; bit0
;
;Special Register usage
;
register UART_data, $f ;used to pass data to and from the UART
;
register store_pointer, $e ;used to pass location of data in scratch pad memory
;
;Two registers to form a 16-bit counter used to count
;interrupt pulses generated at 1us intervals.
;
register int_counter_lsb, $d ;lower 8-bits
register int_counter_msb, $c ;upper 8-bits
;
;
;Scratch Pad Memory Locations
;
;
constant us_time_stamp_lsb, $00 ;16-bit micro-second time stamp
constant us_time_stamp_msb, $01
;
constant us_time_lsb, $02 ;16-bit micro-second real time value
constant us_time_msb, $03
;
constant ms_time_lsb, $04 ;16-bit milli-second real time value
constant ms_time_msb, $05
;
constant real_time_hours, $06 ;Current clock time
constant real_time_minutes, $07
constant real_time_seconds, $08
;
constant alarm_time_hours, $09 ;Alarm time
constant alarm_time_minutes, $0A
constant alarm_time_seconds, $0B
;
constant alarm_status, $0C ;Alarm status
constant alarm_active, $01 ; bit0 - Alarm is active
constant alarm_armed, $02 ; bit1 - Alarm is armed
;
constant time_preserve0, $10 ;storage for protection of registers
constant time_preserve1, $11 ;used by the real time clock routine.
constant time_preserve2, $12
constant time_preserve3, $13
constant time_preserve4, $14
constant time_preserve5, $15
;
;UART character strings will be stored in scratch pad memory ending in carriage return.
;A string can be up to 16 characters with the start location defined by this constant.
;
constant string_start, $20
;
;
;Initialise the system
;
;
cold_start: load s0, $00 ;clear all time values
store s0, us_time_stamp_lsb
store s0, us_time_stamp_msb
store s0, us_time_lsb
store s0, us_time_msb
store s0, ms_time_lsb
store s0, ms_time_msb
store s0, real_time_hours
store s0, real_time_minutes
store s0, real_time_seconds
store s0, alarm_time_hours
store s0, alarm_time_minutes
store s0, alarm_time_seconds
store s0, alarm_status ;clear and disable alarm
call alarm_drive ;turn off alarm control output port
load int_counter_lsb, $00 ;clear 'us' interrupt counter
load int_counter_msb, $00
interrupt enable ;enable the 1us interrupts
;
;
;Start of the main program loop.
;
;A prompt is transmitted to the UART transmitter and then
;a command can be entered and interpreted.
;
;
prompt_input: call send_prompt ;Prompt 'KCPSM3>'
call receive_string ;obtain input string and maintain the time
;
;
;Parse the string and perform actions as required
;
;
;
load s1, string_start
call fetch_char_from_memory
compare s0, character_CR ;carriage return does nothing
jump z, prompt_input
compare s0, character_T ;start of 'TIME' command?
jump z, test_for_TIME
compare s0, character_A ;start of 'ALARM' command?
jump z, test_for_ALARM
;
;trap other command starts here
;
bad_input_command: call send_Syntax_Error ;no valid command
jump z, prompt_input
;
;
test_for_TIME: call fetch_char_from_memory
compare s0, character_I ;test for rest of 'TIME'
jump nz, bad_input_command
call fetch_char_from_memory
compare s0, character_M
jump nz, bad_input_command
call fetch_char_from_memory
compare s0, character_E
jump nz, bad_input_command
;now have a valid TIME command to process
call fetch_char_from_memory
compare s0, character_CR ;carriage return means display time
jump nz, set_time_command
call transmit_time ;transmit time to UART
jump prompt_input
set_time_command: compare s0, character_space
jump nz, bad_input_command
call test_time_string ;interpret 'hh:mm:ss' string
jump c, prompt_input ;test for invalid input
store s6, real_time_hours ;set new time into clock
store s5, real_time_minutes
store s4, real_time_seconds
store s0, ms_time_lsb ;clear 'ms' counter (s0=00)
store s0, ms_time_msb
call transmit_time ;transmit new time to UART
jump prompt_input
;
;
test_for_ALARM: call fetch_char_from_memory
compare s0, character_L ;test for rest of 'ALARM'
jump nz, bad_input_command
call fetch_char_from_memory
compare s0, character_A
jump nz, bad_input_command
call fetch_char_from_memory
compare s0, character_R
jump nz, bad_input_command
call fetch_char_from_memory
compare s0, character_M
jump nz, bad_input_command
;now have a valid ALARM command to process
call fetch_char_from_memory
compare s0, character_CR ;carriage return means display alarm time
jump nz, set_alarm_command
call transmit_alarm_time ;transmit time to UART
jump prompt_input
set_alarm_command: compare s0, character_space ;test for ON or OFF command
jump nz, bad_input_command
call fetch_char_from_memory
compare s0, character_O
jump z, set_alarm_on_off
sub s1, $01 ;move memory pointer back to first character of 'hh:mm:ss' string
call test_time_string ;interpret 'hh:mm:ss' string
jump c, prompt_input ;test for invalid input
store s6, alarm_time_hours ;set new time into clock
store s5, alarm_time_minutes
store s4, alarm_time_seconds
call transmit_alarm_time ;transmit new alarm time and status
jump prompt_input
set_alarm_on_off: call fetch_char_from_memory
compare s0, character_N ;test for 'ON'
jump nz, test_OFF
call fetch_char_from_memory
compare s0, character_CR
jump nz, bad_input_command
fetch s0, alarm_status ;turn alarm on
or s0, alarm_armed
store s0, alarm_status
call transmit_alarm_time ;transmit alarm time and status
jump prompt_input
test_OFF: compare s0, character_F ;test for for 'OFF'
jump nz, bad_input_command
call fetch_char_from_memory
compare s0, character_F
jump nz, bad_input_command
call fetch_char_from_memory
compare s0, character_CR
jump nz, bad_input_command
load s0, $00 ;turn alarm off and stop an active alarm
store s0, alarm_status
call alarm_drive ;turn off alarm
call transmit_alarm_time ;transmit alarm time and status
jump prompt_input
;
;
;
;
;Read an 'hh:mm:ss' time string and provide new values.
;
;The string must be provided in successive scratch pad memory locations
;with the s1 register containing the location of the first character.
;
;A correct time specification will result in the return of new values
;as follows:-
;
; s6 = hours
; s5 = minutes
; s4 = seconds
;
;If the syntax is incorrect or values are not in the correct ranges an
;'Invalid Time' message will be transmitted and the CARRY flag will be set
;
;Registers used s0, s1, s6, s5 and s4
;
test_time_string: call _2char_to_value ;obtain hours value
jump c, invalid_time ;test for non-decimal characters
load s6, s2 ;remember hours
add s1, $01 ;increment memory pointer past hours
call fetch_char_from_memory
compare s0, character_colon ;test for colon
jump nz, invalid_time
call _2char_to_value ;obtain minutes value
jump c, invalid_time ;test for non-decimal characters
load s5, s2 ;remember minutes
add s1, $01 ;increment memory pointer past minutes
call fetch_char_from_memory
compare s0, character_colon ;test for colon
jump nz, invalid_time
call _2char_to_value ;obtain seconds value
jump c, invalid_time ;test for non-decimal characters
load s4, s2 ;remember minutes
add s1, $01 ;increment memory pointer past seconds
call fetch_char_from_memory
compare s0, character_CR ;finish with carriage return
jump nz, invalid_time
;Have values for hh:mm:ss but need to test if each is valid range.
compare s6, hours_in_a_day
jump nc, invalid_time
compare s5, minutes_in_an_hour
jump nc, invalid_time
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?