PIC Projects

Controlling speed and direction of two motors

The motor direction is controlled by buttons connected to ports A4 and A5. Pushing the button changes the direction rotation of the corresponding motor. Releasing a button returns the motor direction to its original state. Both motors run from a single PWM controlled by the pot. Moving the pot tip towards its upper end on the schematic leads to increasing the rotation speed.

To control the motor speed we use PWM as in the previous experiments. The PIC reads the voltage coming out of the pot, which is in the range 0..5V, and redirects it to a built-in ADC with a 10-bit resolution. In this case, however, its two lower bits are ignored. The range of ADC values (0..255) is send directly to the PWM duty cycle ratio control register. This way we get an 8-bit PWM resolution. The PWM period is set to 244Hz.

Schematic Layout

The main part of the program is an endless loop. At each iteration of this loop we read the ADC value and the buttons stati. The input ports A4 and A5 have weak pull-ups enabled. This results in the logical 1 value at these inputs if the buttons are not pushed. Pushing a button modifies this value to 0 and this is used to modify the direction of the corresponding motor. The direction is modified by complementing the corresponding pair of outputs RC3, RC4 or RC1, RC2. The complementing changes the voltage signs on the motor pins.

Note that in this implementation the motor speed is the same, since they are controlled by a single PWM. It is important to know that PWM runs in its own thread and releases the CPU for other operations. There is just one PWM thread in PIC16F684. Due to a difference of motor parameters, the control is not very reliable at very low voltages, as one or both motors might not rotate at all as they need a certain voltage to start. Furthermore, by the same reason the rotation speed at very low voltages might be different. This difference disappears as the pot tip moves about 1/4 of its range counted from the grounded end.

The code is as follows:

 TITLE  "pwm_mot2.asm"          	; PWM control of two motors
 List P=PIC16F684, R=DEC
 INCLUDE "p16f684.inc"

; data segment
 CBLOCK 0x20                   
 del  					; variable used for delay
 temp					; local temp variable	
 ENDC

; code segment
 PAGE
 __CONFIG _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & 
  _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT

  org 0                      		; start program at the beginning of mem
	bcf	STATUS, RP0		; activate BANK 0
	clrf	PORTA			; initialize PORT A
	clrf	PORTC			; initialize PORT C
	movlw	0x07
	movwf	CMCON0			; comparators OFF
	bsf    	STATUS, RP0      	; change to BANK 1
	bcf	OPTION_REG ^ 0x80,7 ; enable pull-ups globally 
	bsf	WPUA ^ 0x80, 4		; enable weak pull-us on A4,A5
	bsf	WPUA ^ 0x80, 5

 	; ADC and PWM configuration
	movlw	b'111001'
	movwf	TRISA ^ 0x80		; enable input on pins A0, A4, A5
	clrf	ANSEL ^ 0x80
	incf	ANSEL ^ 0x80, f		; configure A0 as analog input
	movlw 	b'01110000' 		; set ADC Frc clock
	movwf 	ADCON1 ^ 0x80
	movlw	0xFF	
	movwf	PR2 ^ 0x80		; PWM period 244Hz
	clrf	TRISC ^ 0x80		; enable PORTC for output
	bcf    	STATUS, RP0        	; back to BANK 0

	bsf 	ADCON0, 0 		; Left justify, Vdd Vref, AN0, On	
	movlw	7
	movwf	T2CON			; enable Timer 2 with 1:16 prescaler
	movlw	0x0C			; enable single output PWM
	movwf	CCP1CON 	

loop
	movlw	20
	movwf	del
	call	delay			; 20 msec delay

	bsf	ADCON0, GO		; start ADC operation
	btfsc	ADCON0, GO		; and wait for its completion	
	goto 	$-1	
	movf	ADRESH, w		; get higher 8 bits of ADC
	movwf	CCPR1L			; setup PWM duty cycle ratio

checkDir0
	movlw	b'01010'		; read the first button status
	btfsc	PORTA, 4			
	xorlw	b'11000'		; reverse direction for motor 0

checkDir1				; do the same with the second motor
	btfsc	PORTA, 5
	xorlw	b'00110'		; reverse direction for motor 1
	
	movwf	PORTC			; set up the motor directions
  	goto 	loop			; endless loop


; procedures
delay					; a delay for del milliseconds
	movlw 	200
	
	sublw	1			; this loop takes 5us*200 = 1ms
	sublw	0			; for PIC16F684 @ 4 Mhz
	btfss	STATUS, Z
	goto 	$-3

	decfsz	del, f
	goto 	delay
	return

 end

Download pwm_mot2.asm


Last modified:Mon, Jan 23, 2023.

12703