⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t1_tx_moto_pcm.asm

📁 一款智能老鼠的玩具源代码
💻 ASM
字号:
;****************************************************************;
; Timer1 Service Routine
;
; Generate motor control pulse and Play sound
; Timer1 frequency: 8K 
; Motor control pulse frequency:  
;
; Written by: lixy
; Date: 2004-02-14
;****************************************************************;

;================================================================;
;Constant Area
;================================================================;
c_prtc0_0		equ	#11111110b
c_prtc0_1		equ	#00000001b
c_prtd0_1		equ	#00000001b
c_prtd1_1		equ	#00000010b
c_prtd2_1		equ	#00000100b
c_prtd012_1		equ	#00000111b
c_ir_transmit		equ	#5
c_ir_transmit_l		equ	#5
c_ir_transmit_h		equ	#13
c_ir_group		equ	#12
cnt_ir_transmit_high	equ	#4            ;05ms/(1/8k)=4
cnt_ir_tx_lead		equ	#20           ;2.5ms/(1/8k)=4
cnt_ir_tx_data_0		equ	#4            ;0.5ms/(1/8k)=4
;cnt_ir_tx_data2		equ	#4            ;0.5ms/(1/8k)=4
cnt_ir_tx_data_1		equ	#12           ;1.5ms/(1/8k)=12
;cnt_ir_tx_data2r	equ	#12           ;1.5ms/(1/8k)=12
cnt_ir_tx_stop		equ	#4            ;0.5ms/(1/8k)=12
cnt_ir_rcv_max		equ	#29           ;3.625ms
c_ir_tx_data		equ	#00001111b	;ir transmit data mouse_self
;================================================================;
;Timer1 Data Area
;================================================================;
       .area       time1_var(data)
       
temp_a_1::		.ds	1	;store the acc value
temp_op1_1::		.ds	1
temp_dp_1::		.ds	1
cnt_timer1::		.ds	1	;the interrupt times counter
cnt_ctrl_pulse::	.ds	2	;the motor control pulse counter

cnt_ir_transmit::	.ds	1
;cnt_ir_group::		.ds	1
cnt_ir_rcv::		.ds	1
;//status_ir_rcv is defined in IR_RCV_INT
;status_ir_rcv::		.ds	1	;0 states no data received,1 is lead received ok
;2 is data1 received ok,3 is data2 received ok,4 is data1 reverse ok,5 is data2 reverse ok
;6 is mouse_self ok,7 states cheese broadcast sign received,8 states cheese touched received.
;cnt_ir_rcv_f::		.ds	1
;cnt_ir_rcv_l::		.ds	1
;cnt_ir_rcv_r::		.ds	1
flg_ir_judge::		.ds	1
flg_ir_transmit::	.ds	1
status_ir_transmit::	.ds	1	;0 is not transmit,1 is preamble,2 is data1(0),3 is data2(0)
;4 is data1 reverse(1),5 is data2 reverse(1),6 is stop bit
flg_ir_transmit_high::	.ds	1	;when it is set to 1, not transmit 38k
cnt_ir_tx_data::	.ds	1	;ir transmit data 00001111b
flg_ir_tx_1::		.ds	1	;tx 1 flag
;================================================================;
; PCM Speech Subroutine
;================================================================;
          ;.area   pcmvari(data)
;-------------------------------------
M_sphptr::      .ds     3
M_stopbit::	.ds	1
M_pcmdata::	.ds	1
;================================================================;
;Timer1 Code Area
;================================================================;
       .area       timer1_isr(code)

t1_isr::
	sta	temp_a_1		;save register A
	lda	r_op1			;save register OP1
	sta	temp_op1_1
	lda	r_dp			;save register DP
	sta	temp_dp_1
	call	motor_control_pulse	
	lda 	status_ir_transmit
	cmpe 	#0			;if status=0,yes,no need transmit
	brz	p_skip_tx
	call 	ir_transmit		;need transmit
