I'll double check the connections, but can someone please confirm if I need this to enable the interrupt-on-change feature?
Code:INTCON.3 = 1 'IOCIE bit set to 1
I'll double check the connections, but can someone please confirm if I need this to enable the interrupt-on-change feature?
Code:INTCON.3 = 1 'IOCIE bit set to 1
That doesn't explain why the HPWM doesn't work, though. Is there something that needs to be configured for PWM use of CCP3?
Ross,
The IOC interrupts work differently than the RBC interrupts on the 628A.
To fully understand them, you'll need to read section 13.0 INTERRUPT-ON-CHANGE in the datasheet.
But essentially each IOC pin operates independantly, with individual selection of rising/falling edges, and individual interrupt flags.
Each pin must be enabled with edge selects, and the flags must be cleared on each interrupt.
The registers you need to look at are ...
IOCAP: INTERRUPT-ON-CHANGE PORTA POSITIVE EDGE REGISTERI
IOCAN: INTERRUPT-ON-CHANGE PORTA NEGATIVE EDGE REGISTER
IOCAF: INTERRUPT-ON-CHANGE PORTA FLAG REGISTER
After being setup properly, you can use the interrupt flags to tell what pins changed, instead of reading the port and doing the newbits-oldbits stuff.
If you don't clear the flags, you end up in a continuous interrupt loop and none of the rest of your program will execute.
DT
Thanks Darrel. IOC is definitely more complicated than the RBC interrupt but it's always good to learn new things
This is the config I have so far:
Are you saying that for my PBP interrupt routine I can change the code to look at IOCAF.0 and IOCAF.1 values instead of the NewBits/OldBits? The values on A/B from the rotary encoder (incremental quadrature) are:Code:ANSELA = %00000000 ' Digital only (PortA) ANSELC = %00000000 ' Digital only (PortC) 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) IOCAP.0 = 1 IOCAP.1 = 1 IOCAN.0 = 1 IOCAN.1 = 1 IOCAF.0 = 0 IOCAF.1 = 0
CW
00
10
11
01
CCW
00
01
11
10
I think I still need to track the old values on A/B pins (RA1 & RA0 in my application) and do something like this pseudo code:
If A caused the interrupt then
Compare A & B
If different then
CW rotation
Else
CCW rotation
End If
End If
If B caused the interrupt then
Compare A & B
If same then
CW rotation
Else
CCW rotation
End If
End If
Does that make sense?
(I realize I'm jumping around a bit here but I didn't anticipate that switching from a 16F628A to a 16F1825 (in order to have 2 CCPs) was going to be so complicated)
First things first - getting the rotary encoder code to alter the PWM frequency doesn't matter if I can't get the HPWM command to work at all. In this thread (http://www.picbasic.co.uk/forum/showthread.php?t=1770), it seems to infer that HPWM will only work with channels 1 & 2, not 3 (and greater) and hence manually coding of all the applicable registers is needed. Is that true?
Do you have the latest version of PBP3 (3.0.5.x)?
Sorry if I've already asked, but I have to ask so many people to update I forget who I've asked.
I don't have a problem getting HPWM to work in the simulator.
I know that doesn't mean it will work on real hardware, but I won't have access to an 1825 till monday.
For the encoder.
When using IOC_INT's, determining the direction is as simple as ...
Which is effectively the same thing as your pseudo code.Code:DIR = (A ^ B) ^ IOCAF.0
DT
I found this in the c:\pbp3\readme.txt file:
Release Notes:
-------------------------------------3.0.5--------------------------------------
Fixed BLOCK_SIZE for 16(L)F1826/1827
Fixed configuration defaults for 12(L)F752 to match MPASM 5.44
Legacy SFR names restored for many devices
New Parts: 12F1501, 16F1503, 16F1508, 16F1509, 16F1512, 16F1513
... so I'm assuming that means I have 3.0.5 (I only bought the PBP3 upgrade last month).
I'll be using HPWM with a motor, but right now I just want to see it working with an LED. I've tried using CCP1 (which is an EECP) and CCP3, but no luck; the LED is just dimly lit no matter what Duty Cycle I use:
(note that I used the example from the link above, but I'd really like to just use HPWM as my interrupt routine is going to modify the motor's speed via the HPWM duty cycle and that worked really well with the 16F628A)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, _LVP_OFF #ENDCONFIG DEFINE CCP3_REG PORTA DEFINE CCP3_BIT 2 ANSELA = %00000000 ' Digital only (PortA) ANSELC = %00000000 ' Digital only (PortC) ADCON1 = $0F TRISA = %00000000 ' Make all pins on PortA output TRISC = %00000000 ' Make all pins on PortC output DUTY3 var word ' Set CCP modules to PWM mode CCP3CON = %00001100 ' Mode select = PWM PR2 = $FF '255 T2CON = %00000110 ' TMR2 on 1:!6 prescale DUTY3 = 512 CCP3CON.4 = DUTY3.0 CCP3CON.5 = DUTY3.1 CCPR3L = DUTY3 >> 2 lblLoop: goto lblLoop end
Bookmarks