Wednesday, July 8, 2020

ATMega32 SPI Interfaces To SN74HC164 And LCD Using 3 Pins

The HD44780 character LCD type uses parallel interface with controller, even it operates in 4-bit data transfer mode. Currently most electronic hobbyists use an additional shift register or an I/O expanding chip, especially the PCF8574T chip.

ATMega32 SPI Interfaces To SN74HC164 And LCD Using 3 Pins
Character LCD With PCF8574T
In this example, I use SN74HC164 shift register to interface between controller and character LCD. 

ATMega32 SPI Interfaces To SN74HC164 And LCD Using 3 Pins
Schematic Diagram
I use two wires - serial data and serial clock to interface between controller and SN74HC164. However I use one additional pin to interacts with LCD Enable pin. It's because I have difficulty during programming.

  1. /*
  2.  * SPI74164LCD.c
  3.  *
  4.  * Created: 7/7/2023 9:48:09 AM
  5.  * Author : Admin
  6.  */
  7.  
  8.  
  9. #include <avr/io.h>
  10.  
  11. #define F_CPU 4000000UL
  12. #include <util/delay.h>
  13.  
  14. void masterInit(void){
  15. /*Set MOSI, SCK and SS Output*/
  16. DDRB|=(1<<4)|(1<<5)|(1<<7);
  17. /*Enable SPI Master Set Clock Rate Fclk/4*/
  18. SPCR|=(1<<SPE)|(1<<MSTR);
  19. }
  20.  
  21. void masterTransmit(unsigned char spiData){
  22. /*Start The Transmission*/
  23. SPDR = spiData;
  24. /*Wait For Completion*/
  25. while(!(SPSR&(1<<SPIF)));
  26. }
  27.  
  28. void lcdCmd(unsigned char cmd){
  29.  
  30. masterTransmit(cmd&0xF0);
  31. PORTB|=(1<<4);
  32. _delay_us(100);
  33. PORTB&=~(1<<4);
  34. _delay_us(100);
  35.  
  36. masterTransmit(cmd<<4);
  37. PORTB|=(1<<4);
  38. _delay_us(100);
  39. PORTB&=~(1<<4);
  40. _delay_us(100);
  41.  
  42. }
  43.  
  44. void lcdDat(unsigned char dat){
  45.  
  46. masterTransmit((dat&0xF0)|1);
  47. PORTB|=(1<<4);
  48. _delay_us(100);
  49. PORTB&=~(1<<4);
  50. _delay_us(100);
  51.  
  52. masterTransmit((dat<<4)|1);
  53. PORTB|=(1<<4);
  54. _delay_us(100);
  55. PORTB&=~(1<<4);
  56. _delay_us(100);
  57. }
  58.  
  59. void lcdInit(){
  60.  
  61. masterTransmit(0x00);
  62. _delay_ms(20);
  63. lcdCmd(0x33);
  64. _delay_us(100);
  65. lcdCmd(0x32);
  66. _delay_us(100);
  67. lcdCmd(0x28);
  68. _delay_us(100);
  69.  
  70. lcdCmd(0x0F);
  71. _delay_us(100);
  72. lcdCmd(0x01);
  73. _delay_ms(2);
  74. lcdCmd(0x06);
  75. _delay_us(100);
  76. }
  77.  
  78. void lcdStr( char *str){
  79. unsigned char i=0;
  80. while(str[i]!=0){
  81. lcdDat(str[i]);
  82. i++;
  83. }
  84. }
  85.  
  86. void lcdXY(unsigned char x, unsigned char y){
  87. unsigned char tbe[]={0x80,0xC0,0x94,0xD4}; // 20x4
  88. lcdCmd(tbe[y-1]+x-1);
  89. _delay_us(100);
  90. }
  91.  
  92. void lcdClear(){
  93. lcdCmd(0x01);
  94. _delay_us(10);
  95. }
  96.  
  97.  
  98. int main(void)
  99. {
  100. masterInit();
  101.  
  102. lcdInit();
  103.  
  104. lcdXY(1,1);
  105. lcdStr("ATMEGA32 SN74HC164");
  106.  
  107. lcdXY(1,2);
  108. lcdStr("Character LCD ");
  109. lcdXY(1,3);
  110. lcdStr("Interfacing Using");
  111. lcdXY(1,4);
  112. lcdStr("Three Wires.......");
  113. lcdCmd(0x0F);
  114. _delay_ms(100);
  115.  
  116. while (1)
  117. {
  118. }
  119. }
  120.  
  121.  
  122.  

