这是使用图16f676中的TIMER0中断使LED Flink 的MPASM代码。端口A的引脚0(RA0)未切换到关闭位置。请帮帮我
我是新手图片组装,我想掌握图片。有没有什么绘画天才,请帮助我学习……
我需要每隔1秒眨眼一次。代码是:
#include "p16F676.inc"
__CONFIG _FOSC_INTRCIO & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _BOREN_OFF & _CP_OFF & _CPD_OFF
MyCount EQU 0x20
RES_VECT CODE 0x0000
GOTO CODE_INIT
ISR CODE 0x0004
GOTO ISR_HANDLER
;MAIN_PROG CODE
CODE_INIT:
CALL PORT_INIT
CALL TIMER_INIT
GOTO IDLE_LOOP
ISR_HANDLER:
DECFSZ MyCount, 1
RETFIE
movlw 0x01
xorwf PORTA, F
BCF INTCON, TMR0IF
MOVLW d'10'
MOVWF TMR0
RETFIE
IDLE_LOOP:
NOP
NOP
NOP
NOP
GOTO IDLE_LOOP
PORT_INIT:
BSF STATUS, RP0
MOVLW b'00000000'
MOVWF ADCON1
MOVWF ANSEL
MOVWF TRISA
RETURN
TIMER_INIT:
CLRWDT
MOVLW b'00000110'
MOVWF OPTION_REG
BSF INTCON, GIE
BSF INTCON, TMR0IE
BCF STATUS, RP0
MOVLW d'18'
MOVWF MyCount
BCF INTCON, TMR0IF
MOVLW d'10'
MOVWF TMR0
RETURN
END
它似乎打赌延迟的问题。但 Shuffle 的前标量和计数器保持领先的地位。我需要打开和关闭LED。
1条答案
按热度按时间x7rlezfr1#
下面是我在你的代码中发现的一些问题。
1.端口初始化错误
正如我在this answer中提到的,您的init代码缺少
CMCON
的代码,CMCON
是控制模拟比较器modue的寄存器。以下是您应该如何正确设置它:2.您的计时器设置不会给您给予1秒的延迟
将预分频器设置为1:128,意味着计时器将每128 us递增一次。
您的计时器重新加载值为10,意味着它将计数245,直到溢出。那么溢出率是
128us * 245 = 31360us
。为了从这个值产生1秒的延迟,你应该使用一个辅助变量,并将其设置为
1000000 / 31360 = 31.8877
,让我们将其舍入为十进制的32。因此,您应该将MyCount
变量加载为32,以生成总共1秒的延迟。但你的实际值是十进制的18,这将使
18 * 31360 = 564.480ms
大约是半秒。3.错误的中断处理
让我们先看看你的定时器0中断处理程序代码。
每次计时器0触发中断时,您都应该清除计时器0标志。但只有当计数器归零时才能清除。但问题来了:则程序将在定时器中断中卡住,直到其标志被清除。因此,
DECFSZ MyCount, 1
指令将由于对定时器中断的连续调用而非常快速地执行,从而导致输出引脚非常快速地 Flink 。因此,没有眼睛会抓住它 Flink 。另一个问题是,在
MyCount
的值为零后,您不会重新加载它。这将导致变量下溢到255,并且在第一次之后,它总是从255开始倒数。因此,你应该做的是清除标志,并重新加载计时器0值每次中断得到命中,计数器的值。您还应该重新加载
MyCount
值,以便它从计算值开始倒数。最后,定时器中断的正确流程如下:将上述修复应用到您的代码中,然后重试。告诉我结果。