p_skip_tx:
;//Receive IR count
	lda	cnt_ir_rcv		;receive IR count*125us
	inca
	sta	cnt_ir_rcv
	cmpe	#cnt_ir_rcv_max		;cnt_ir_rcv>=cnt_ir_rcv_max, c=1	
	brnc	t1_isr_play	        ;cnt_ir_rcv<max,receiver ir normal,skip
	lda	#0
	sta	cnt_ir_rcv
	sta	status_ir_rcv
       
t1_isr_play:
	lda	#0ffh			;检查是否播发完?
	cmpe	M_stopbit
	brz	t1_isr_end
	call	Pcm_Play
	lda	M_pcmdata
	sta	r_pwmc
t1_isr_end:        
	lda	temp_dp_1		;restore register DP
        sta	r_dp
	lda	temp_op1_1		;restore register OP1
	sta	r_op1
	lda	temp_a_1		;restore register A
        reti

;--------------------------------------------------------------------;
;IR Transmit and Receive Subroutine
;IR transmit pin: PRTC.0 ("1" not transmit, "0" transmit)
;IR receive pins: PRTD.7 (front)

ir_transmit:
	lda	cnt_ir_transmit		;发射的信号的电平长度计数
	inca
	sta	cnt_ir_transmit
	lda 	flg_ir_transmit_high	;1 stop 38k
	cmpe	#0
	brz	ir_transmit_low         ;=0,goto low
	lda 	cnt_ir_transmit         ;high
	cmpe	#cnt_ir_transmit_high    ;0.5ms/125us=4,
	brz	ir_transmit_next_bit         ;=4 will enter the next status(low)
	ret				 ;continue hold high
ir_transmit_next_bit:
	lda 	cnt_ir_tx_data
	adda	#0	;clear cy
	rolc
	sta	cnt_ir_tx_data
	lda	#0
	sta	flg_ir_tx_1	;clear 0
	addc	flg_ir_tx_1
	sta	flg_ir_tx_1     ;set cy
	lda	r_prtc			;when prtc.0 is low, 38k carrier pulse pass-by.
	anda	#c_prtc0_0
	sta	r_prtc	
	lda	#0
	sta	cnt_ir_transmit		;clear the counter,repeat count
	sta 	flg_ir_transmit_high	;0 to transmit 38k
	lda	status_ir_transmit
	inca	
	sta	status_ir_transmit
	cmpe	#11
	brc	ir_transmit_over
	ret 
ir_transmit_over:                      ;stop bit,shouldn't have this status 
	lda	r_prtc			;when prtc.0 is high, not transmit ir.
	ora	#c_prtc0_1		;把PC[1]置高
	sta	r_prtc
	ret
ir_transmit_low:
	lda	status_ir_transmit
	cmpe	#1			;is lead preamble?
	brnz	ir_transmit_data_low
	lda	cnt_ir_transmit         ;transmit lead code
	cmpe	#cnt_ir_tx_lead
	brc	ir_transmit_low_00      ;>=,turn to high 0.5ms
	lda	r_prtc			;continue tx 38k,when prtc.0 is low, 38k carrier pulse pass-by.
	anda	#c_prtc0_0
	sta	r_prtc	
	lda	#c_ir_tx_data           ;set initial value #00001111b
	sta	cnt_ir_tx_data
	ret
ir_transmit_data_low:
	cmpe	#10			;is stop bit?
	brc	ir_tx_data_low_over
	lda	flg_ir_tx_1
	cmpe	#1
	brz	ir_transmit_data_1
	lda	cnt_ir_transmit          ;flg_ir_tx_1=0 
	cmpe	#cnt_ir_tx_data_0
	brz	ir_transmit_low_00
	lda	r_prtc			;continue tx 38k,when prtc.0 is low, 38k carrier pulse pass-by.
	anda	#c_prtc0_0
	sta	r_prtc	
	ret   
ir_transmit_data_1:
	lda	cnt_ir_transmit         ;tx 1(low)
	cmpe	#cnt_ir_tx_data_1
	brz	ir_transmit_low_00
	lda	r_prtc			;continue tx 38k,when prtc.0 is low, 38k carrier pulse pass-by.
	anda	#c_prtc0_0
	sta	r_prtc	
	ret        
