Assembly 用于pic 16f84A的汇编语言TMR0
我试图在我的代码中使用TMR0来让一个蜂鸣器在一辆小车上工作,但是我很难使用它,我已经花了4个小时试图让我的头绕过它,所以现在我在这里寻求帮助,这将是感激的,小车运行在4Mhz,蜂鸣器在端口B上是位0,理想情况下,我希望它在倒车时能嗡嗡作响,但在这一点上,我只想让它嗡嗡作响一次 这是代码,如您所知,小车在按下按钮后向前移动,它将反转一小段时间,然后继续旋转90度,然后再次向前移动并重复此操作Assembly 用于pic 16f84A的汇编语言TMR0,assembly,microcontroller,pic,Assembly,Microcontroller,Pic,我试图在我的代码中使用TMR0来让一个蜂鸣器在一辆小车上工作,但是我很难使用它,我已经花了4个小时试图让我的头绕过它,所以现在我在这里寻求帮助,这将是感激的,小车运行在4Mhz,蜂鸣器在端口B上是位0,理想情况下,我希望它在倒车时能嗡嗡作响,但在这一点上,我只想让它嗡嗡作响一次 这是代码,如您所知,小车在按下按钮后向前移动,它将反转一小段时间,然后继续旋转90度,然后再次向前移动并重复此操作 ; Buggy.ASM 11MAR02 ;::::::::::::::::::::::::::::::
; Buggy.ASM 11MAR02
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Configuration data
; PICmicro MCU type: 16F84
; Oscillator: XTAL mode, fast, VR1 fully clockwise (max.rate)
; LCD display: off
; 7-segment display: off
; Version 2 board settings: J14 links: Digital
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
; The following line embeds configuration data into the PICmicro
LIST P=16F84
__CONFIG H'3FFA' ; XTAL mode
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; using aliases, bit names and conditional loops
#DEFINE PAGE0 BCF STATUS,5
#DEFINE PAGE1 BSF STATUS,5
STATUS EQU H'03' ; STATUS register
TRISB EQU H'86' ; Port B direction register
PORTB EQU H'06' ; Port B data register
TRISA EQU H'85' ; Port A direction register
PORTA EQU H'05' ; Port A data register
OPSHUN EQU H'81' ;OPTION_REGISTER
INTCON EQU H'0B' ;INTCON REGISTER
TMR0 EQU H'01' ;
TMRCNT EQU H'20' ;TMR COUNT
d1 EQU H'22' ;
d2 EQU H'23' ;
d3 EQU H'24' ;
ORG 0 ; Reset vector
GOTO 5 ; Goto start of program
ORG 4 ; Interrupt vector
GOTO BUZZ ; Goto BUZZ
ORG 5 ; Start of program memory
CLRF PORTB ; clear Port B data register
CLRF PORTA ;
PAGE1 ; PAGE1
MOVLW B'11000010' ;
MOVWF OPSHUN ;set timer ratio to 1:8 (TMR0 rate)
MOVLW B'11111111' ;
MOVWF TRISA ; Set port A to input
CLRF TRISB ; Port B direction register for output
PAGE0
MOVLW B'10100100' ;
MOVWF INTCON
CLRF TMR0
MOVLW D'15' ;
MOVWF TMRCNT ;
FORWARD MOVLW D'80'
MOVWF PORTB ; Set Port B to 80
BTFSC PORTA,0 ;
GOTO BACK_R ;BACK RIGHT
BTFSC PORTA,1 ;
GOTO BACK_L ;BACK LEFT
GOTO FORWARD ;
BACK_R
MOVLW D'164' ;
MOVWF PORTB ;
BCF INTCON,2 ; ENABLE TMR0 INTTERUP
CALL DELAY_R ;
MOVLW D'148' ;
MOVWF PORTB ;
CALL DELAY_R ;
GOTO FORWARD ;
BACK_L
MOVLW D'162' ;
MOVWF PORTB ;
BCF INTCON,2 ; ENABLE TMR0 INTTERUP
CALL DELAY_R ;
MOVLW D'98' ;
MOVWF PORTB ;
CALL DELAY_R ;
GOTO FORWARD ;
BUZZ
BSF PORTB,0
DECFSZ TMRCNT ;
GOTO BUZZ
MOVLW d'15' ;RESET THE DELAY COUNTER
MOVWF TMRCNT ;
BCF PORTB,0
RETFIE
DELAY_R
movlw 0xFF
movwf d1
movlw 0xFF
movwf d2
movlw 0x05
movwf d3
goto Delay_0
DELAY_T
movlw 0xFF
movwf d1
movlw 0xFF
movwf d2
movlw 0x05
movwf d3
Delay_0
decfsz d1, f
goto Delay_0
decfsz d2, f
goto Delay_0
decfsz d3, f
goto Delay_0
;4 cycles
return
END ; final statement
在你的中断程序中有一些问题。一个是您没有清除定时器0中断标志(
T0IF
在INTCON
寄存器中)。您可以在BUZZ
例程的开始处添加此选项:
BCF INTCON,2
如果不这样做,下次就不会触发中断
另一个问题是:
GOTO BUZZ
在这里,您可以在循环中非常快速地减小TMRCNT
,然后在蜂鸣器归零时关闭蜂鸣器。这样,你几乎听不到蜂鸣器的声音。您应该将其替换为RETFIE
关闭蜂鸣器后,还需要关闭定时器0中断。所以你会得到这样的结果:
BUZZ
BCF INTCON,2 ; clear Timer0 interrupt flag
BSF PORTB,0 ; turn buzzer on
DECFSZ TMRCNT
RETFIE ; return to main program, keeping buzzer on until next interrupt
MOVLW D'15' ; reset the delay counter
MOVWF TMRCNT
BCF PORTB,0 ; turn buzzer off
BCF INTCON,5 ; disable Timer0 interrupts
RETFIE
此外,在其他函数中,无论何时向端口B
寄存器写入内容,都必须注意不要覆盖位0,该位将控制蜂鸣器
您还应在代码中将BCF INTCON,2
替换为BSF,INTCON,5
,并用B'10000100'
初始化INTCON