Convert Rotary Encoder Code from 16F628A to 16F1825


Closed Thread
Results 1 to 28 of 28

Hybrid View

  1. #1
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,624


    Did you find this post helpful? Yes | No

    Default Re: Convert Rotary Encoder Code from 16F628A to 16F1825

    Hi,
    Should work....from section 13 (Interrupt-On-Change) of the datasheet:
    The PORTA pins can be configured to operate as Interrupt-On-Change (IOC) pins. On the PIC16(L)F1829 devices, the PORTB pins can also be configured to operate as IOC pins.
    /Henrik.

  2. #2


    Did you find this post helpful? Yes | No

    Default Re: Convert Rotary Encoder Code from 16F628A to 16F1825

    Thanks Henrik, but the 14 pin 16F1825 schematic doesn't show PortB pins.

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,624


    Did you find this post helpful? Yes | No

    Default Re: Convert Rotary Encoder Code from 16F628A to 16F1825

    No, but it does show PortA pins and according to the quote from the datasheet PortA has IOC.

  4. #4


    Did you find this post helpful? Yes | No

    Default Re: Convert Rotary Encoder Code from 16F628A to 16F1825

    Thanks Henrik - I didn't catch the part about PortB on chip 16F1829.

    I've got the code converted to work with a 16F1825 but I had to add the following to the p16F1825.inc file in MPASM:

    Code:
    CCPTMRS          EQU  H'029E'
    CCPTMRS0         EQU  H'029E'
    Can anyone tell me why? All I'm trying to do is use HPWM on CCP3 with the following config/code:

    Code:
    ANSELA   = %00000000
    ANSELC   = %00000000
    TRISA    = %00000011     ' Make PortA pins 0-1 input for rotary encoder
    TRISC    = %00000000     ' Make all pins on PortC output
    
    HPWM 3, 97, 20000
    Until I added the line above in the p16F1825.inc MPASM file, I got this compile error:

    Code:
    Error[113] c:\pbp\pbppi14e.lib 2089 : Symbol not previously defined (CCPTMRS0)

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    In the version history for PBP3 ... http://support.melabs.com/content/29...ersion-History

    One of the bug fixes listed is ... Fixed HPWM compile error for Enhanced Mid-Range parts in which CCPTMRS0 doesn't exist.
    DT

  6. #6


    Did you find this post helpful? Yes | No

    Default Re: Convert Rotary Encoder Code from 16F628A to 16F1825

    Ah! So what you're saying is, use PBP3 already I did purchase the software upgrade but haven't tried converting my existing PBP code yet. Guess I should start sooner than later.

  7. #7


    Did you find this post helpful? Yes | No

    Default Re: Convert Rotary Encoder Code from 16F628A to 16F1825

    This code works on a PIC 16F628A:

    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
    This code does NOT on a PIC 16F1825:

    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
    (The motor spins at full speed and encoder changes are ignored).

    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?

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts