Monday, December 24, 2007

AVR hacking

For the past couple of weeks I have finally had the chance to play with AVR microcontrollers.  A few months ago I bought an Atmel STK-500 evaluation board but it took me a while to get it fired up.  I started out using the AVR Studio integrated development environment, but being more of an old school programmer, those fancy-schmancy GUI tools with their point-and-click code editing drive me crazy.  I can edit code much faster with vi than by having to move a pointer around with a mouse.  Besides that, I try to limit the use of Windows at home, so I have successfully moved to developing code on my Mac using the GNU AVR tool chain.  Thanks to the OSX-AVR distro, the transition was pretty smooth.

Since I am just starting out, I needed to write a Hello World program.  Using the ATmega8515L processor that came installed on the STK-500, I wrote some routines to drive some DL1414 alphanumeric displays I had.  Some of my first 68HC11 microcontroller projects back in the late '80s used similar DL1416 displays, so it was sort of returning to familiar territory.  However, the AVR environment is much nicer than what I did on the the 'HC11, since writing code in C is a lot easier than hammering out assembly code one instruction at a time.




The circuit I came up with for the DL1414 was simply the external memory interface Atmel recommends for the '8515L.   It's remarkably similar to the 68HC11 <-> DL1416 interface I devised back in 1989.  (See below)  However, the Atmel processor has a mode to support it directly so I can write to the display as write-only memory, no fancy bit-banging required.  I had to bit bang the individual I/O lines with the 68HC11 because interfacing memory to the processor would use up all of the parallel I/O lines unless you used port replication expansion chip, which I didn't have.




The only snag is that the characters on the display are addressed right to left whereas strings are handled in C from left to right. Thus I needed a little extra code to reverse the order of the characters:


int dl1414str(sp)

char *sp;  /* pointer to a string to display */

{
    int length;
    int i;
    char *daddr;

    length = (int) strlen(sp);

    if (length > DL_SIZE) length = DL_SIZE;

    daddr = (char *)DL_ADDR;

    /* We have to reverse the order of the characters since the
           addressing of display characters is "backwards." */
    for (i=0;i<length;i++) daddr[(DL_SIZE-1)-i]=sp[i];       

    /* Blank out end of line if string being displayed is shorter than
       the display itself */
    if (length < DL_SIZE) for (i=0;i<(DL_SIZE-length);i++)
        daddr[i]=' ';

    return(0);
}