An application using the 16F873A requires three interrupts t
Solution
Timer0 has a register called TMR0 Register, which is 8 bits of size.
We can write the desired value into the register which will be increment as the program progresses. Frequency varies depending on the Prescaler. Maximum value that can be assigned to this register is 255.
Just notice the PULLUPs are enabled when RBPU is 0. Also RB4 must be configured as input to alow interrupt be generated.
In the ISR you CAN NOT read PORTB or execute BCF or BSF (because any reading of PORTB or any Read-modify-write instruction like BCF or BSF on PORTB can reset RBIF) until you check RBIF!!!
At some point in ISR you probably have something like:
but if you did read PORTB before this, your PROCESS INTERUPT ON CHANGE routine will never be executed because RBIF is reseted.
Also in the main program reading of PORTB is not recommended when use interrupt on change because of the same reason. An interrupt can happen exact on the instruction which read PORTB (i.e. movf PORTB,w) and in such situation RBIF will be set but current instruction must be executed first, before jump to ISR. But executing that instruction will cause RBIF to be cleared (reading of PORTB will fill internal latch with current pin states on PORTB and it means there is no difference between external pin states and latch states and result of such comparation will clear RBIF) and interrupt will not be generated.
If you use any of RB7:RB5 or RB3:RB1 as an output and if these outputs can not be synchronized through INTERRUPT ON CHANGE routine then I suggest to use a timer and in the ISR on timer interrupt check PORTB pins rather then using INTERRUPT ON CHANGE feature.
The A/D module has four registers.
These registers are: • A/D Result High Register (ADRESH)
• A/D Result Low Register (ADRESL)
• A/D Control Register 0 (ADCON0)
• A/D Control Register 1 (ADCON1)
