Microchip PICs

Introduction

Once upon a time, I'd make controller-based systems around the 8085 and the several supporting chips needed for that. These worked and still do work well, but they tend to be rather large -- hard to make something useful on anything much smaller than a 100 by 160 mm card, where about half of the space is taken by mandatory chips.

To make anything useful it starts with the 8085, 74LS373 for the address latch, 2764, 27128, or 27256 for the EPROM, then 74LS139 for address decoding, one or two 61256 for RWM, 74LS32, 74LS74, 74LS04, maybe a 74LS240 for interrupt action and 74LS245 for IO bus buffering. That is close to a dozen devices, just before any real interesting stuff can begin to happen. There is now also the matter of obtaining new devices; the processors and EPROMS needed are increasingly harder to obtain, and they are forever becoming more expensive. Then there is the matter of the sockets and wiring which takes time and was just as, or more, expensive as the ICs themselves.

It worked and it still works well (tcx33) and reliable once assembled, but it is old-school and parts are getting hard to procure.

Then there are the now-extinct Motorola 68HC705K1, single-chip devices in their 16-pin cases of which 11 were available for interesting IO. (uswm) The available programmer would only run properly on an old 4.77MHz PC with MS-DOS, as a faster machine would not generate the correct timing... Even these would need some additional ICs in order to communicate with other devices such as A-D converters or make frequency measurements, by generating timing pulses to start and stop 4040-type counters.

Yet these were an improvement when it came to chip count and power consumption, but the limited IO would make them less useful when wanting to transfer much information in or out.

Because even before today's networked machines, the interesting action was all about getting information from one device to another: some device or instrument would sit quietly somewhere in the yard or a remote corner of the house reading sensors and controlling devices, whilst others would be sitting on a shelf indoors displaying these values and maybe allowing for inputs that would change the operations.

Back in those days, serial ports, as in RS-232 serial, was the way things would be made to work. Ethernet was for PCs and servers, which could not be put in a corner and left to run for months or years without attention. Besides regular RS232, there were analog lines, and multiwire serial data connections, but all of these were and are point to point.

Then the Picotux appeared. Picotuxes are discussed at length elsewhere on these pages ; suffice it to say, that they made it possible to go from the point-to-point dedicated serial lines, to use Ethernet networking to communicate with the world at large, as well as extending short-haul IO by using an i2c bus to connect various other sensors and devices to it.

However, the Picotux had a few shortcomings that needed to be worked around: they started out with a read-only root file system, so there was no easy way of configuring them to start out running specific programs. They also only had 6 documented GPIO lines in addition to the serial port, besides another undocumented GPIO line and the undocumented i2c port. Interestingly enough, on startup, a PCF8574P connected to it would "twitch" some of its data lines in a predictable manner. One of these, D3, would start out H, then go L and back to H about 20 seconds after power-on or reboot. About 70 seconds after this, the Picotux would emit its signon message on the serial port, ending it with the root-user prompt character, a #. So, how about adding a device that would be reset by the D3 line from the PCF8574, then wait for the # to appear on the serial port, and then feed some startup-command back to the console? That would maybe work?

Now, the Picotux runs the serial port at 38400 Baud, and that was too fast for the good old 8251A, so in the earliest systems the serial receiver was implemented with some 74LS74s and an 74LS164 shift register, then a 74LS521 comparator was used to look for and discover the # character, upon discovery of which it would start a 4040 counter, playing a sequence of bits from an EPROM back into the Picotux forming a string such as "go". This worked and still works, splendidly, but it basically ended up with about as many ICs as any of the old 8085 systems, even before adding some ICs for IO expansion. Essentially, the nice little compact Picotux ended up sitting in a corner of a large board full of ICs. Not elegant at all... (sym40, stn44, stn45, stn50, stn51)

So the question came up, would there not be some single-chip microcontroller available that could be programmed to do just this: wait for the # and when it comes, reply "go" as well as changing some IO bit to indicate that we have started and might want to receive serial input from somewhere else. Or maybe act on other serial characters, or maybe even squawk some characters when something else of interest is happening, as a form of interrupt-action? Since the Picotux doesn't readily support being interrupted other than in the form of receiving characters on its serial port or network interface.

PIC16F628A

On searching around, I discovered an article where someone had connected a PIC16F628A to an LCD display, and used its serial hardware. I downloaded the data-sheet for the PIC16F628A, and indeed, this controller has a USART, among more commonly seen GPIO, timers, etc. Very interesting.

I went to ELFA and ordered 10 of them, as well as a PicKit2 programmer and started development. The onboard UART is capable of running at close to 38400 Baud with the internal oscillator. However, the frequency was a little off, so I found out I had to run it from an external oscillator; though with this, the startup and running worked perfectly fine: The D3 "twitch" from the PCF8574P would be used as the reset pulse, then sit and wait for the # coming from the Picotux and then send it a startup command such as "go" and it would be on its way. Now put the whole assembly in some remote place of the property, hook it up, power it on, wait for a couple minutes for the Picotux to get started and initialized and there it is good to go. (gar43, sym47, sym51)

