UART + IOC on an 8-bit PIC - Page 1
Forum section: electronics / general

author: void_error
author_rank: Frequent Contributor
timestamp: August 02, 2016, 03:27:30 pm
content: PIC16F1459's datasheet says that if a pin is configured as a peripheral, like UART in this case, you can't change the state of the pin but you can read it.Everything fine so far but what if I also want to use the Interrupt-On-Change function of that pin?To be more specific, I want to know if I enable UART (RB5 - RX, RB7 - TX, idle high) and IOC (falling edge) on RB5 will I get an interrupt when RX goes low.Has anyone done this before?

author: void_error
author_rank: Frequent Contributor
timestamp: August 02, 2016, 03:37:24 pm
content: Just to make this easier:Generic I/O Pin diagram is on page 125IOC block diagram is on page 139EUSART Receive block diagram is on page 249The idea should theoretically work, and as far as I remember they fixed the IOC bug on the newer 8-bit PICs (16F1xxx and 16F1xxxx).

author: rstofer
author_rank: Super Contributor
timestamp: August 02, 2016, 03:52:12 pm
content: Why don't you just try it and see?

author: void_error
author_rank: Frequent Contributor
timestamp: August 02, 2016, 03:59:15 pm
content: I can only try it tomorrow at work, I don't have any similar micros at home so I thought I'd ask. This puts one of my personal projects on hold for this evening.

author: StillTrying
author_rank: Super Contributor
timestamp: August 02, 2016, 04:10:10 pm
content: I didn't see anything in the data sheet that said RX and IOC can't both work at the same time, you could always link RX to another IOC pin of course.Simulate it.

author: Kilrah
author_rank: Unknown
timestamp: August 02, 2016, 04:23:06 pm
content: QuoteIf the GPIO functionality wasn't disabled on peripheraloutputpins then you could presumably turn the pin into an output, set it to a level that conflicts with what the peripheral puts out and thus cause a short.So when a pin has a peripheral output assigned to it it's forced as an input from the GPIO side of things. It changes nothing at all to the input function, you can use IOC as you want. You can even use IOC on the TX line if you felt like, IOC is aninputfunction.Unrelated, but obviously be careful at what you do in that interrupt as you'll be receiving a bunch of them, and some at the same time as your receive interrupt.