Click here to download source file.

ATMega32 SPI Interfaces To SN74HC164 And LCD Using 3 Pins
Simulating Program


Tuesday, July 7, 2020

ATMega32 SPI Interfaces To SN74HC164 And LED

ATMega32 contains an SPI communication module. This type of communication interface typically uses 3 wires plus chip select pins. However this controller uses only two pins - serial data and serial clock pin to interface with SN74HC164 parallel out shift register chip.

ATMega32 SPI Interfaces To SN74HC164 And LED
Simulating Program

ATMega32 SPI Interfaces To SN74HC164 And LED
SN74HC164 DIP-14

I use Hardware SPI with the clock rate Fosc/4. Microcontroller clock is internal RC running at 4MHz.

  1. /*
  2.  * SPI74164LED.c
  3.  *
  4.  * Created: 7/7/2023 9:16:53 AM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #define F_CPU 4000000UL
  11. #include <util/delay.h>
  12.  
  13. void masterInit(void){
  14. /*Set MOSI, SCK and SS Output*/
  15. DDRB|=(1<<4)|(1<<5)|(1<<7);
  16. /*Enable SPI Master Set Clock Rate Fclk/4*/
  17. SPCR|=(1<<SPE)|(1<<MSTR);
  18. }
  19.  
  20. void masterTransmit(char spiData){
  21. /*Start The Transmission*/
  22. SPDR = spiData;
  23. /*Wait For Completion*/
  24. while(!(SPSR&(1<<SPIF)));
  25. }
  26.  
  27.  
  28. int main(void)
  29. {
  30. masterInit();
  31.  
  32. while (1)
  33. {
  34. masterTransmit(0xF0);
  35. _delay_ms(1000);
  36. masterTransmit(0xAA);
  37. _delay_ms(1000);
  38. masterTransmit(0x0F);
  39. _delay_ms(1000);
  40. }
  41. }
  42.  
  43.  

Click here to download its source file.

Sunday, July 5, 2020

ATMega32 Interfaces To SN74HC164 Shift Registers

A shift register is needed whenever we want to expand microcontroller outputs. The SN74HC164 is a parallel out serial shift register. This IC is very simple to use.

ATMega32 Interface To SN74HC164 Shift Register
SN74HC164 Pin Assignments

ATMega32 Interfaces To SN74HC164 Shift Registers
SN74HC164 DIP-14

Controller typically need only two pins - serial clock and serial data to interface to this chip.

ATMega32 Interface To SN74HC164 Shift Registers
Logic Diagram

Serial Data Input A (DSA) and Serial Data Input B (DSB) must be wired together. Otherwise we can make one input high.

ATMega32 Interface To SN74HC164 Shift Registers
Timing Diagram
 

To interface to this chip controller should have an SPI module. Otherwise the programmer must write an SPI software routine using bit banging.

In this example, I use software bit banging to send serial data to SN74HC164 chip. It needs only two pins - data and clock.

ATMega32 Interfaces To SN74HC164 Shift Registers
Schematic