Now the PIC16F628A has several more pins available, which ought to be useful for something? Yes -- one of these could be configured to generate a PWM signal with 10 bits resolution; seeing as the device is already connected to the Picotux, it was a matter of defining the necessary serial protocol between the two. Similarly, Interrupt-on-change could be made to hit the Picotux with some strings, allowing for it to react to external changes. A very good match of the two devices, and no need for enormous perfboards and dozens of sockets anymore.

Also, the extra IOs and PWM output turned out useful with several devices, such as a motor-controller, that would use the PWM for speed, and some timed pulses for start and stop. (sym75)

PIC16F690

The PicTool2 programmer came with a demo card, on which there was another, 20-pin PIC, the PIC16F690. It advertised the presence of an A-D converter so I found it interesting and downloaded its datasheet as well. And not only was there the A-D converter, as well as serial port and PWM and timers and internal eeprom like the 16f628A had too; but there was this SSP module, allowing for SPI and I2C master or slave operations.

Hmm... i2c slave, and ADC, and eeprom; that sounds like this could do much the same as both a PCF8591 (or one or more ADC0804s with necessary multiplexers and IO-expansion chips) and the PIC16F628A.

So another order was made, for more PICs, some more 16F628As as well as 16F690s.

And indeed, the ability to make them as smart i2c slave devices is great. During the last few years, I have come up with a rather standardized set of programs for these now; they run as i2c slave, with varying presence of pwm, adcs, interrupt-on-change, serial port, servo drive, accumulator-function and even frequency measurement. (stn76, wse93)

The i2c works with the bit-banging i2c-gpio subsystems in the Picotux and the WD Worldbook, as well as when using this on a Raspberry Pi.

Later I got it got it working with the in-built i2c-bus functions in the Raspberry Pi, by ignoring the start bit and running the PIC16F690 at 8MHz. This same configuration works fine with the PineA64 devices as well.

It needed to run at 8 MHz, or there would be occasional dropouts.

Of course, the Worldbook, the Raspberry Pi and the PineA64 are configurable and can be made self-starting, so the startup-hack that the Picotuxes needed is no longer required, thus the serial port or its pins become available for other uses.

Programming the PIC16F628 and PIC16F690

We use the gpasm program, from the gputils (GNU PIC utilities) package.

Example of a makefile for PIC16F690

all: flowco57.hex
	-rm -f datetime.as
	echo OK

INCDIR=/usr/share/gputils/header
INCFIL=/usr/share/gputils/header/p16f690.inc

flowco57.hex: flowco57.asm datetime.as
	gpasm -I $(INCDIR) -p 16f690 flowco57.asm
	grep ^Errors flowco57.lst
	grep ^Warnings flowco57.lst
	grep ^Messages flowco57.lst

datetime.as: 
	dtmark > datetime.as

clean:
	-rm -f flowco57.hex datetime.as

the dtmark program emits some relevant assembly code with today's date in it, so the date and time of compilation can be made part of the assembly program.

apt install gputils gputils-common gputils-doc

Programming the device itself with pictool 2 can be handled via the pk2cmd program; I have made a shell-script for this

#!/bin/sh

# Information on the device
echo Information
pk2cmd -PPIC16F690 -I

# Pull contents out of the device
# pk2cmd -PPIC16F690 -GF dev.hex

#erase
echo Erasing...
pk2cmd -PPIC16F690 -E

#blank check
echo Blank Check...
pk2cmd -PPIC16F690 -C

# Program
echo Programming ...
pk2cmd -PPIC16F690 -F $1 -M

# Load and verify some hex file against device contents
echo Verifying ...
pk2cmd -PPIC16F690 -F $1 -Y

For the PIC16F628 all of this will be similar, just that we refer to the 16f628 instead of 16f690 for the .inc file, in the -p argument to gpasm, and the device strings to the pk2cmd.

PIC12F675 and PIC12F683

These are like the little cousins of the PIC16F628 and PIC16F690. They have internal oscillators, AD-converters and eeprom, though no i2c or serial port, but they come in the small 8-bit packages, allowing for up to 6 IO lines.

PIC12F1822

This is almost like the 16F690's little brother, as it has most of the same periferals in it, but only 8 pins, so not everything can be used at once. Yet, sometimes that is what is needed, and there isn't the sense of waste of not using all the pins on the 16F690. Running this as an i2c slave with an analog input, an accumulator input, and a frequency-counter input, makes it a great interface for various kinds of sensors when hosted by a Raspberry Pi.

Here, pin 2 is frequency-counter input, pin 3 is accumulator pulses input and pin 7 is ADC in, Full scale 2.048 V, whether the device itself is run at 3.3 V or 5 V.

An updated version of the software allows pin 7 to be used for accumulator units output pulses instead of ADC input.

I did have to obtain a PicTool3 programmer in order to program these however. The PicTool2 wasn't capable for this, apparently.

Some interesting links

Microchip documentation

PIC16F690 information page

Programmer hardware with Raspberry Pi

Programming the PIC from a Raspberry Pi

TLCs modification of the above

Thread in the Raspberry Pi forum