以下是我在您的代码中发现的一些问题...
1.端口初始化错误
正如我在中提到的这个答案 https://stackoverflow.com/a/77071601/12749998你的初始化代码缺少代码CMCON
,控制模拟比较器模式的寄存器。以下是正确设置的方法:
BCF STATUS,RP0 ;Bank 0
CLRF PORTA ;Init PORTA
MOVLW 05h ;Set RA<2:0> to
MOVWF CMCON ;digital I/O
BSF STATUS,RP0 ;Bank 1
CLRF ANSEL ;digital I/O
CLRF TRISA ;set all pins as outputs
BCF STATUS,RP0 ;Bank 0
2.你的定时器设置不会给你1秒的延迟
您将预分频器设置为 1:128,意味着定时器将每 128us 递增一次。
您的计时器重载值为 10,这意味着它将计数 245 直到溢出。那么你的溢出率为128us * 245 = 31360us
.
为了从此值产生 1 秒延迟,您应该使用辅助变量并将其设置为1000000 / 31360 = 31.8877
我们将其四舍五入为十进制的 32。所以你应该加载MyCount
变量为 32,以便总共生成 1 秒的延迟。
但你的实际值是十进制的 18,这将是18 * 31360 = 564.480ms
大约是半秒。
3. 不正确的中断处理
让我们先看看你的timer0中断处理程序代码。
ISR_HANDLER:
DECFSZ MyCount, 1
RETFIE
movlw 0x01
xorwf PORTA, F
BCF INTCON, TMR0IF
MOVLW d'10'
MOVWF TMR0
RETFIE
每次timer0 遇到中断时,您都应该清除timer0 标志。但只有当计数器达到零时才将其清除。但问题是:程序将陷入定时器中断,直到其标志被清除。所以DECFSZ MyCount, 1
由于连续调用定时器中断,指令将非常快速地执行,导致输出引脚非常快速地闪烁。因此没有人的眼睛会发现它在闪烁。
另一个问题是你没有重新加载MyCount
达到零后的值。这将导致变量下溢到 255,并且在第一次之后它将始终从 255 开始倒数。
因此,您应该做的是清除标志并在每次中断发生时重新加载timer0值,无论计数器的值如何。您还应该重新加载MyCount
值,以便从计算值开始不断倒计时。最后,定时器中断的正确流程如下:
ISR_HANDLER
bcf INTCON, TMR0IF
movlw d'10'
BANKSEL TMR0 ; Make sure you're in correct data bank
decfsz MyCount, 1
retfie
movlw d'32'
BANKSEL MyCount ; Again make sure you're in correct bank
movwf MyCount
; PORTA and MyCount are in the same bank since MyCount's address is 0x20
movlw 1
xorwf PORTA, F ; Toggle output due to 1 sec time out
retfie
将上述修复应用到您的代码中,然后重试。让我知道结果。