DC Motor Controlling System using PIC

This is assembly language program for PIC IC16F84A. This program controls A DC motor’s Speed and Direction using Interrupts.

Interrupts used : Timer0 overflow Interrupt, External Interrupt, PORTB Inerrupt
Timers used      : TIMER0
Ports used        : PORTA as output, PORTB as input

Program:

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

Editorial Team
Editorial Team

We are a group of young techies trying to provide the best study material for all Electronic and Computer science students. We are publishing Microcontroller projects, Basic Electronics, Digital Electronics, Computer projects and also c/c++, java programs.

17 thoughts on “DC Motor Controlling System using PIC

  1. I am interested to do project on bidirectional 12V dc motor with clock and anti-clockwise Directional rotation.kindly help me by providing source code using PIC16f84A and schematic of the same.

    Thanks & Regards
    Vinoth kumar.G

  2. The solutions to my inquiries have been very easy to take in thanks to this blog. It is certainly worth reading to aid relieve the stress I have been encountering. I suggest this for an award.

Leave a Reply

Your email address will not be published. Required fields are marked *

Get the latest updates on your inbox

Be the first to receive the latest updates from Codesdoc by signing up to our email subscription.

    StudentProjects.in