I wrote this example in C using Microchip Studio.

  1. /*
  2.  * SN74HC164LEDBitBang.c
  3.  *
  4.  * Created: 7/7/2023 7:18:00 PM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #define SDAT 7
  11. #define SCLK 6
  12.  
  13. void send74hc164(unsigned char data){
  14. for(int i=0; i<8;i++){
  15. if ((data&(1<<7))==0)
  16. {
  17. PORTC&=~(1<<SDAT);
  18. }
  19. else PORTC|=(1<<SDAT);
  20. PORTC|=(1<<SCLK);
  21. for(int i=0;i<=50;i++);
  22. PORTC&=~(1<<SCLK);
  23. for(int i=0;i<=50;i++);
  24. data<<=1;
  25. }
  26. }
  27.  
  28. int main(void)
  29. {
  30. unsigned char newData = 0, oldData = 0;
  31.  
  32. DDRC|=(1<<SDAT)|(1<<SCLK);
  33. DDRB=0x00;
  34. PORTB=0xFF;
  35. while (1)
  36. {
  37. newData = PINB;
  38. if (newData!=oldData)
  39. {
  40. send74hc164(newData);
  41. oldData = newData;
  42. }
  43. }
  44. }
  45.  
  46.  

Click here to download zip file.

ATMega32 Interfaces To SN74HC164 Shift Registers
Simulating Program In Proteus

 

Friday, July 3, 2020

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers

A dot matrix display is a cool electronics hobby project for most of microcontroller learners. At the time I studied with PIC16F84A microcontroller, I program a simple single 8x8 dot matrix display using assembly language. I solder all LED of the display using only hand tool only.

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
A red 32x8 dot matrix display

Schematic Design

I use Proteus VSM 8.15 SP1 to design its schematic. There are some other professional schematic capture tools. But I get used to Proteus for many years now.
 

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Sheet 1

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Sheet 2

PCB Design

The PCB seems to be a double-sided copper board. But I use only one side to fabricate on copper clad. Another side, I use jumper wire to connect the tracks.

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
PCB View

 
Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Design 3D View
Click here to download Proteus PCB design.

PCB Processing and DIY Assembling 

I make this copper board using toner transfer method with my own laser printer, and stand drill. The copper pattern was etched using Ferric Chloride acid.

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Laser Printing on Glossy Paper

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Toner Transfer to Copper Clad

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Components side toner transfer

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Finished etching with lead plating

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Finished PCBA Etching with lead plating

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Arduino Test Program #1

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Arduino Test Program #2

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Front Panel LED matrix

Making A 32x8 Dot Matrix Display With SN74HC595N Shift Registers
Components side with stand off

Source Code:


/* Main.ino file generated by New Project wizard
 *
 * Created:   Thu Sep 5 2013
 * Processor: ATmega328P
 * Compiler:  Arduino AVR
 */

#include <SPI.h>
#include <TimerOne.h>
 
const char EN=10;
 
//unsigned char dot1[8]={0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA};
//unsigned char dot1[8]={0x00,0x00,0x00,0x01,0x03,0xFF,0x00,0x00};
//char dot1[8]={0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00};
//unsigned char dot1[8]={0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00};
//unsigned char dot2[8]={0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00};
//unsigned char dot3[8]={0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00};
/*
unsigned char dot1[3][8]={{0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00},
                  {0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00},
                  {0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}};
*/

/*
volatile unsigned char dot1[26][8]={
    { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00},   // U+0041 (A)
    { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00},   // U+0042 (B)
    { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00},   // U+0043 (C)
    { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00},   // U+0044 (D)
    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00},   // U+0045 (E)
    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00},   // U+0046 (F)
    { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00},   // U+0047 (G)
    { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00},   // U+0048 (H)
    { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0049 (I)
    { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00},   // U+004A (J)
    { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00},   // U+004B (K)
    { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00},   // U+004C (L)
    { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00},   // U+004D (M)
    { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00},   // U+004E (N)
    { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00},   // U+004F (O)
    { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00},   // U+0050 (P)
    { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00},   // U+0051 (Q)
    { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00},   // U+0052 (R)
    { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00},   // U+0053 (S)
    { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0054 (T)
    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00},   // U+0055 (U)
    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},   // U+0056 (V)
    { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00},   // U+0057 (W)
    { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00},   // U+0058 (X)
    { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00},   // U+0059 (Y)
  { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z)
};
*/

