This code works on a PIC 16F628A:
This code does NOT on a PIC 16F1825:Code:'---------Initialization-------- DEFINE OSC 20 ' set oscillator 20Mhz ' *************************************************************** ' Device Fuses ' *************************************************************** #CONFIG __config _HS_OSC & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BODEN_ON & _LVP_OFF & _CP_OFF & _CPD_OFF #ENDCONFIG 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 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 ' 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 '---------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, 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 & (%00110000) Old_RPM = MotorRPM LCDOUT $FE, 1 PAUSE 1000 rpmAdj CON 20 ' PWM cycle seems to be "higher" than HPWM, so need ' to reduce PWM cycle max to be less than HPWM cycle value ' Spin up motor to saved value of _MotorRPM IF MotorRPM > rpmAdj Then FOR i = 0 to (MotorRPM - rpmAdj) PWM PortB.3, I, 100 NEXT I EndIf ' Begin background HPWM GOSUB motorhpwm 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 1, 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: New_Bits = PORTB & (%00110000) 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 MotorRPM < 255 then MotorRPM = MotorRPM + 1 Else ' CCW rotation - decrease speed to a min of 0 IF MotorRPM > 0 Then MotorRPM = MotorRPM - 1 EndIF DoneRotEnc: Old_Bits = New_Bits @ INT_RETURN
(The motor spins at full speed and encoder changes are ignored).Code:' *************************************************************** ' Initialization ' *************************************************************** 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, _LVP_OFF #ENDCONFIG ANSELA = %00000000 ANSELC = %00000000 TRISA = %00000011 ' Make PortA pins 0-1 input for rotary encoder TRISC = %00000000 ' Make all pins on PortC output 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 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 ' 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 '---------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, 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 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_Bits = PORTA & (%00000011) 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 HPWM 3, 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 RETURN end ' *************************************************************** ' [RBC - interrupt handler] ' *************************************************************** Rot_Encoder: New_Bits = PORTA & (%00000011) IF (New_Bits & %00000011) = (Old_Bits & %00000011) Then DoneRotEnc RotEncDir = New_Bits.1 ^ Old_Bits.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 DoneRotEnc: Old_Bits = New_Bits @ INT_RETURN
I've been at this most of the night - any ideas? Apart from the subtle change to spinning up the motor to the saved _MotorRPM EEPROM variable, I can't see what I'm doing wrong. Am I missing a register setting to tell it to use PWM on CCP3?




Bookmarks