This is the MPASM code for blinking led using the TIMER0 interrupt in pic16f676. The pin 0 (RA0) of portA is not toggling to off position. please help...
I'm newbie to pic assembly, I would like to master pic. is there any pic prodigies please help me to learn...
I need to blink at an interval of 1 sec. CODE is:
#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
It seems to bet the delay problem. But shuffling the pre-scalar and counter keeps led in on position. I need to On and Off Led.
Here are some problems I detected in your code...
1. Wrong port initialization
As I have mentioned in this answer your init code lacks code for
CMCON, the register that controls the analog comparators modue. Here is how you should set it up correctly:2. Your timer setup will not give you a 1 second delay
You set the prescaler to 1:128, means that the timer will be incremented on every 128us.
Your timer reload value is 10, means that it will count 245 until it overflows. Then your overflow rate is
128us * 245 = 31360us.In order to produce 1 sec delay from this value you should use a helper variable and set it to
1000000 / 31360 = 31.8877let's round it up to 32 in decimal. So you should load theMyCountvariable with 32 in order to generate a 1 sec delay in total.But your actual value is 18 in decimal, that would make a
18 * 31360 = 564.480mswhich is approximately half a second.3. Incorrect interrupt handling
Let's see your timer0 interrupt handler code first.
You should have cleared the timer0 flag everytime the timer0 hits the interrupt. But you clear it only when your counter reaches to zero. But here is the problem: the program will get stuck in the timer interrupt until its flag gets cleared. So the
DECFSZ MyCount, 1instruction will be executed very rapidly due to the successive calls to the timer interrupt, resulting in a very fast flashing of the output pin. Hence no eyes will catch it is flashing.Another problem is that you don't reload the
MyCount's value after it reaches the zero. This will cause that the variable underflow to 255 and after the first time it always will keep counting down from 255.So what you should do is to clear the flag and reload the timer0 value everytime the interrupt gets hit, regardles the value of the counter. You should also reload the
MyCountvalue so that it keeps counting down from the calculated value. Finally the correct flow in the timer interrupt would be as following:Apply the above fixes into your code and try it again. Let me know the result.