unsigned char font8x8_basic[128][8] = {
    { 0x000x000x000x000x000x000x000x00},   // U+0000 (nul)
    { 0x000x000x000x000x000x000x000x00},   // U+0001
    { 0x000x000x000x000x000x000x000x00},   // U+0002
    { 0x000x000x000x000x000x000x000x00},   // U+0003
    { 0x000x000x000x000x000x000x000x00},   // U+0004
    { 0x000x000x000x000x000x000x000x00},   // U+0005
    { 0x000x000x000x000x000x000x000x00},   // U+0006
    { 0x000x000x000x000x000x000x000x00},   // U+0007
    { 0x000x000x000x000x000x000x000x00},   // U+0008
    { 0x000x000x000x000x000x000x000x00},   // U+0009
    { 0x000x000x000x000x000x000x000x00},   // U+000A
    { 0x000x000x000x000x000x000x000x00},   // U+000B
    { 0x000x000x000x000x000x000x000x00},   // U+000C
    { 0x000x000x000x000x000x000x000x00},   // U+000D
    { 0x000x000x000x000x000x000x000x00},   // U+000E
    { 0x000x000x000x000x000x000x000x00},   // U+000F
    { 0x000x000x000x000x000x000x000x00},   // U+0010
    { 0x000x000x000x000x000x000x000x00},   // U+0011
    { 0x000x000x000x000x000x000x000x00},   // U+0012
    { 0x000x000x000x000x000x000x000x00},   // U+0013
    { 0x000x000x000x000x000x000x000x00},   // U+0014
    { 0x000x000x000x000x000x000x000x00},   // U+0015
    { 0x000x000x000x000x000x000x000x00},   // U+0016
    { 0x000x000x000x000x000x000x000x00},   // U+0017
    { 0x000x000x000x000x000x000x000x00},   // U+0018
    { 0x000x000x000x000x000x000x000x00},   // U+0019
    { 0x000x000x000x000x000x000x000x00},   // U+001A
    { 0x000x000x000x000x000x000x000x00},   // U+001B
    { 0x000x000x000x000x000x000x000x00},   // U+001C
    { 0x000x000x000x000x000x000x000x00},   // U+001D
    { 0x000x000x000x000x000x000x000x00},   // U+001E
    { 0x000x000x000x000x000x000x000x00},   // U+001F
    { 0x000x000x000x000x000x000x000x00},   // U+0020 (space)
    { 0x180x3C0x3C0x180x180x000x180x00},   // U+0021 (!)
    { 0x360x360x000x000x000x000x000x00},   // U+0022 (")
    { 0x360x360x7F0x360x7F0x360x360x00},   // U+0023 (#)
    { 0x0C0x3E0x030x1E0x300x1F0x0C0x00},   // U+0024 ($)
    { 0x000x630x330x180x0C0x660x630x00},   // U+0025 (%)
    { 0x1C0x360x1C0x6E0x3B0x330x6E0x00},   // U+0026 (&)
    { 0x060x060x030x000x000x000x000x00},   // U+0027 (')
    { 0x180x0C0x060x060x060x0C0x180x00},   // U+0028 (()
    { 0x060x0C0x180x180x180x0C0x060x00},   // U+0029 ())
    { 0x000x660x3C0xFF0x3C0x660x000x00},   // U+002A (*)
    { 0x000x0C0x0C0x3F0x0C0x0C0x000x00},   // U+002B (+)
    { 0x000x000x000x000x000x0C0x0C0x06},   // U+002C (,)
    { 0x000x000x000x3F0x000x000x000x00},   // U+002D (-)
    { 0x000x000x000x000x000x0C0x0C0x00},   // U+002E (.)
    { 0x600x300x180x0C0x060x030x010x00},   // U+002F (/)
    { 0x3E0x630x730x7B0x6F0x670x3E0x00},   // U+0030 (0)
    { 0x0C0x0E0x0C0x0C0x0C0x0C0x3F0x00},   // U+0031 (1)
    { 0x1E0x330x300x1C0x060x330x3F0x00},   // U+0032 (2)
    { 0x1E0x330x300x1C0x300x330x1E0x00},   // U+0033 (3)
    { 0x380x3C0x360x330x7F0x300x780x00},   // U+0034 (4)
    { 0x3F0x030x1F0x300x300x330x1E0x00},   // U+0035 (5)
    { 0x1C0x060x030x1F0x330x330x1E0x00},   // U+0036 (6)
    { 0x3F0x330x300x180x0C0x0C0x0C0x00},   // U+0037 (7)
    { 0x1E0x330x330x1E0x330x330x1E0x00},   // U+0038 (8)
    { 0x1E0x330x330x3E0x300x180x0E0x00},   // U+0039 (9)
    { 0x000x0C0x0C0x000x000x0C0x0C0x00},   // U+003A (:)
    { 0x000x0C0x0C0x000x000x0C0x0C0x06},   // U+003B (;)
    { 0x180x0C0x060x030x060x0C0x180x00},   // U+003C (<)
    { 0x000x000x3F0x000x000x3F0x000x00},   // U+003D (=)
    { 0x060x0C0x180x300x180x0C0x060x00},   // U+003E (>)
    { 0x1E0x330x300x180x0C0x000x0C0x00},   // U+003F (?)
    { 0x3E0x630x7B0x7B0x7B0x030x1E0x00},   // U+0040 (@)
    { 0x0C0x1E0x330x330x3F0x330x330x00},   // U+0041 (A)
    { 0x3F0x660x660x3E0x660x660x3F0x00},   // U+0042 (B)
    { 0x3C0x660x030x030x030x660x3C0x00},   // U+0043 (C)
    { 0x1F0x360x660x660x660x360x1F0x00},   // U+0044 (D)
    { 0x7F0x460x160x1E0x160x460x7F0x00},   // U+0045 (E)
    { 0x7F0x460x160x1E0x160x060x0F0x00},   // U+0046 (F)
    { 0x3C0x660x030x030x730x660x7C0x00},   // U+0047 (G)
    { 0x330x330x330x3F0x330x330x330x00},   // U+0048 (H)
    { 0x1E0x0C0x0C0x0C0x0C0x0C0x1E0x00},   // U+0049 (I)
    { 0x780x300x300x300x330x330x1E0x00},   // U+004A (J)
    { 0x670x660x360x1E0x360x660x670x00},   // U+004B (K)
    { 0x0F0x060x060x060x460x660x7F0x00},   // U+004C (L)
    { 0x630x770x7F0x7F0x6B0x630x630x00},   // U+004D (M)
    { 0x630x670x6F0x7B0x730x630x630x00},   // U+004E (N)
    { 0x1C0x360x630x630x630x360x1C0x00},   // U+004F (O)
    { 0x3F0x660x660x3E0x060x060x0F0x00},   // U+0050 (P)
    { 0x1E0x330x330x330x3B0x1E0x380x00},   // U+0051 (Q)
    { 0x3F0x660x660x3E0x360x660x670x00},   // U+0052 (R)
    { 0x1E0x330x070x0E0x380x330x1E0x00},   // U+0053 (S)
    { 0x3F0x2D0x0C0x0C0x0C0x0C0x1E0x00},   // U+0054 (T)
    { 0x330x330x330x330x330x330x3F0x00},   // U+0055 (U)
    { 0x330x330x330x330x330x1E0x0C0x00},   // U+0056 (V)
    { 0x630x630x630x6B0x7F0x770x630x00},   // U+0057 (W)
    { 0x630x630x360x1C0x1C0x360x630x00},   // U+0058 (X)
    { 0x330x330x330x1E0x0C0x0C0x1E0x00},   // U+0059 (Y)
    { 0x7F0x630x310x180x4C0x660x7F0x00},   // U+005A (Z)
    { 0x1E0x060x060x060x060x060x1E0x00},   // U+005B ([)
    { 0x030x060x0C0x180x300x600x400x00},   // U+005C (\)
    { 0x1E0x180x180x180x180x180x1E0x00},   // U+005D (])
    { 0x080x1C0x360x630x000x000x000x00},   // U+005E (^)
    { 0x000x000x000x000x000x000x000xFF},   // U+005F (_)
    { 0x0C0x0C0x180x000x000x000x000x00},   // U+0060 (`)
    { 0x000x000x1E0x300x3E0x330x6E0x00},   // U+0061 (a)
    { 0x070x060x060x3E0x660x660x3B0x00},   // U+0062 (b)
    { 0x000x000x1E0x330x030x330x1E0x00},   // U+0063 (c)
    { 0x380x300x300x3e0x330x330x6E0x00},   // U+0064 (d)
    { 0x000x000x1E0x330x3f0x030x1E0x00},   // U+0065 (e)
    { 0x1C0x360x060x0f0x060x060x0F0x00},   // U+0066 (f)
    { 0x000x000x6E0x330x330x3E0x300x1F},   // U+0067 (g)
    { 0x070x060x360x6E0x660x660x670x00},   // U+0068 (h)
    { 0x0C0x000x0E0x0C0x0C0x0C0x1E0x00},   // U+0069 (i)
    { 0x300x000x300x300x300x330x330x1E},   // U+006A (j)
    { 0x070x060x660x360x1E0x360x670x00},   // U+006B (k)
    { 0x0E0x0C0x0C0x0C0x0C0x0C0x1E0x00},   // U+006C (l)
    { 0x000x000x330x7F0x7F0x6B0x630x00},   // U+006D (m)
    { 0x000x000x1F0x330x330x330x330x00},   // U+006E (n)
    { 0x000x000x1E0x330x330x330x1E0x00},   // U+006F (o)
    { 0x000x000x3B0x660x660x3E0x060x0F},   // U+0070 (p)
    { 0x000x000x6E0x330x330x3E0x300x78},   // U+0071 (q)
    { 0x000x000x3B0x6E0x660x060x0F0x00},   // U+0072 (r)
    { 0x000x000x3E0x030x1E0x300x1F0x00},   // U+0073 (s)
    { 0x080x0C0x3E0x0C0x0C0x2C0x180x00},   // U+0074 (t)
    { 0x000x000x330x330x330x330x6E0x00},   // U+0075 (u)
    { 0x000x000x330x330x330x1E0x0C0x00},   // U+0076 (v)
    { 0x000x000x630x6B0x7F0x7F0x360x00},   // U+0077 (w)
    { 0x000x000x630x360x1C0x360x630x00},   // U+0078 (x)
    { 0x000x000x330x330x330x3E0x300x1F},   // U+0079 (y)
    { 0x000x000x3F0x190x0C0x260x3F0x00},   // U+007A (z)
    { 0x380x0C0x0C0x070x0C0x0C0x380x00},   // U+007B ({)
    { 0x180x180x180x000x180x180x180x00},   // U+007C (|)
    { 0x070x0C0x0C0x380x0C0x0C0x070x00},   // U+007D (})
    { 0x6E0x3B0x000x000x000x000x000x00},   // U+007E (~)
    { 0x000x000x000x000x000x000x000x00}    // U+007F
};
 
