|
|
View previous topic :: View next topic |
Author |
Message |
JAM2014
Joined: 24 Apr 2014 Posts: 138
|
IOC with the 18F45K50 |
Posted: Mon Feb 10, 2020 5:10 pm |
|
|
Hi All,
I'm in the process of updating a design based on the 18F45K50. This design uses a rotary encoder type switch (with 'A' and 'B' outputs) and an integral SPST switch. I currently 'poll' these three inputs using a timer interrupt, and the functionality is 'adequate', but not 100%. I'm thinking that using the IOC functionality with improve the responsiveness of the rotary switch and SPST switch input.
So, I need three IOC inputs. According to the datasheet, these inputs can be found on B4:7 and C0:2. Pin C2 is out because I need PWM out as well. Pins B6 & B7 are out because I use ICSP.
Questions:
1. Can I use individual pins from both port B and port C to get the three IOC pins I need?
2. Can I use a different pin for PWM output?
3. Can I use the alternate ICSP clock and data pins?
4. Should I consider a different PIC that doesn't have these limitations? I do need USB functionality!
Sorry, I've been reading the datasheet to find these answers, but it's not clear enough for me to proceed with a new board design at this point!
Thanks,
Jack |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Mon Feb 10, 2020 9:09 pm |
|
|
While I don't use that PIC.....
1) Probably but may depend upon speed needed for the encoder and what else the PIC has to do.
2) Again, speed might be an issue (SW vs HW PWM).
3) If offered, yes, just be sure to program it correctly.
4) A 'bigger' PIC will always be better, even if it costs a little more.
Often not considered is the true cost of R&D. Say it's $100/hr. Option 'A', spend more than an hour TRYING to work out a USB 'bug'. Option 'B', buy a TTL-USB module for $1. USB can be problematic (layout, parts, code space), so an hour's wasted labour could have bought 100 pieces of troublefree INSTANT working USB. 'B' is what I've done. Sure I played with the 18F4550 when it came out but quickly realized it was better, faster, cheaper to use a premade module. OK, maybe after quantity of 500-1000pcs, it MIGHT be cheaper to have a PIC with integral USB. I've never done the 'break even' analysis.
The same hold for encoders. I've used LSICSI chips for decades, never had one fail. They, well, work...
For 'simple' upgrades, perhaps choose a faster running PIC ? Just be real careful about PCB layout, power supply, etc.
ICSP pins can be used for 'real world' interfacing, though I just use big PICs and dedicate them, cheaper in the overall picture. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Wed Feb 12, 2020 3:42 am |
|
|
Now, questions. You talk about three pins for the encoder. Sounds as if
this is a 2 pin encoder, with a 'zero' switch pulse output?. If so, the third
pin doesn't want IOC. So wire this just to a normal interrupt RB0, 1 or 2.
Then IOC for the two encoder phase pins. C6 & C7 would be good.
Now a lot does depend on how fast this encoder may be changing.
How many pulses per rev?. What maximum shaft speed?. If the product
of these results in a high figure, then first the code itself for the interrupt
will start to become a little more complex, and if the figure gets really high
a hardware decoder may be the better choice.
Give us the encoder part number, and the maximum rotation rate. We
may then be able to give some advice.
Your pin numbers for IOC seem 'odd'. Data sheet has IOC on B4 to B7, and
C0 to C7 (missing C3 since this is VddCore). |
|
|
JAM2014
Joined: 24 Apr 2014 Posts: 138
|
|
Posted: Wed Feb 12, 2020 4:41 pm |
|
|
Hi,
The rotary encoder is a CTE 290VAB0R201B2. Digikey was the supplier: https://www.digikey.com/products/en?keywords=ct3007-nd.
It has two quadrature outputs, 'A' and 'B', and a momentary switch.
This rotary switch is used to control a menu, and enter data. The momentary switch acts like an 'enter' key, while the rotary switch acts like a 'decrement' key (CCW), and an 'increment' key (CW). I'm not sure how to estimate the maximum shaft speed, maybe 120 RPM (2 revs./sec.)?
OK, the momentary switch seems well-suited to a normal interrupt, like RB0.
As for pin numbers for the IOC, the data sheet says the following:
Quote: |
10.11 PORTB/PORTC Interrupt-on-Change: An input change on PORTB<7:4> or PORTC<2:0> sets flag bit IOCIF of the INTCON register.
|
Am I reading this incorrectly?
Thanks,
Jack |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Thu Feb 13, 2020 12:37 am |
|
|
Looks like a misprint. If you look at the IOCC register it has entries for
the whole of Port C. I'll look later at my datasheet and see if it has that line. |
|
|
JAM2014
Joined: 24 Apr 2014 Posts: 138
|
|
Posted: Fri Feb 14, 2020 8:24 am |
|
|
Hi Ttelmah,
I agree there is a misprint. The text I quoted is in the current datasheet for the 18f45K50 device. I also note that the IOCC register map shows all port C pins, except C3, as IOC pins.
The question is, which one is correct?
Thanks,
Jack |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Fri Feb 14, 2020 9:32 am |
|
|
I'd say it's that one paragraph.
It is defined on all pins in too many other places. The IOCC register map.
The pin diagrams (all show IOCC0, 1, 2, 4, 5, 6, 7).
The pin descriptions (again all pins listed).
Then the register description for this as well.
I haven't got the K50 handy, but I seem to remember using the upper
pins for IOC a while ago.
Point it out to MicroChip. They are usually quick to answer an irregularity
like this, then you will know for sure. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Fri Feb 14, 2020 9:51 am |
|
|
My compiler is way too old, but, have a look at the 'processor header ' file to see what CCS thinks the PIC has to offer.
I assume IOC.3 isn't there because it's some form of USB pin ?
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Fri Feb 14, 2020 10:08 am |
|
|
It's the VDDCore regulator pin.
CCS doesn't have any support for these interrupt sources. You have to
set the bits in IOCB and IOCC yourself. All they give is the single INT_RB
interrupt triggered by these.
Unlike later chips where the mask bits allow you to also specify the edge
and CCS added support for these, this one is just like the old INT_RB
on the upper four bits of PORT B, but it also triggers on a number of
bits on PORT C. The question is 'how many'.... |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Sat Feb 15, 2020 12:01 pm |
|
|
Sorry I'm "late to the party". The example code I wanted to post earlier in the week is only found at home, and since I'm now at home, here it is.
The following won't be complete because I'm not going to bother posting the LCD driver. That said, the LCD code is irrelevant anyway. This was a very simple example I would give to students in a lab environment many years ago. The encoder's A and B lines are routed to an 18F452's port B (port B interrupt on change). The code also sets up a timer to "race" the encoder. If it's turned slowly (timer wins), the code gives a slow change to whatever it is you are changing. If the encoder is turned quickly, the timer loses and that results in a faster change (larger increment/decrement) as the knob is turned.
Code: | #include <18F452.h>
#device adc=8
#use delay(clock=4000000,RESTART_WDT)
#fuses XT, BROWNOUT, BORV20, PUT, STVREN, NOLVP, WDT
#byte portb = 0xf81 // RAM address of port b
#use fast_io(B) // tells the compiler not to alter our direction register for port b
#include "lcd_driver.c"
int8 port_b_state, old_b_state = 3, count = 0, step;
int1 cw = FALSE, ccw = FALSE;
// want a simple program to display an 8 bit integer on the lcd, and if the knob is turned CW, the number increases,
// and if it is turned CCW, the number decreases
// want it to be intelligent - i.e. sense the rotation speed: slow, increase/decrease by 1; fast, increase/dec by more than 1
// want to update the screen only when the knob is in the detent position
// we'll wire the encoder to the pic as follows: A (left lead) to B4, B (right lead) to B5, and middle lead (COM) to GND
// CW: 3 2 0 1 3
// CCW: 3 1 0 2 3
#int_RB
RB_isr() {
port_b_state = (portb & 0x30) >> 4; // read portb to clear the mismatch
set_timer0(0); // user has beat the timer, so reset the timer
switch (port_b_state) {
case 0:
if (old_b_state == 2) {
step++;
}
else if (old_b_state == 1) {
step++;
}
break;
case 1:
if (old_b_state == 0) {
step++;
}
else if (old_b_state == 3) {
step = 1; // user just started to turn the knob, so set step to 1 now
}
break;
case 2:
if (old_b_state == 3) {
step = 1; // user just started to turn the knob, so set step to 1 now
}
else if (old_b_state == 0) {
step++;
}
break;
case 3: // knob is now in detent - okay to signal to update screen now
if (old_b_state == 1) {
cw = TRUE;
step++;
}
else if (old_b_state == 2) {
ccw = TRUE;
step++;
}
break;
}
old_b_state = port_b_state; // save a copy of this state of portb, which will become our old state the next time thru
}
#int_RTCC
RTCC_isr() {
if (step > 0) {
step--; // the clock beat the human, take one away from step
}
}
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_ON);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32|RTCC_8_BIT); // overflows every 8 ms
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
enable_interrupts(INT_RTCC);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
port_b_pullups(TRUE); // enable port b's pullups
set_tris_b(0xff); // make portb all input
set_tris_e(0x00); // need port E output for the lcd's control lines
lcd_init();
printf(lcd_putc,"\fCount = %03u",count); // %03u means print 3 digits, with leading zeroes
while (TRUE) {
restart_wdt();
if (cw) {
cw = FALSE; // cw means count up
count = count + step; // add step to count
lcd_gotoxy(9,1); // go to where count is actually being displayed
printf(lcd_putc,"%03u",count); // ...and print it out
}
if (ccw) {
ccw = FALSE;
count = count - step; // subtract step from count
lcd_gotoxy(9,1); // go to where count is actually being displayed
printf(lcd_putc,"%03u",count); // ...and print it out
}
}
}
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|