I did some prototyping with the 16F628A but now I need to move my code to another PIC which as at least two CCPs so I can send out HPWM commands to 2 motors (but use 1 rotary encoder to control the duty cycle). The 16F628A only has 1 CCP so after some trial and error on the Microchip site to find an appropriate PIC I settled on the 16F1825 which has 4 CCPs (more than I need, I know).
Now that I'm converting the code I'm wondering if I've really messed up. In the 16F628A data sheet it says that RB4/5 pins can be used as interrupt-on-pin change and indeed when I connect the A/B pins of the rotary encoder to these two and using the code below with Darrel's interrupt plug-in all works fine:
Now that I've got the 16F1825 chip, though, and I'm reading through the data sheet I don't see similar info about any of the PortA/C pins in terms of providing interrupt-on-pin change, so here's my question: have I picked the wrong chip? All I really want is one very similar to the 16F628A but with two CCPs. If I still can use the 16F1825, what does this code become and what pins can I use (presuming RA4/5 are for the external oscillator & RC3/5 are for the HPWM)?Code:'**************************************************************** '* Name : Nacelle_Motors_16F628A.BAS * '* Author : Ross A. Waddell * '* Notice : Copyright (c) 2010 RAW Studios * '* : All Rights Reserved * '* Date : 05/18/2012 * '* Version : 1.0 * '* Notes : Motor control for TOS E engines * '* : * '**************************************************************** '---------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 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 & (%11110000) 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 & (%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 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
Code: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




Bookmarks