Lets Avr drive Led and Lcd displays

Introduction

In not so old time, it was common to have a lot of components around a microprocessor to drive a lcd or led display. The display was stuck to the board and in the case the board was no longer usefull it was not easy to reuse the display.

With Avr and certainly others micros, things become more easy. Just stick a micro to the back of the display, lets the micro do the dirty things and connect it to your board with a three wires whithout taking the risk to be too tired.

Overview

This is an arrangement done for the purpose of the picture. Don't try to find some other usefullness.

We can say : they are all different with a lot of common features.

Harware

The design is done in order to simplify the hardware and consist to connect, in a bit to bit way, an unused microprocessor pin to an active pin of the display. This can give a lot of possible combinations that can be restricted with mechanical considerations. My ones are to put the display on one side and the processor on the other side and try to connect the more pins possible with the shorter wire.

Taking for example the aff4 design, which is a 40 pins LCD connected to a 40 pins processor, the internal number represents the processor pins, external number the LCD pins, the dotted line a short connection between the processor and the LCD, and longer connection for example A4 LCD is connected to processor PA2. Here, Reserved pins are VCC, GND, RESET, RXD TXD, XTAL1, XTAL2. On the LCD A2 mean segment a of rhe second digit...

 *  40 K0  ------           PB0  1    40 VCC          PB0  1 bp
 *  39 nc          F2       PB1  2    39 PA0  G4           2 nc
 *  38 dl          A2       PB2  3    38 PA1  F4           3 nc
 *  37 G1  ------           PB3  4    37 PA2  A4           4 nc
 *  36 F1  ------           PB4  5    36 PA3     ------    5 E1
 *  35 A1  ------           PB5  6    35 PA4     ------    6 D1
 *  34 B1  ------           PB6  7    34 PA5     ------    7 C1
 *  33 nc          G2       PB7  8    33 PA6  d1dp1        8 dp1
 *  32 G2  PB7           -RESET  9    32 PA7     ------    9 E2
 *  31 F2  PB1          RXD PD0 10    31 PE0     ------   10 D2
 *  30 A2  PB2          TDX PD1 11    30 PE1     ------   11 C2
 *  29 B2  ------           PD2 12    29 PE2     ------   12 dp2
 *  28 d2  ------           PD3 13    28 PC7     ------   13 E3
 *  27 G3  ------           PD4 14    27 PC6     ------   14 D3
 *  26 F3  ------           PD5 15    26 PC5     ------   15 C3
 *  25 A3  ------           PD6 16    25 PC4     ------   16 dp3
 *  24 B3  ------           PD7 17    24 PC3     ------   17 E4
 *  23 G4  PA0            XTAL2 18    23 PC2     ------   18 D4
 *  22 F4  PA1            XTAL1 19    22 PC1     ------   19 C4
 *  21 A4  PA2             GND  20    21 PC0     ------   20 B4

At this point, we can wire the circuit or make a PCB, we can draw a schematics...

Preparing for the driving table

I am used to put, as a comment in the source file, a pinout of the processor and the name of the signal a pin connect to. This can be done with using the previous mapping. An example is shown below : so pin 1 of processor is connected to K0 which is the back plane of the display. This comment will be used later by the mkledtab program to generate a source file containing the driving table.

 *        model ndigit ndot      microname
 * PinOut LCD_1 4 2          ATmega8515
 * 
 *  K0             (OC0/T0) PB0  1    40 VCC                 VCC
 *  F2                 (T1) PB1  2    39 PA0 (AD0)           G4
 *  A2               (AIN0) PB2  3    38 PA1 (AD1)           F4
 *  G1               (AIN1) PB3  4    37 PA2 (AD2)           A4
 *  F1                 (SS) PB4  5    36 PA3 (AD3)           E1
 *  A1               (MOSI) PB5  6    35 PA4 (AD4)           D1
 *  B1               (MISO) PB6  7    34 PA5 (AD5)           C1
 *  G2                (SCK) PB7  8    33 PA6 (AD6 d1)        d1dp1
 *                       -RESET  9    32 PA7 (AD7)           E2
 *  RXD               (RXD) PD0 10    31 PE0 (ICP/INT2)      D2
 *  TXD               (TDX) PD1 11    30 PE1 (ALE)           C2
 *  B2               (INT0) PD2 12    29 PE2 (OC1B)          dp2
 *  d2               (INT1) PD3 13    28 PC7 (A15)           E3
 *  G3                (XCK) PD4 14    27 PC6 (A14)           D3
 *  F3               (OC1A) PD5 15    26 PC5 (A13)           C3
 *  A3                 (WR) PD6 16    25 PC4 (A12)           dp3
 *  B3                 (RD) PD7 17    24 PC3 (A11)           E4
 *                        XTAL2 18    23 PC2 (A10)           D4
 *                        XTAL1 19    22 PC1 (A9)            C4
 *  GND                    GND  20    21 PC0 (A8)            B4

