Now that I've got the HPWM stuff sorted (thanks to Darrel) I'm back to the original problem which is converting RBC interrupts to IOC on the 16F1825 - rotating the rotary encoder knob has no effect on MotorRPM. Here's the code I have so far:
Code:
DEFINE OSC 20 ' Set oscillator 20Mhz
' ***************************************************************
' Device Fuses
' ***************************************************************
' PIC chip data sheets can be found here: C:\Program Files\Microchip\MPASM Suite
#CONFIG
__config _CONFIG1, _FOSC_HS & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
__config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
#ENDCONFIG
' ***************************************************************
' Initialization
' ***************************************************************
DEFINE CCP3_REG PORTA
DEFINE CCP3_BIT 2
;DEFINE CCP4_REG PORTC
;DEFINE CCP4_BIT 1
ANSELA.2 = 0 ' Digital only on CCP3 pin
;ANSELC.1 = 0 ' Digital only on CCP4 pin
TRISA = %00000011 ' Make PortA pins 0-1 input for rotary encoder
;TRISC = %00000000 ' Make all pins on PortC output
;INTCON.3 = 1 ' Enable interrupt-on-change (IOCIE)
INTCON = %10001000 ' Global int enabled, IOCI enabled, IOCI flag bit 0 clr
IOCAP.0 = 1 ' Enable positive (rising edge) change
IOCAP.1 = 1 ' Enable positive (rising edge) change
IOCAN.0 = 1 ' Enable negative (falling edge) change
IOCAN.1 = 1 ' Enable negative (falling edge) change
IOCAF.0 = 0 ' Clear interupt-on-change flag
IOCAF.1 = 0 ' Clear interupt-on-change flag
A VAR PortA.1 ' Variable to store encoder's A pin output (RA1)
B VAR PortA.0 ' Variable to store encoder's B pin output (RA0)
RotEncDir VAR BIT ' 1=CW, 0=CCW
' Rot Enc pin A connected to PortA.1;
' Rot Enc pin B connected to PortA.0
Old_RPM VAR BYTE
I 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
;define LCD_BITS 4
;define LCD_LINES 2
;define LCD_COMMANDUS 2000
;define LCD_DATAUS 50
' ***************************************************************
' Includes
' ***************************************************************
INCLUDE "EE_Vars.PBP" ' Requires MPASM assembler
' Go to "View > Compile and Program Options..."
' On "Assembler" tab, check "Use MPASM"
' (no need to change any of the default settings)
' --> copy file to PBP main folder (i.e. c:\pbp)
MotorRPM VAR BYTE : @ EE_var _MotorRPM, BYTE, 100
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 IOC_INT, _Rot_Encoder, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE IOC_INT ; Interrupt-on-Change interrupt
' Set default values
Old_RPM = MotorRPM
;LCDOUT $FE, 1
;PAUSE 1000
' Spin up motor to saved value of _MotorRPM
IF MotorRPM > 1 THEN
FOR I = 0 to MotorRPM
pause 30
HPWM 3, I, 20000
; HPWM 4, I, 20000
NEXT I
EndIf
Main:
IF MotorRPM <> Old_RPM Then
Old_RPM = MotorRPM
GOSUB motorhpwm
@ EE_write_var _MotorRPM ; save the new number to EEPROM
EndIF
; LCDOUT $FE, 2, "MotorRPM: ", #MotorRPM, " "
; pause 10
GOTO Main
motorhpwm:
HPWM 3, MotorRPM, 20000 ; Tried 245 Hz but it made the motor too loud.
; Supposedly, anything above 20kHz is above
; human hearing
; HPWM 4, MotorRPM, 20000 ; 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:
RotEncDir = (A ^ B) ^ IOCAF.0
IF RotEncDir = 1 Then
; CW rotation - increase speed but only to a max of 255
IF MotorRPM < 255 then MotorRPM = MotorRPM + 1
Else
' CCW rotation - decrease speed to a min of 0
IF MotorRPM > 0 Then MotorRPM = MotorRPM - 1
EndIF
IOCAF.0 = 0 ' Clear interrupt flags
IOCAF.1 = 0
@ INT_RETURN
Any ideas?
Bookmarks