author: void_error
author_rank: Frequent Contributor
timestamp: August 02, 2016, 05:02:11 pm
content: IOC on the TX line could be useful, I asked the question because I'll have RX/TX activity LEDs and I want them to be toggled by the bytes sent/received on UART instead of slapping an extra transistor directly on the RX/TX lines to drive the LEDs.Why use a transistor? Because the RX line is driven by an open-collector logic optocoupler and the TX line has to drive an optocoupler's LED, and adding an extra load to the pin will mess with the edges of the signal on those lines.Since I have some pins available I thought about using IOC for RX, for TX there's the TXIF flag.As far as interrupt code goes it's not much, only a handful of instructions in assembly (no, I'm not coding in assembly, only done it once when I started out, using C now).It'll be like this:For RX:IOC interrupt -> clear IOCBF5 -> turn RX LED on -> disable IOC -> return / turn LED off when RCIF is set and re-enable IOCFor TX I have two options: use TXIF or IOC although the first option is more convenient:Write to transmit buffer and turn LED on / TXIF interrupt -> clear TXIF -> turn TX LED off -> return.Can't wait to try this out tomorrow after work.

author: MicroBlocks
author_rank: Contributor
timestamp: August 02, 2016, 05:57:56 pm
content: Why not use the TXIF and RCIF interrupts to switch the leds on, set a flag and a few milliseconds later switch them of.That would just take a couple of lines.Also the leds would brightness would not be influenced by the baudrate. Keeping them on/off for about 100ms or so gives a good visual indication.

author: JPortici
author_rank: Super Contributor
timestamp: August 02, 2016, 06:21:46 pm
content: you already have those interrupts without having to resort to convoluted methods.TXIF: Transmit buffer empty (if TXFIFO is present it can be configured to generate an interrupt on any position of the FIFO)RCIF: Receiver buffer full (if RCFIFO is present... you get it)Actually you CAN modify the state of the pin AT ANY TIME, if you write on the PORTx register. The output will be modified for a portion of the instruction cycle before the peripherals regain controls, resorting to glitches in the pin(that's why you RMW or better yet use the LATx register)if you absolutely need to detect the start bit the IOC should work anyway.. or you tie the UART pin with another one and use that other pin IOC

author: void_error
author_rank: Frequent Contributor
timestamp: August 02, 2016, 07:13:36 pm
content: Quote from: MicroBlocks on August 02, 2016, 05:57:56 pmThat's another option and a pretty good one. I've got two timers available, Timer0 and Timer2.I needed to detect the start bit for debugging purposes. With IOC on RX I'd have the bytes "gated".

author: JPortici
author_rank: Super Contributor
timestamp: August 02, 2016, 07:39:58 pm
content: oh wait.. you want to turn on the LEDs when you send/receive a message? i think i would use a not gate (after the optocoupler) and i would use another couple of nots to drive the tx line so i already have a couple unused(this is how is it done on a couple of midi interfaces i have anyway)

author: void_error
author_rank: Frequent Contributor
timestamp: August 02, 2016, 08:00:49 pm
content: Not exactly... or I didn't get your question.I just want to keep the indicator LEDs lit up while the RX buffer fills or the TX buffer is emptied, the LEDs are on pins other than RX or TX.I've used the two NOT gate configuration before, but I needed to drive 24 optocouplers and I would have exceeded the maximum Vdd/Vss pin current.74HC04 to the rescue... three of them. I did drive 8 of the optos using a GPIO port with no problem.In this case however, I only need to drive 3, the only thing I need to care about is exceeding the maximum current sunk by those two pins.With H11L1 I managed to get away with about 5mA through the LED, good up to 230.4k BAUD. I'm currently planning to use TLP118 optos because of their smaller form factor.And the RX/TX indicator LEDs won't need more than 1mA, I don't want my board to look like it belongs in a disco, like some dev boards talked about on the forum... 10-15mA through a modern LED - that's insane.

author: Cervisia
author_rank: Regular Contributor
timestamp: August 04, 2016, 11:42:52 am
content: Quote from: void_error on August 02, 2016, 08:00:49 pmThe H11L1 is guaranteed to need no more than 1.6 mA.QuoteDo you really need 20,000,000 baud? The TLP2361 (15 Mbaud) would work with 1.6 mA, too.

author: David Hess
author_rank: Super Contributor
timestamp: August 04, 2016, 02:31:29 pm
content: I always use a driver for LEDs instead of driving them directly from complex logic to avoid excessive ground or supply noise. A transistor or separate gate allows routing the LED current directly to a low impedance point.I like the idea of pulse stretching via an IOC function but I would use my fast housekeeping interrupt instead of a dedicated timer. Then if I wanted an accurate delay, I would let the fast housekeeping interrupt toggle the LEDs and signal it from the IOC function through a flag to keep interrupt overhead as low as possible. In most applications this level of detail is not required though.

author: void_error
author_rank: Frequent Contributor
timestamp: August 08, 2016, 05:29:19 pm
content: Quote from: Cervisia on August 04, 2016, 11:42:52 amUnless you want a lower propagation delay. Went with 5mA so the LED's parasitic capacitance is charged/discharged faster and it was actually less than 5mA because the LED had a resistor in parallel, didn't do that many measurements, was in a hurry. The aim was to match propagation delays.Quote from: Cervisia on August 04, 2016, 11:42:52 amToo bad I can't get that from the main distributor I use, found it on Mouser but shipping is 20 euros compared to TME which ships for less than 5.They do have the TLP2362 which is the cheapest in that package but it needs more drive current.Quote from: David Hess on August 04, 2016, 02:31:29 pmA PNP emitter follower should do the trick then... or NPN if I invert the signal on the RX and TX lines in firmware (just some register settings).Quote from: David Hess on August 04, 2016, 02:31:29 pmFor pulse stretching that would be my approach too, I don't like my interrupt service routines too cluttered.But if it's just toggling a LED then it's the same as toggling a flag.Another thing... since this is part of a USB-UART converter (yes, I know, I can get a FT232 or CH340 or MCP2200 to do the same job but I might need the option to reprogram it as a custom HID), what can I do with the 2 extra pins I have left on my micro (PIC16F1459)? Do I really need the RTS/CTS lines or can I get away without them and use a lower pin count micro (PIC16F1454)?