Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Need help with motor control with potentiometer using pic16f88

Status
Not open for further replies.

erikj

New Member
I cant figure out the programming for this project I have only done the PWM so the motor runs. I am using a pic16f88. The potentiometer is connected to the AN0 which is pin17,Vss pin5 of the pic and then live. My motor is connected RB4 pin10 of the pic can anyone please give me a assembly code for this it is due in 2 days and I need this urgently as I have no idea how to do it please!
 
Last edited:
Post what you have done with the PWM.... I take it its in assembly? IF you have done a PWM output, then controlling CCP1L with a pot is EXTREMELY easy... I'll give you more detail when you post what you have done.

Nigel's tutorials! ( link in my signature ) has everything you need...
 
This is what I have so far and yes it is in assembly done in MPLab. All that this does is run my motor please tell me if there is anything that does not have to be there and what I have to do so the potentiometer determines at what speed my motor runs. I appreciate the help.

Code:
	#INCLUDE <P16F88.INC>

	__CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_OFF & _WDT_OFF & _INTRC_IO
     __CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF
     
  ORG 0x0000
  goto START
  
   START:
  
               nop
	bsf 	STATUS,RP0	; go to bank 1 
     
               movlw 	b'00000001'
               movwf 	TRISA
               movlw 	b'10111111'
               movwf 	TRISB
;***********************************************	

 
	clrf 	ANSEL
	
	movlw 	b'00000001'
	movlw 	ANSEL
	
	movlw 	b'00110000' 
	movwf 	ADCON1
	
	movlw 	.1
               movwf	ADFM
	
	movlw 	b'10000000' 
	movwf 	ADCON0
	bsf           ADON,1
	
	
	


;***********************************************	
	
	
	
	movf 	ADRESH
	movwf 	PR2
	
	movlw	b'01100000'
	movwf	OSCCON
	bcf 	OPTION_REG, 7
               bcf 	STATUS,RP0                     ;back to bank 0
               movlw	b'00001100'
	movwf	CCP1CON
	bsf 	T2CON, TMR2ON
	movlw	.30
	movwf 	CCPR1L


	
     
     end
 
Last edited:
This code is incomplete... There are no loops to track a pot... The pot (adresh) needs to go into CCP1L not PR2... PR2 is the period value CCP1L must be between PR2 and 0.

I'll take a longer look tonight...
 
I dont know much about assembly programming that is why I really need the help so I can just past because this is the only time we will be using assembly. If it is possible and not to much effort can you maybe write me a simple and easy code that can run after you have taken a look at it tonight?
 
If you can write me a short simple code can you maybe just add short comments so I know more or less what is going on as I still have to write a report on it. Thanks
 
It's not that hard just read the pot and save that to a variable read in 8bits use that to update your PWM


I may write you a example
 
Last edited:
You'll have to set the registers to match your chip but this example should get you going
Myke Predko wrote this code not me
figure you'll learn something.
Code:
 title  "asmMotor 2 - DC Motor Control using a TMR0 Timebase"
;
;  This Program Monitors a Pot at RA3 (RA3) and moves a 
;   DC Motor Accordingly.  Values less than 0x80 move the 
;   motor in reverse while Values greater than 0x80 move
;   the motor forwards.  When the Pot is at an extreme, the 
;   Software PWM moves at full speed.   
;
;  Hardware Notes:
;   PIC16F684 running at 4 MHz Using the Internal Clock
;   RA4 - Pot Command
;   RC5/P1A - Motor Forwards High
;   RC4/P1B - Motor Reverse PWM (on Low)
;   RC3/P1C - Motor Reverse High
;   RC2/P1D - Motor Forwards PWM (on Low)
;
;
;  Myke Predko
;  05.01.10
;
  LIST R=DEC
 INCLUDE "p16f684.inc"

 __CONFIG _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSCIO

;  Variables
 CBLOCK 0x020
Direction
ADCState, ADCValue
PWMDuty, PWMCycle
 ENDC

  PAGE