ir_transmit_low_00:
	lda	#1
	sta 	flg_ir_transmit_high	;1 stop 38k
	lda	#0
	sta	cnt_ir_transmit		;repeat start counting
	lda	r_prtc			;when prtc.0 is high, not transmit ir.
	ora	#c_prtc0_1		;把PC[1]置高
	sta	r_prtc
	ret
ir_tx_data_low_over:
	lda	cnt_ir_transmit
	cmpe	#cnt_ir_tx_stop
	brz	ir_tx_end
	lda	r_prtc			;continue tx 38k,when prtc.0 is low, 38k carrier pulse pass-by.
	anda	#c_prtc0_0              ;wait for end
	sta	r_prtc	
	ret
ir_tx_end:
	lda	#0
	sta	status_ir_transmit
	sta	cnt_ir_transmit
	sta 	flg_ir_transmit_high	;1 stop 38k
	lda	r_prtc			;when prtc.0 is high, not transmit ir.
	ora	#c_prtc0_1		;把PC[1]置高
	sta	r_prtc
	ret	

;--------------------Play PCM----------------------------------------------        
Pcm_Play:
	lda	M_sphptr+2	
	sta	r_tpp
        lda     M_sphptr+1
        sta     r_tph
        lda     M_sphptr
        sta     r_tpl
        inca
        sta     M_sphptr
        lda     #00h
        addc    M_sphptr+1
        sta     M_sphptr+1
        lda	#00h
        addc	M_sphptr+2
        sta	M_sphptr+2
;//20040630,since the rom size is smaller than 64k, as for 89c21,the following code is redundancy        
;loop_rom_ready:        
;       lda	r_op1			;if data rom grand than 64k
;      anda	#10000000b		;program must detect OP1[7]
;       brz	loop_rom_ready		;or add 5us delay in program
        ldv
        xora    #0xFF
        brz     10$
        xora    #0xFF
        sta     M_pcmdata
        ret
10$:
        lda     #0xFF
        sta     M_stopbit
play_over:
	;call	tail
;	lda	#00h
;	sta	r_voc			;close PWM and D/A
	ret
;----------------------------------------------------------------;
;Motor Control Pulse Subroutine
;Motor 1 driver circuit controlled by the input1,input2.
;Motor 2 driver circuit controlled by the input3,input4.
;Motor1: input1-----PRTD.3    Motor2: input3-----PRTD.5
;        input2-----PRTD.4            input4-----PRTD.6
;----------------------------------------------------------------;
motor_control_pulse::
	lda	cnt_timer1
	inca
	sta	cnt_timer1
	cmpe	m_ctrl_t1		;这寄存器在查表中得到
	brz	ctrl_pulse_1st_part
	cmpe	m_ctrl_t2
	brz	ctrl_pulse_2nd_part
	ret
ctrl_pulse_1st_part:			;
	lda	r_prtd
	ora	m_prtd_ctrl_1_1		;不理解为什么这样做(是输出高电平吗?但好象****)	
	sta	r_prtd			;PWM valid levels are finished,will output high to all(the 2cnd level)
	br	motor_ctrl_pulse_end
ctrl_pulse_2nd_part:
	lda	r_prtd
	anda	m_prtd_ctrl_2_0
	ora	m_prtd_ctrl_2_1
	sta	r_prtd
	lda	#00h
	sta	cnt_timer1
	;adda	#00h			;clear c
	lda	cnt_ctrl_pulse		;时间长度计数
	inca
	sta	cnt_ctrl_pulse
	lda	cnt_ctrl_pulse+1
	addc	#00h
	sta	cnt_ctrl_pulse+1
	cmpe	m_ctrl_pulse+1		;counter's high 8bit compare with the set value
	brnc	motor_ctrl_pulse_end	;if it is lower than the set value, go on counting.
	lda	cnt_ctrl_pulse
	cmpe	m_ctrl_pulse		;counter's low 8bit compare with the set vlaue
	brnc	motor_ctrl_pulse_end	;if it is lower than the set value, go on counting.
	lda	#00h			;/*04-02-19*/
	sta	cnt_ctrl_pulse
	sta	cnt_ctrl_pulse+1
	lda	#1
	sta	flg_new_random
motor_ctrl_pulse_end:
	ret        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -