Sunday, April 17, 2011

Shift Registers

My idea for an 8-bit hex decoder discussed in the previous post turns out to have been overcomplicated.  It would've been fun to implement, but was still too complicated.  Recall that I was going to use a PISO shift register for input, an ATTiny85 as the brains, and two SIPO shift registers -- one for each 7-segment display.  Looking around (I can't remember the source), I realized that the output stage didn't need nearly quite so many components.  If I have nine output pins (maybe eight?), I can connect both displays simultaneously, using the same pins, with transistors on their common anode lines to switch between the two.  The idea is that I set the segments on the first display while the second is off, and then vice versa.  Do it fast enough, and the eye thinks they've both been on the whole time.

In order to do this, though, I need 8-9 output pins on the microcontroller which can be devoted to the output stage.  As it happens, the ATTiny2313 should have enough, and is about the size of the ATTiny85 and one of the shift registers.

But enough about that.  I wanted to play with shift registers, even if I wasn't going to use them in the digit decoder.  To do that, I used an ATMega644 to drive a single 7-segment display.  For input, I used four switches connected to a 74HC165N shift register.  Output was via a 74HC565N shift register.  Why shift registers and an ATMega644, which is wildly overpowered for this application, and which could read the switches and drive the 7-segment display directly?  I didn't want to have to worry about microcontroller constraints (RAM size, etc), and wanted to concentrate on the shift registers.


This is the most complicated circuit I've ever breadboarded, and it just about fills up the breadboard.  Everything from the ATMega644 to the left on the lower row is necessary support stuff (from right to left, the MCU, RS232 transceiver, and power switch.  So basically support stuff takes up 1/3 of the board, leaving me the other 2/3.  I'm going to need to switch to the big board soon.  I'm tempted to leave the ATMega644 set up on this one so I don't have to rewire it and the transceiver whenever I want to use it.  At the very least, I'll probably leave it set up until I verify whether I can make the hex decoder work.

Lessons learned (or relearned):
  • Fuses are important.  Not the kind that blow when there's too much current (though they're useful too), but the kind Atmel uses to configure AVR processors.  The first one to bite me was the one that controls the JTAG interface. With it enabled (which it is by default), PC2-PC5 are dedicated to JTAG use.  PC0 and PC1 function normally, which gave me one heck of a time trying to figure out why an early 3-LED circuit (one each on PC0-PC2) would only partially work.
  • The other important fuses are the ones which control the oscillator.  Atmel has a bewildering array of oscillator configuration options, involving 8 of the 19 fuses on the ATMega644.  This AVR fuse calculator was very helpful.
  • To write fuses, invoke avrdude as
    avrdude -p part -U fusename:w:0xvalue:m
  • To read fuses to stdout, invoke it as
    avrdude -p part -U fusename:r:-:h
  • I'd learned about aliasing while watching an EEVblog review of the "budget" Agilent 2000-series oscilloscope, and this time I got to see it in person.  I wanted to verify that the processor was running properly at 16MHz, so I set the CKOUT pin, and ran it through my PCSU1000.  I don't remember which Time/Div setting I was using, but I was seeing a stable output sine wave at about 1kHz, rather than 16MHz.  Hilarity ensued until I remembered Dave's mention of aliasing, at which point I decreased the Time/Div setting.  Low and behold, a 16MHz wave appeared.  So that was exciting.
  • You don't use the same variable for writing AVR ports as you do for reading them.  PORTn for output, PINn for reading.   Reading from PORTn, expecting to get input values, will only lead to sadness and dismay.

Wednesday, April 6, 2011

Plans for my next design, and a breakout board for the AVRISP2

I'd like to build a circuit which samples 8 bits of input and displays the results as a hexadecimal number on two 7-segment displays.  This would be much simpler if the standard 7400-series decoders weren't all BCD, and thus didn't all stop at 9.  There are true hexadecimal multi-segment drivers, but the one that looked best (the ICM7212) was close to $7, and would've required lots of support glue.