;  Mainline

 org     0

  nop                           ;  For ICD Debug

  movlw   b'010111'             ;  Set PORTC According to 
  movwf   PORTC                 ;   Operating Parameters
  movlw   7                     ;  Turn off Comparators
  movwf   CMCON0
  movlw   b'00001101'           ;  Enable ADC on RA4
  movwf   ADCON0
  clrf    TMR0                  ;  Using TMR0 as a PWM Base

  bsf     STATUS, RP0
  movlw   b'11010001'           ;  1:4 Prescaler to TMR0
  movwf   OPTION_REG ^ 0x80;  
  movlw   1 << 3                ;  RA4 (AN3) ADC Input
  movwf   ANSEL ^ 0x80
  movlw   b'00010000'           ;  Select ADC Clock as Fosc/8
  movwf   ADCON1 ^ 0x80
  bcf     STATUS, RP0

  bcf     INTCON, T0IF          ;  Wait for TMR0 to Overflow
  clrf    ADCState
  clrf    PWMDuty               ;  Not Moving at First
  clrf    PWMCycle              ;  Start at the Beginning
  clrf    Direction             ;  Moving Forwards

Loop:
  btfss   INTCON, T0IF          ;  Wait for Timer Overflow
   goto   $ - 1
  bcf     INTCON, T0IF          ;  Reset and Wait for Next

  btfsc   ADCState, 0           ;  Start or Read ADC?
   goto   ADCRead
  bsf     ADCON0, GO            ;  Start ADC Read
  bsf     ADCState, 0           ;  Next State
  goto    ADCDone
ADCRead:                        ;  Read the ADC Value
  movf    ADRESH, w
  movwf   ADCValue
  clrf    ADCState              ;  Original State
ADCDone:                        ;  Process ADC Value

  movlw   0x80                  ;  Forwards or Reverse?  
  subwf   ADCValue, w
  btfss   STATUS, C             ;  Less than 0x80 go in Reverse
   goto   MotorReverse

MotorForwards:
  movwf   PWMDuty
  bcf     STATUS, C             ;  Convert the Value from 7 Bits 
  rrf     PWMDuty, f            ;   to 5
  bcf     STATUS, C
  rrf     PWMDuty, f
  clrf    Direction             ;  Move Forwards
  goto    MotorUpdate

MotorReverse:
  movlw   0x7F                  ;  Cheesy 7 Bit Negation of the 
  xorwf   ADCValue, w           ;   Reverse CCPR1L Value
  movwf   PWMDuty
  bcf     STATUS, C             ;  Convert the Value from 7 Bits 
  rrf     PWMDuty, f            ;   to 5
  bcf     STATUS, C
  rrf     PWMDuty, f
  movlw   1
  movwf   Direction             ;  Move Backwards

MotorUpdate:                    ;  Check to Update the Motor
  movf    PWMDuty, w            ;  If Duty > Cycle, then Off
  subwf   PWMCycle, w
  movlw   b'011011'             ;  TRISC Forwards
  btfsc   Direction, 0          ;  Forwards or Reverse?
   movlw  b'100111'             ;  TRISC Reverse
  btfsc   STATUS, C
   movlw  b'111111'             ;  Turn off Motors?  
  bsf     STATUS, RP0
  movwf   TRISC ^ 0x80
  bcf     STATUS, RP0

  incf    PWMCycle, f           ;  Increment the PWM Cycle Count
  bcf     PWMCycle, 5           ;  Maximum of 32 States

  goto    Loop                  ;  Finished, Loop Around Again


  end

And here how it should look not tested
Code:
 title  "asmMotor 2 - DC Motor Control using a TMR0 Timebase"
;
;  This Program Monitors a Pot at RA3 (RA3) and moves a 
;   DC Motor Accordingly.  Values less than 0x80 move the 
;   motor in reverse while Values greater than 0x80 move
;   the motor forwards.  When the Pot is at an extreme, the 
;   Software PWM moves at full speed.   
;
;  Hardware Notes:
;   PIC16F684 running at 4 MHz Using the Internal Clock
;   RA4 - Pot Command
;   RC5/P1A - Motor Forwards High
;   RC4/P1B - Motor Reverse PWM (on Low)
;   RC3/P1C - Motor Reverse High
;   RC2/P1D - Motor Forwards PWM (on Low)
;
;
;  Myke Predko
;  05.01.10
;
 #INCLUDE <P16F88.INC>
 
	__CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_OFF & _WDT_OFF & _INTRC_IO
     __CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF
 
