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.
Code:
'---------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
Bookmarks