Digression: The ICM7212 controls four 7-segment displays.  The 40-pin DIP has one pin for each segment on each display, four digit pins, and four data pins.  To display a value on a given 7-segment display set the data lines with the desired value, and toggle the appropriate digit line.  This circuit will have eight data lines inbound, so we'd need a quad 2-1 mux (the 74HCT157, for example).  We only need to toggle two digit lines, which we could do with a 555 and an RTL inverter.

For giggles, let's cost it out (all prices from for individual quantities); $6.70 for the ICM7212, $0.47 for the timer, and $0.69 for the mux.  We'll assume that the resistors, capactors, and transistors needed for the 555 timer glue and for the inverter are free. $8.55 for the whole thing.  Oh, and the ICM7212 is huge.

All of this is a long way of justifying doing it with a microcontroller instead.  The added advantage of doing it with the microcontroller and shift registers is that I'll likely see them again (and again and again), so it'd be helpful to gain some experience.

So the current plan is to do something with an ATtiny85 microcontroller.  A parallel-in-serial-out (PISO) shift register on the input, sampled periodically by the microcontroller, and two serial-in-parallel-out (SIPO) shift registers on the output.  If we can share the clock lines between all three chips, I think we can get away with using only four pins on the microcontroller.  The tiny has 6, excluding VCC and GND, so this should be doable.

To familiarize myself with the chips required, I decided to build the beAVR setup described here.  It's nothing fancy -- just an ATmega644 with supporting gunk (caps, clock, etc).  I don't have the USB-to-5V serial cable recommended in the article, so I also had to add an SP3232EBCP RS232 transceiver so I could hook up the USB serial line.  This won't be needed for the final design, with the tiny, but it's nice to have for debugging.  Who knows -- with two pins left, maybe I can use it on the tiny.

I've done the medusa head AVRISP2 connection before.  I didn't like it then, and I don't like it now, so this time I decided to do something about it.  I built a little breakout board that transforms the 2x3 pin ISP connector to 1x6pin, which is compatible with the breadboard.   Here are some pictures:

Things I learned from building this thing:
  • The Helping Hands are amazingly useful.  Now I have a stable suspended platform on which to solder.  It makes things like header pin alignment considerably easier.
  • The default font in TextEdit (12pt Helvetica?) has precisely the right vertical spacing when you print at 50%.
  • To attach the labels, print on a full-size sheet of paper, cut out the width to fit (from the top of the VCC to the bottom of the MOSI), but leave it an inch or two longer than necessary.  This gives you a nice handle with which to hold the label while you superglue it to the plastic thing on the header.
  • I'm not a huge fan of long pad-to-pad solder bridges.  I like wires.  They're much less fussy than bridges.
  • Hot glue is, once again, my friend.  I used it to protect the underside of the PCB.
What I'll do differently next time (there will be a version two):
  • This version's pin mapping between the 2x3 header and the 1x6 is based on shortest distance.  Unfortunately, that approach results in a 1x6 ordering that doesn't match the pin ordering on the ATmega644.  As I'll likely be doing most of my programming with the mega, I'd rather the breakout board just drop into place, without requiring me to string wires hither and yon.  Version 2's mapping will follow the ATmega644 pin ordering.  VCC and GND may be shifted back on the board, behind the 2x3, allowing them to plug directly into the breadboard power rails.
  • Pin labels should be visible regardless of breakout board orientation.  In this version, they're only visible from the front, which makes it awkward when I install it with the front facing away from me.  The paper is fragile, but I knew that going in.  We'll see how it works out.  I may need to switch to another material.

Monday, April 4, 2011

Mac Serial Program

Having grown weary of Minicom, and not really wanting to set up screen to talk to a serial port, I went looking for a Mac terminal program.  I think I have a new favorite: goSerial.  It does all the basic things you'd want, and looks like it'll meet my needs nicely.  Notably, it looks nothing like this.