//volatile unsigned char dot1[128][8];
char cnt=0;
 
void dotPrint(char chr[8]){
  int j=0;
 
  for(int i=0;i<8;i++){
    digitalWrite(EN,LOW);
    /*
    SPI.transfer(~font8x8_basic[cnt+32][i]);
    SPI.transfer(~font8x8_basic['C'][i]);
    SPI.transfer(~font8x8_basic['B'][i]);
    SPI.transfer(~font8x8_basic['A'][i]);
    */

 
 
    //SPI.transfer(~font8x8_basic[chr][i]);
    for(int k=7;k>=0;k--)
      SPI.transfer(~font8x8_basic[chr[k]][i]);
 
    digitalWrite(EN,HIGH);
    digitalWrite(A3,HIGH);
    digitalWrite(A0,j&0x01);
    digitalWrite(A1,j&0x02);
    digitalWrite(A2,j&0x04);
    j++; 
    delay(3);
  }
}
 
void dotStr(unsigned char *str){
  while(*str) dotPrint(*str++);
}
 
void timeCount(void){
cnt++;
if(cnt>=90) cnt=0;
}
 
void setup()
 { // put your setup code here, to run once:
   SPI.begin();
   //SPI.beginTransaction(SPISettings(14000000, LSBFIRST, SPI_MODE0));
   pinMode(EN,OUTPUT);
   pinMode(A0,OUTPUT);
   pinMode(A1,OUTPUT);
   pinMode(A2,OUTPUT);
   pinMode(A3,OUTPUT);
   Timer1.initialize(500000);
  Timer1.attachInterrupt(timeCount);
 
 }
 
void loop()
 { // put your main code here, to run repeatedly:
/*
  int j=0;
  for(int i=0;i<8;i++){
    digitalWrite(EN,LOW);
    SPI.transfer(~font8x8_basic[cnt+32][i]);
SPI.transfer(~font8x8_basic['C'][i]);
SPI.transfer(~font8x8_basic['B'][i]);
SPI.transfer(~font8x8_basic['A'][i]);
digitalWrite(EN,HIGH);
    digitalWrite(A3,HIGH);
        digitalWrite(A0,j&0x01);
    digitalWrite(A1,j&0x02);
        digitalWrite(A2,j&0x04);
         j++; 
        delay(3);      
  }
*/

  dotPrint("ABCD");
  //dotStr("1234");
 }

 

Click here to download Arduino sketch.