;  Variables
 CBLOCK 0x20
 Direction
 ADCState, ADCValue
 PWMDuty, PWMCycle
 ENDC
 
  PAGE
;  Mainline
 
 org     0
 
  nop                           ;  For ICD Debug
 
  movlw   b'010111'             ;  Set PORTB According to 
  movwf   PORTB                 ;   Operating Parameters
  movlw   7                     ;  Turn off Comparators
  movwf   CMCON
  movlw   b'00001101'           ;  Enable ADC on RA4
  movwf   ADCON0
  clrf    TMR0                  ;  Using TMR0 as a PWM Base
 
  bsf     STATUS, RP0
  movlw   b'11010001'           ;  1:4 Prescaler to TMR0
  movwf   OPTION_REG ^ 0x80;  
  movlw   1 << 3                ;  RA4 (AN3) ADC Input
  movwf   ANSEL ^ 0x80
  movlw   b'00010000'           ;  Select ADC Clock as Fosc/8
  movwf   ADCON1 ^ 0x80
  bcf     STATUS, RP0
 
  bcf     INTCON, TMR0IF          ;  Wait for TMR0 to Overflow
  clrf    ADCState
  clrf    PWMDuty               ;  Not Moving at First
  clrf    PWMCycle              ;  Start at the Beginning
  clrf    Direction             ;  Moving Forwards
 
Loop:
  btfss   INTCON, TMR0IF          ;  Wait for Timer Overflow
   goto   $ - 1
  bcf     INTCON, TMR0IF          ;  Reset and Wait for Next
 
  btfsc   ADCState, 0           ;  Start or Read ADC?
   goto   ADCRead
  bsf     ADCON0, GO            ;  Start ADC Read
  bsf     ADCState, 0           ;  Next State
  goto    ADCDone
ADCRead:                        ;  Read the ADC Value
  movf    ADRESH, w
  movwf   ADCValue
  clrf    ADCState              ;  Original State
ADCDone:                        ;  Process ADC Value
 
  movlw   0x80                  ;  Forwards or Reverse?  
  subwf   ADCValue, w
  btfss   STATUS, C             ;  Less than 0x80 go in Reverse
   goto   MotorReverse
 
MotorForwards:
  movwf   PWMDuty
  bcf     STATUS, C             ;  Convert the Value from 7 Bits 
  rrf     PWMDuty, f            ;   to 5
  bcf     STATUS, C
  rrf     PWMDuty, f
  clrf    Direction             ;  Move Forwards
  goto    MotorUpdate
 
MotorReverse:
  movlw   0x7F                  ;  Cheesy 7 Bit Negation of the 
  xorwf   ADCValue, w           ;   Reverse CCPR1L Value
  movwf   PWMDuty
  bcf     STATUS, C             ;  Convert the Value from 7 Bits 
  rrf     PWMDuty, f            ;   to 5
  bcf     STATUS, C
  rrf     PWMDuty, f
  movlw   1
  movwf   Direction             ;  Move Backwards
 
MotorUpdate:                    ;  Check to Update the Motor
  movf    PWMDuty, w            ;  If Duty > Cycle, then Off
  subwf   PWMCycle, w
  movlw   b'011011'             ;  TRISB Forwards
  btfsc   Direction, 0          ;  Forwards or Reverse?
   movlw  b'100111'             ;  TRISB Reverse
  btfsc   STATUS, C
   movlw  b'111111'             ;  Turn off Motors?  
  bsf     STATUS, RP0
  movwf   TRISB ^ 0x80
  bcf     STATUS, RP0
 
  incf    PWMCycle, f           ;  Increment the PWM Cycle Count
  bcf     PWMCycle, 5           ;  Maximum of 32 States
 
  goto    Loop                  ;  Finished, Loop Around Again
 
 
  end

