?? 196kxa.cod
字號:
DIVIDE_BY_1 set 000h
DIVIDE_BY_2 set 001h
DIVIDE_BY_4 set 002h
DIVIDE_BY_8 set 003h
DIVIDE_BY_16 set 004h
DIVIDE_BY_32 set 005h
DIVIDE_BY_64 set 006h
OVR_TIMER1 set 001h
OVR_TIMER2 set 000h
cseg
; Configure Timer @@TIMER_NUMBER@
$$if$ TIME_CON.7
; - Enable timer @@TIMER_NUMBER@
$$end$
$$ifn$ TIME_CON.4
; - Counting direction = $%TTIME_CON.6$up$down$
$$end$
$$ifn$ TIME_CON.3 |! TIME_CON.4 |! TIME_CON.5
; - Clock source = $%7TIME_CON.3-5$XTAL/4$TxCLK$XTAL/4$TxCLK$TxCLK$Timer 1 Overflow$Timer 1 Overflow$
$$end$
$$if$ TIME_CON.3 && TIME_CON.4 && TIME_CON.5
; - Clock mode = Quadrature Clocking
$$end$
$$ifn$ TIME_CON.3 |! TIME_CON.4 |! TIME_CON.5
; - Counting Direction Source = $%7TIME_CON.3-5$UD bit$UD bit$TxDIR$TxDIR$UD bit$UD bit$same as timer 1$
$$end$
$$ifn$ TIME_CON.3 |! TIME_CON.4 |! TIME_CON.5
; - Prescale = divide_by_$%7TIME_CON.0-2$1$2$4$8$16$32$64$
$$end$
init_timer@@TIMER_NUMBER@:
ld tmpreg0, #0$$TIME_CON$h
st tmpreg0, t@@TIMER_NUMBER@control[0]
$$if$ TIMER_INTERRUPT
SET_BIT_REG int_mask, 0 ;set epax interrupt mask
SET_BIT epa_mask1, OVR_TIMER@@TIMER_NUMBER@
$$end$
ret
$$ifn$ TIME_CON.3-5
; delay1:
; routine to delay at least (Xtal * 4 * ($$TIME_CON.0-2$+1)) * 'time'
; units of time.
delay@@TIMER_NUMBER@:
$$ifp$ 80C196NT || 80C196NQ
ld tmpreg0+2, 4[sp]
$$end$
$$ifp$ 80C196KT || 80C196KQ || 80C196KR || 80C196JR || 80C196JQ || 80C196JT
ld tmpreg0+2, 2[sp]
$$end$
ld tmpreg0, timer@@TIMER_NUMBER@[0] ;load start time
read_timer@@TIMER_NUMBER@_again:
ld tmpreg0+4, timer@@TIMER_NUMBER@[0] ;read current time
sub tmpreg0+4, tmpreg0 ;calculate elapsed time
cmp tmpreg0+4, tmpreg0 ;is elapsed > parameter
bnc read_timer@@TIMER_NUMBER@_again
ret
$$end$
$$if$ TIME_CON.5 && TIME_CON.4 && TIME_CON.3
rseg
speed: dsw 1
$$end$
$$ifp$ 80C196NT || 80C196NQ
cseg at 0ff2080h
$$end$
$$ifp$ 80C196KT || 80C196KQ || 80C196KR || 80C196JR || 80C196JQ || 80C196JT
cseg at 02080h
$$end$
main_timer@@TIMER_NUMBER@:
ld sp, #STACK
call init_timer@@TIMER_NUMBER@
; If the EPA unit is to be used with the timers, then the init
; EPA code should be called.
$$if$ TIMER_INTERRUPT
ei ;globally enable interrupts
$$end$
$$if$ TIME_CON.5 && TIME_CON.4 && TIME_CON.3
; In Quadrature clocking mode, reading the timer@@TIMER_NUMBER@
; at fixed intervals of time can give speed and
; direction. example:
ld tmpreg0, timer@@TIMER_NUMBER@[0]
push tmpreg0 ; save time value
; User's routine to delay some time
; push #10h ;some amount of time
$$if$ TIMER_NUMBER.0
; call delay2 ;delay routine using timer2
$$end$
$$if$ TIMER_NUMBER.1
; call delay1 ;delay routine using timer1
$$end$
; add sp, #2 ;clear stack
ld speed, timer@@TIMER_NUMBER@[0]
pop tmpreg0
sub speed, tmpreg0
; Speed now contains direction and magnitude of the quadrature
; clocked device.
$$end$
; The timer@@TIMER_NUMBER@ can now be used by the EPA or read at any time to
; obtain information on counting speed and or direction.
ret
$$if$ TIMER_INTERRUPT
; To have code generated for the timer interrupt,
; select the ICU design screen.
$$end$
end
##80C196NT Serial#
##80C196NQ Serial#
##80C196KT Serial#
##80C196KQ Serial#
##80C196KR Serial#
##80C196JR Serial#
##80C196JT Serial#
##80C196JQ Serial#
$$ifp$ 80C196NT || 80C196NQ
$model(NT)
$$end$
$include (80c196kr.inc)
SP_MODE0 set 000h
SP_MODE1 set 001h
SP_MODE2 set 002h
SP_MODE3 set 003h
REC_ENABLE set 008h
REC_DISABLE set 000h
EVEN_PARITY set 008h
ODD_PARITY set 028h
NO_PARITY set 000h
SET_BIT_8 set 010h
SP_INTERNAL_CLK set 08000h
SP_EXTERNAL_CLK set 00000h
TXD_INTERRUPT set 008h
RXD_INTERRUPT set 010h
TI_BIT set 005h
RI_BIT set 006h
FE_BIT set 004h
OE_BIT set 002h
RPE_BIT set 007h
RB8_BIT set 007h
TXE_BIT set 003h
rseg
sp_status_image: dsb 1
$$ifn$ INT_MASK1.4 |! INT_MASK1.3
$$ifn$ INT_MASK1.3 && P2_MODE.0
cseg
putchar:
clr_bit sp_status_image, TXE_BIT
check_TXE_ready:
orb sp_status_image, sp_status[0]
jbc sp_status_image, TXE_BIT, check_TXE_ready
clr_bit sp_status_image, TXE_BIT
$$if$ SP_CON.4
; If bit 8 needs to be set, then the following line needs to
; be inserted:
; ldb tmpreg0, sp_con[0]
; orb tmpreg0, #SET_BIT_8
; stb tmpreg0, sp_con[0]
$$end$
$$ifp$ 80C196NT || 80C196NQ
ld tmpreg0, 4[sp]
$$end$
$$ifp$ 80C196KT || 80C196KQ || 80C196KR || 80C196JR || 80C196JQ || 80C196JT
ld tmpreg0, 2[sp]
$$end$
stb tmpreg0, sbuf_tx[0]
ret
$$end$
$$ifn$ INT_MASK1.4 && P2_MODE.1
cseg
getchar:
ldb sp_status_image, sp_status[0]
jbc sp_status_image, RI_BIT, getchar
jbc sp_status_image, FE_BIT, no_frame_error
; User code for framing error
CLR_BIT_REG sp_status_image, FE_BIT
no_frame_error:
jbc sp_status_image, OE_BIT, no_overrun_error
; User code for overrun error
CLR_BIT_REG sp_status_image, OE_BIT
no_overrun_error:
$$if$ SP_CON.2
jbc sp_status_image, RPE_BIT, no_parity_error
; User code for Parity error
CLR_BIT_REG sp_status_image, RPE_BIT
no_parity_error:
$$end$
$$if$ SP_CON.4
jbc sp_status_image, RB8_BIT, no_8th_bit
; User code for Receiving BIT 8
CLR_BIT_REG sp_status_image, RB8_BIT
no_8th_bit:
$$end$
ldbze tmpreg0, sbuf_rx[0]
ret
$$end$
$$end$
$$if$ INT_MASK1.3-4
$$if$ INT_MASK1.4
$$ifp$ 80C196KT || 80C196KQ || 80C196KR || 80C196JR || 80C196JQ || 80C196JT
cseg at 2038h
rx_vector: dcw receive
$$end$
$$ifp$ 80C196NT || 80C196NQ
cseg at 0FF2038h
rx_vector: dcw LSW receive
$$end$
$$end$
$$if$ INT_MASK1.3
$$ifp$ 80C196KT || 80C196KQ || 80C196KR || 80C196JR || 80C196JQ || 80C196JT
cseg at 2036h
tx_vector: dcw transmit
$$end$
$$ifp$ 80C196NT || 80C196NQ
cseg at 0FF2036h
tx_vector: dcw LSW transmit
$$end$
$$end$
$$if$ INT_MASK1.3
TRANSMIT_BUF_SIZE set 20
$$end$
$$if$ INT_MASK1.4
RECEIVE_BUF_SIZE set 20
$$end$
$$if$ INT_MASK1.3
; transmit buffer and it's indexes
dseg
trans_buff: dsb TRANSMIT_BUF_SIZE
rseg
begin_trans_buff: dsb 1
end_trans_buff: dsb 1
$$end$
$$if$ INT_MASK1.4
; receive buffer and it's indexes
dseg
receive_buff: dsb RECEIVE_BUF_SIZE
rseg
end_rec_buff: dsw 1
begin_rec_buff: dsw 1
$$end$
cseg
$$if$ INT_MASK1.3
transmit: ;serial interrupt routine
pusha
push tmpreg0
; image sp_status into sp_status_image
ldb sp_status_image, sp_status[0]
; transmitt a character if there is a character in the buffer
; else leave TI_BIT set in image for putchar to enable interrupts
cmpb begin_trans_buff, end_trans_buff
je no_char_to_send
$$if$ SP_CON.4
; If bit 8 needs to be set, then the following line needs to
; be inserted:
; SET_BIT sp_con, SET_BIT_8
$$end$
ldbze tmpreg0, begin_trans_buff
ldb tmpreg0, trans_buff[tmpreg0]
incb begin_trans_buff
stb tmpreg0, sbuf_tx[0] ;tranmit character
; The next statement makes the buffer circular by starting over when the
; index reaches the end of the buffer.
cmpb begin_trans_buff, #TRANSMIT_BUF_SIZE-1
bnh not_at_end_of_buffer
clrb begin_trans_buff
not_at_end_of_buffer:
CLR_BIT sp_status_image,TI_BIT ;clear TI bit in sp_status_image.
no_char_to_send:
pop tmpreg0
popa
ret
putchar:
; Remain in loop while the buffer is full. This is done by checking
; the end of buffer index to make sure it does not overrun the
; beginning of buffer index. The while instruction checks the case
; when the end index is one less then the beginning index and at the
; end of the buffer when the beginning index may be equal to 0 and
; the end buffer index may be at the buffer end.
wait_for_buffer_ready:
addb tmpreg0, end_trans_buff, #1
cmpb tmpreg0, begin_trans_buff
je wait_for_buffer_ready
cmpb end_trans_buff, #TRANSMIT_BUF_SIZE-1
jne ready_to_send
cmpb begin_trans_buff, zero_reg
je wait_for_buffer_ready
ready_to_send:
$$ifp$ 80C196NT || 80C196NQ
ldb tmpreg0, 4[sp]
$$end$
$$ifp$ 80C196KT || 80C196KQ || 80C196KR || 80C196JR || 80C196JQ || 80C196JT
ldb tmpreg0, 2[sp]
$$end$
; put character in buffer
ldbze tmpreg0+2, end_trans_buff
stb tmpreg0, trans_buff[tmpreg0 + 2]
incb end_trans_buff
; make buffer circular.
cmpb end_trans_buff, #TRANSMIT_BUF_SIZE - 1
bnh not_at_end_of_buffer2
clrb end_trans_buff
not_at_end_of_buffer2:
jbc sp_status_image, TI_BIT, dont_set_interrupt
; if transmitt buffer was empty, then cause an interrupt
; to start transmitting.
orb int_pend1, #TXD_INTERRUPT
dont_set_interrupt:
ret
$$end$
$$if$ INT_MASK1.4
receive: ;serial interrupt routine
pusha
push tmpreg0 ;image sp_status into sp_status_image
ldb sp_status_image, sp_status[0]
; If the input buffer is full, the last character can be handled
; as desired.
add tmpreg0, end_rec_buff, #1
cmp tmpreg0, begin_rec_buff
je handle_overrun
cmp end_rec_buff, #RECEIVE_BUF_SIZE-1
jne ready_to_receive
cmpb begin_rec_buff, zero_reg
jne ready_to_receive ;not 0 so okay to receive
handle_overrun: ;input overrun code
ready_to_receive:
; The next statement makes the buffer circular by starting over when the
; index reaches the end of the buffer.
inc end_rec_buff
; Make a circular buffer.
cmp end_rec_buff, #RECEIVE_BUF_SIZE - 1
bnh not_at_end_rec_buffer
clr end_rec_buff
not_at_end_rec_buffer:
ldb tmpreg0, sbuf_rx[0]
stb tmpreg0, receive_buff[end_rec_buff]
; Check for errors.
jbc sp_status_image, FE_BIT, no_frame_error
; User code for framing error
CLR_BIT_REG sp_status_image, FE_BIT
no_frame_error:
jbc sp_status_image, OE_BIT, no_overrun_error
; User code for overrun error
CLR_BIT_REG sp_status_image, OE_BIT
no_overrun_error:
$$if$ SP_CON.2
jbc sp_status_image, RPE_BIT, no_parity_error
; User code for Parity error
CLR_BIT_REG sp_status_image, RPE_BIT
no_parity_error:
$$end$
$$if$ SP_CON.4
jbc sp_status_image, RB8_BIT, no_8th_bit
; User code for Receiving BIT 8
CLR_BIT_REG sp_status_image, RB8_BIT
no_8th_bit:
$$end$
CLR_BIT_REG sp_status_image,RI_BIT ;clear RI bit in sp_status_image.
pop tmpreg0
popa
ret
getchar:
cmp begin_rec_buff, end_rec_buff
je getchar
inc begin_rec_buff
cmp begin_rec_buff, #RECEIVE_BUF_SIZE - 1
bne not_at_end_rec_buf2
; Make buffer circular.
clr begin_rec_buff
; Return the character in buffer.
not_at_end_rec_buf2:
ldb tmpreg0, receive_buff[begin_rec_buff]
ret
$$end$
$$end$
cseg
init_serial:
ldb tmpreg0, #0$$SP_CON$h
stb tmpreg0, sp_con[0]
ld tmpreg0, #0$$SP_BAUD$h
st tmpreg0, sp_baud[0]
$$if$ P2_MODE.0
SET_BIT p2_reg,0 ;init txd pin output
CLR_BIT p2_dir,0 ;make txd pin output
SET_BIT p2_mode,0 ;enable txd mode on p2.0
$$end$
$$if$ P2_MODE.1
SET_BIT p2_reg,1 ;init rxd pin input
SET_BIT p2_dir,1 ;make rxd pin input
SET_BIT p2_mode,1 ;enable rxd mode on p2.1
$$end$
$$ifn$ SP_BAUD.15
SET_BIT p6_reg,2 ;init t1clk pin input
SET_BIT p6_dir,2 ;make t1clk pin input
$$end$
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -