|
SOFTWARE
list p=16F84A
#include "p16f84A.inc"
__CONFIG
_CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
cblock 0x0c ;Declaring variables
count
level
sel_delay
dir
endc
;************************* MACRO
**************************************
send1
macro dir ;Macro for sending high to portA
banksel PORTA
btfsc dir,0 ;If dir=0 rotate CLOCKWISE else
ANTI-CLOCKWISE
goto next16
goto next15
next15:bsf PORTA,0 ;Setting or Resetting the PORTA pins
bsf PORTA,1 ;For CLOCKWISE direction
bcf PORTA,2
bcf PORTA,3
goto next19
next16:bcf PORTA,0 ;Setting or Resetting the PORTA pins
bcf PORTA,1 ;For ANTI-CLOCKWISE direction
bsf PORTA,2
bsf PORTA,3
goto next19
next19:
ENDM
send0
macro ;Macro for sending low to portA
banksel PORTA ;Resetting the PORTA pins done here
bcf PORTA,0
bcf PORTA,1
bcf PORTA,2
bcf PORTA,3
ENDM
org 0x00 ;Reset vector address
goto MAIN ;Begining of main programm
org 0x04 ;Interrupt vector address
goto int_service ;Beginig of interrupt routine
;************************ MAIN PROGRAM
********************************
MAIN
banksel TRISA ;Select BANK1
movlw 0x00
movwf TRISA ;Set PORTA as output port
movlw 0xff
movwf TRISB ;Set PORTB as input1
movlw 0x00 ;Regester for indicating 1 or 0 for PORTA
pins
movwf level ;By default high is sected
banksel PORTA
movlw 0x03
movwf PORTA ;Initialise PORTA (pin 0,1) as high
movlw 0x37
movwf TMR0 ;Initialise TIMER0
movlw 0x00 ;Regester for indicating SPEED of motor
movwf sel_delay ;By defult maximum speed is selected
movlw 0x00 ;Regester for indicating DIRECTION of motor
movwf dir ;By default ANTI-CLOCKWISE is selected
banksel INTCON ;Enable PORTB(bit3=0)EXTERNAL
INTERRUPT(bit4=0)
movlw b'10111000' ;TIMER0 (bit 5=0) interrupts
movwf INTCON
loop:
banksel OPTION_REG
btfsc sel_delay,0;If el_delay=0prescaler=1:256 else prescaler=1:1
goto next20
goto next21
next20:
banksel OPTION_REG ;Intialise OPTION_REG with 000 for TIMER0
movlw 0x00 ;Prescaler=1:1 ,and bit 7(=0) for
activating
movwf OPTION_REG ;"PULL UP" resistor of the PORTB
goto end_rt
next21:
banksel OPTION_REG
movlw 0x07 ;Intialise OPTION_REG with 111 for
movwf OPTION_REG ;TIMER0 prescaler=1:256
goto end_rt
end_rt:
goto loop ;Main programm ends here
;***************** INTERRUPT SERVICE ROUTINE
**************************
int_service
banksel PORTA ;Select BANK0
btfsc INTCON,2 ;Check for TIMER0 overflow interupt
goto isr_time ;if occured goto TIMER0 ISR
btfsc INTCON,0 ;Check for PORTB(Pin 4/5/6/7)interrupt
goto isr_prtrinc ;if occured goto PORTB ISR
btfsc INTCON,1 ;Check for EXTERNALINTERRUPT (RB0/INT)
goto isr_direct ;if occured got EXTERNAL ISR
;///////////////////// TIMER OVERFLOW ISR
/////////////////////////////
isr_time:
btfss level,0 ;If level=0 (bit 0) call send0 macro
goto next4
decf level,1 ;Else update level
banksel TMR0 ;Select BANK0
movlw 0xc8
movwf TMR0 ;Initialise TIMER0 with 'ON' time
send1 dir ;send HIGH to PORTA pins (MACRO)
goto end_isr
next4:
banksel TMR0
movlw 0x37 ;Initialise TIMER0 with 'OFF' time
movwf TMR0
send0 ;Send LOW to PORTA pins (MACRO)
banksel PORTA
incf level ;Update level
goto end_isr
;///////////////////// PORTB ISR
//////////////////////////////////////
isr_prtrinc:
banksel PORTB ;If there is an Interrupt on PORTB Pin 4
btfsc PORTB,5 ;Alternativelly select max. and min. speed
goto end_isr
incf sel_delay,1 ;sel_delay(bit0)changes to 0and1
alternatively
goto end_isr
;///////////////////// EXTERNAL ISR
///////////////////////////////////
isr_direct:
banksel PORTB ;If INTERRUPT on RB0/INT pin occured
btfsc PORTB,0 ;Regester dir = 0 for CLOCKWISE ROTATION
goto end_isr ; dir = 1 for ANTI-CLOCKWISE
ROTATION
incf dir,1 ;Incriment Direction regester (bit0=1)
goto end_isr
end_isr:bcf INTCON,0 ;Clear PORTB INTERRUPT FLAG
bcf INTCON,1 ;Clear TIMER OVER FLOW FLAG
bcf INTCON,2 ;Clear EXTERNAL INTERRUPT FLAG
retfie ;Return from ISR enabling GLOBAL INTERRUPT
FLAG
END ;END OF THE PROGRAMM
|