I moved from portC to PORTB same pin number this is also software PMW using timr0
 
Last edited:
I dont mean to hijack, but I noticed something there I've not seen before, looks like your using an assembler directive to logical shift a 1 3 places and another instruction to or 0x80 with ansel, is this mplab compatible?
 
A starter... Its not perfect but it's running about 14.6 KHz The duty is from 10% to around 90%

I want to see if you get it ( its only 8 bit resolution but at 4MHz it will do...)
Code:
	#INCLUDE <P16F88.INC>
 
	__CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_OFF & _WDT_OFF & _INTRC_IO
     __CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF

	cblock  0x20
		ADCres
		D1
		D2
	endc

	ORG 0x0000
	goto START
 
START
 	banksel OSCCON
	movlw	b'01100000'
	movwf	OSCCON		; 4 MHz clock
	nop
	nop
	nop
	nop

;***********************************
; set up Ports
;***********************************
	banksel TRISA		; go to bank 1 
 	movlw 	b'00000001'
	movwf 	TRISA
	movlw 	b'11111110'
	movwf 	TRISB
	bcf 	OPTION_REG, 7			; disable pullups

;***********************************
; set up ADC
;***********************************	
 	banksel ANSEL
 	movlw 	b'00000001'
	movlw 	ANSEL
	clrf 	ADCON1		; 8 bit 5v - 0v
	banksel ADCON0
	movlw 	b'01000000' 
	movwf 	ADCON0		; TOSC = 8

;***********************************
; set up PWM
;***********************************
	movlw	b'00001100'
	movwf	CCP1CON
	clrf	CCPR1L
	movlw	b'00000010'
	movwf	T1CON
	banksel PR2
	movlw	b'01000000'
	movwf	PR2
	bsf 	T2CON, TMR2ON
	banksel PORTB
;***********************************
; Main loop
;***********************************	
Loop
 	call	readADC
	movf 	ADRESH,w
	movwf	ADCres	
	bcf		CCP1CON,CCP1Y
	bcf		CCP1CON,CCP1X
	bcf		STATUS,C
	rrf		ADCres,f
	btfsc	STATUS,C
	bsf		CCP1CON,CCP1X	
	bcf		STATUS,C
	rrf		ADCres,f
	btfsc	STATUS,C
	bsf		CCP1CON,CCP1Y
	movf 	ADCres,w
	movwf 	CCPR1L
	goto	Loop



;***********************************
; Read the ADC
;*********************************** 
 	
readADC
	bsf		ADCON0,ADON
	call	delay
	bsf		ADCON0,GO
adc
	btfsc	ADCON0,GO
	goto	adc
	return


delay
	clrf	D1
	clrf	D2		
del	decfsz 	D1
	goto	del	
	decfsz	D2
	goto	del
	return
     end

This will work better if you DONT write the CCP module every cycle... Only when the pot moves.... RB0 is the PWM output.
 
Last edited:
I dont mean to hijack, but I noticed something there I've not seen before, looks like your using an assembler directive to logical shift a 1 3 places and another instruction to or 0x80 with ansel, is this mplab compatible?

It's using a Bitwise exclusive OR @ 0x80 on the ANSEL It works
 
Ok... Your temp sensor seems to give an output of 1°C for every bit in the ADRESH... Your PWM output seems to be on pin 10!!!!! RB0 is pin 6 and RB3 is pin 9.

PWM output has to be on one of these pins...
 
Ok... Your temp sensor seems to give an output of 1°C for every bit in the ADRESH... Your PWM output seems to be on pin 10!!!!! RB0 is pin 6 and RB3 is pin 9.

PWM output has to be on one of these pins...

Ian it's 19.5 mV for 1°C
 
I just changed pin 10 to pin 6 and it still doesnt work? Can the problem be with the tempreture sensor?
 
Room temp is not going to give a real high pwm

Your not using a potentiometer which would give a full scale reading
 
Last edited:
Depends on the reading it could be to low to switch the transistor on
your probably only seeing 218 Microamps at the base of the transistor

room temp is only .48 volts
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top