From the input to the segments

The input is driven by another application connected on the serial line and is received by the internal usart. It is a displayable characters string with the first character acting as command. for example, to display the time :

H 1:04:59 

For my 4 digit LCD, the decoding function prepare a 4 byte buffer containing the index in table tcod_seg, see the file segled.c. So to display " 1 04", the buffer is set to values 0x16, 1, 0, 4. And the values addressed by these indexes are 0, 0x06, 0x7E, 0x96.

Each bit set in these values corresponds to a lighted segment as indicated in the next paragraph. The first byte 0 do not light any segment, the digit is blank, second byte 0x06 fires segment b and c, byte 0x7E fires a, b, c, d, e, f and byte 0x96 fires b, c, f, g representing respectively the symbols blank, "1", "0", "4".

*    Multiplexage : from left to right  digit 0 to digit 8
*                      bit 0 light the dot decimal point
*    Segment Command : bit 1 a 7 corespond aux segments de a-g
*                       bit 0 => dp.
*                       bit 1 => segment c
*                       bit 2 => segment b
*                       bit 3 => segment a
*                       bit 4 => segment f
*                       bit 5 => segment e
*                       bit 6 => segment d
*                       bit 7 => segment g
*    Segment lights if the corresponding bit is 1
*
* *
* *             a
* *            ***
* *           *   *
* *         f *   * b
* *            ***
* *           * g *
* *         e *   * c
* *            ***
* *             d
*

As this point we know which segment to light for each digit, but we have to determine which port pins to activate and that depends from the mapping we have previouly prepared and converted to a table taddr_led.

Now for each digit and for each bit lighted we have to compose the display_buf according the values set in table taddr_led.

The display buffer is the image to be given to the port for each phase or multiplex. Our lcd is considerated to be a one phase so one buffer, but is a 2 phases. values are the same and inverted when phase change.

The led port update is done by interrupt at a rate that depend on the number of digits, the type of display led/lcd, the number of phase, or multiplex. The basic principle is to copy the display_buf to ports with some arrangement depending on display type and phase number.

Table taddr_led

The index in this table is defined like this:

 *   index = digit_bitseg
 *      bits  7  6  5  4  3  2  1  0
 *           D4 D3 D2 D1 D0 S2 S1 S0
 *   D4-0 = digit number 0-n or dot number
 *   S2-0 = Segment number 0-7, 0 is dp

The value at index in this table is defined like this:

 *   val = port_bit(index)
 *      bits  7  6  5  4  3  2  1  0
 *            x H0 P2 P1 P0 B2 B1 B0
 *   H0  = 0, 1 phase number
 *   P2-0 = port number 0-7 A,B,C,D,E + ext
 *   B2-0 = bit number in port 0-7

For our 4 digit LCD the value at index 1 is 0x05. Index 1 is the place where we find the port address for segment C digit 1 and value 0x05 means bit 5 on portA. If we take a look to the comment given in the C source file, we see that port PA5 is connected to segment C1.

This table is not easy to create and is subject to errors. But there is a some mechanical between the description comment and the table itself that can be delegated to the perl program mkledtab. This program takes as input the C source file et to be more precise, the comment describing the processor pins connection and generate the ledtab.c ledtab.h files that contains taddr_led table.

Using this method, a n phases common anode is processed the same way as a n phases common cathode the values are only inverted when sending to port.

Display N° 1

display number 1
back display number 1

Display N° 2

display number 2
back display number 2

Display N° 3

display number 3
back display number 3

Display N° 4

display number 4
back display number 4

Display N° 5

display number 5
back display number 5

Display N° 6

The attiny2313 supplies clock to atmega8515 on its CKOUT pin from its internal oscillator. Atmega8515 computes port settings for attiny2313 and send them on its SPI interface. Attiny2313 simply copy them to its ports.

display number 6
back display number 6

Display N° 7

display number 7
back display number 7

Schematics

I don't display the schematics as they are only showing wires between 2 components. But you can find then in the packages. You may need symbols to display/modify schematics with .See [3].

References

  1. [1] Gotronic Afficheurs LCD / Afficheurs à Leds.
  2. [2] An Avr bootloader program.
  3. [3] gEDA symbols.

Download

LICENSE

The Display softwares are licensed under the terms of the GNU General Public License as published by the Free Software Foundation. See the file "COPYING" in the download directory.