PDA

View Full Version : HPWM Frequencies for Motor Control



RossWaddell
- 21st May 2012, 22:20
I'm using a PIC16F628A (with a 20Mhz ceramic resonator; will switch to a oscillator + caps later on) to drive a small DC motor and I've incorporated a rotary encoder to adjust the duty cycle during run time. I've been told that I need to use high frequencies (> 20kHz) to reduce the motor whine, but I'm not sure if it's actually using the value of 32767 I've coded below. Is there a way to find out what the max frequency is for a PIC? The data sheet isn't clear on what are the maximum values or if only specific frequencies are allowed.



'---------Initialization--------

DEFINE OSC 20 ' set oscillator 20Mhz


' ************************************************** *************
' Device Fuses
' ************************************************** *************


@ __config _HS_OSC & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BODEN_ON & _LVP_OFF & _CP_OFF & _CPD_OFF




CMCON = 7 ' Turn off comparators
TRISA = %00000000 ' Make all PortA pins output
TRISB = %00110000 ' Make PortB pins 4-5 input




Old_Bits VAR BYTE
New_Bits VAR BYTE
RotEncDir VAR BIT ' 1=CW, 0=CCW
' Rot Enc pin A connected to PortB.5;
' Rot Enc pin B connected to PortB.4




p0 VAR BYTE
Old_p0 VAR BYTE


'************************************************* **************************
' SETUP YOUR LCD HERE!!!
'************************************************* **************************


;Define LCD_DREG PORTA
;Define LCD_DBIT 0
;Define LCD_RSREG PORTA
;define LCD_RSBIT 4
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 7 ' Use PortB.7 as the Enable (E) bit since PortB.3
' on the 16F628A is the one-and-only HPWM output
;define LCD_BITS 4
;define LCD_LINES 2
;define LCD_COMMANDUS 2000
;define LCD_DATAUS 50




INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
' --> copy both files to PBP main folder
' (i.e. c:\pbp)
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RBC_INT, _Rot_Encoder, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM


@ INT_ENABLE RBC_INT ;RB Port Change Interrupt


' Set default values
Old_Bits = PORTB & (%11110000)
p0= 60
Old_p0 = p0


LCDOUT $FE, 1
PAUSE 1000
GOSUB motorhpwm


Main:
IF p0 <> Old_p0 Then
Old_p0 = p0
GOSUB motorhpwm
EndIF


LCDOUT $FE, 2, "p0: ", #p0, " "
pause 10

GOTO Main


motorhpwm:
HPWM 1, p0, 32767 ; Tried 245 Hz but it made the motor too loud.
; Supposedly, anything above 20kHz is above human hearing


RETURN
end


'---[RBC - interrupt handler]---------------------------------------------------
Rot_Encoder:
New_Bits = PORTB & (%11110000)
IF (New_Bits & %00110000) = (Old_Bits & %00110000) Then DoneRotEnc
RotEncDir = New_Bits.5 ^ Old_Bits.4
IF RotEncDir = 1 Then
; CW rotation - increase speed but only to a max of 255
IF p0 < 255 then p0 = p0 + 1
Else
' CCW rotation - decrease speed to a min of 0
IF p0 > 0 Then p0 = p0 - 1
EndIF


DoneRotEnc:
Old_Bits = New_Bits
@ INT_RETURN

Tobias
- 22nd May 2012, 02:50
Find the Mister-E calculator, its handy as hell.

As far as needing 20k HZ, I run DC motors down to 500hz. There is a low whine to them but its not the end of the world. The generated electrical noise is less also the heat generated from switching is alot easier to deal with at lower frequencies.

You might want to take a look at an 18F4431 chip. Its really handly too for motor control

c_moore
- 22nd May 2012, 10:53
I am doing something similar and a frequency of 10,000 seems to work good for me.

SteveB
- 22nd May 2012, 23:35
The data sheet isn't clear on what are the maximum values or if only specific frequencies are allowed.

Have a look at the PWM Mode section, 9.3

PWM Period = [(PR2)+1] * 4 * Tosc * TMR2prescale
PWM Freq = 1 / PWM period

So, your frequency can be varied over a wide range. With a 20 MHz OSC, Min = 1.221 KHz, Max = 2.5 MHz.

As Tobias suggested, use Mister-E's Calculator to help with getting the correct value for PR2 and TRM2 Prescale.
http://www.picbasic.co.uk/forum/showthread.php?t=4994

Some examples with 20 MHz OSC:
02 KHz - PR2=155, Prescaler 1:16
05 KHz - PR2=249, Prescaler 1:4
10 KHz - PR2=124, Prescaler 1:4
20 KHz - PR2=249, Prescaler 1:1