Welcome, Guest
Username: Password: Secret Key Remember me
  • Page:
  • 1
  • 2

TOPIC: Re: 74HC595-driven LCD Interface - 2 Pin 8 Bit Versions

Re: 74HC595-driven LCD Interface - 2 Pin 8 Bit Versions 4 years 3 months ago #16416

  • MMcLaren
  • MMcLaren's Avatar
  • Offline
  • Fresh Boarder
  • Posts: 12
  • Thanks received: 30
Hi guys,

Just wanted to share a couple 2-Pin 8-Bit LCD backpack variations. I'm interested in the 8-bit outputs because it opens up other possibilities, like driving 7-segment displays, or other devices, with the same interface. Either circuit uses the same LCD driver software;



I'm using an RC integrator to drive the 74HC595 SER pin (or 74HC164 AB pins) and I've chosen RC values with a time constant (τ) of 3.3 usecs which should work well all the way down to an Fosc of 4 MHz where the timing values would be most critical. The driver software uses an interval of 3τ (10-usecs) to charge or drain the capacitor on the SER pin to the correct level before clocking each bit into the shift register. This means it takes about 100 usecs to write a byte of data to the shift register and LCD.

Let's look at RC timing calculations for a host with Fosc = 4 MHz. At this speed each PIC instruction takes 1 microsecond. Data on the SER pin (blue) is shifted into the shift register on the rising edge of the signal on the SCK pin (pink) which is also the RC integrator input. Notice that while sending a '1' bit to the shift register, the RC output voltage (blue) on the SER pin will fall to about 3.5 volts when the SCK pin is driven low for one microsecond.



I modified an existing 3-Pin 8-Bit LCD backpack prototype with the new 2-Pin 8-Bit 74HC595 circuit and it came up first try (I love it when that happens).



I've included an 18F14K22 demo program listing below.

Cheerful regards, Mike
/******************************************************************
   *                                                                *
   *  Project: 18F14K22 2-Pin 8-Bit LCD Backpack Test               *
   *   Source: 18F14K22_2-Pin_8-Bit_LCD_Backpack_Test.c             *
   *   Author: Mike McLaren, K8LH                                   *
   *  (C)2013: Micro Application Consultants                        *
   *  Revised: 14-Jan-2013                                          *
   *                                                                *
   *  18F14K22 (16-MHz) demo for the K8LH 2-Pin 8-Bit Backpack      *
   *                                                                *
   *      IDE: MPLAB 8.84 (tabs = 4)                                *
   *     Lang: Sourceboost BoostC v7.05, Lite/Free version          *
   *                                                                *
   ******************************************************************/

   #include <system.h>

   #pragma DATA _CONFIG1H, _FOSC_IRC_1H & _PLLEN_OFF_1H & _FCMEN_OFF_1H & _IESO_OFF_1H 
   #pragma DATA _CONFIG2L, _PWRTEN_ON_2L & _BOREN_SBORDIS_2L & _BORV_22_2L
   #pragma DATA _CONFIG2H, _WDTEN_OFF_2H & _WDTPS_256_2H
   #pragma DATA _CONFIG3H, _HFOFST_OFF_3H & _MCLRE_ON_3H
   #pragma DATA _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L

  /*
   *  _FOSC_IRC_1H       Internal RC oscillator
   *  _PLLEN_OFF_1H      PLL is under software control
   *  _FCMEN_OFF_1H      Fail-Safe Clock Monitor disabled
   *  _IESO_OFF_1H       Oscillator Switchover mode disabled
   *  _PWRTEN_ON_2L      PWRT enabled (default)
   *  _BOREN_SBORDIS_2L  Brown-out Reset enabled in hardware
   *  _BORV_22_2L        VBOR set to 2.2 V nominal
   *  _WDTEN_OFF_2H      WDT controlled via WDTCON SWDTEN bit
   *  _WDTPS_256_2H      WDT prescaler 1:256
   *  _HFOFST_OFF_3H     Hold system clock until HFINTOSC stable
   *  _MCLRE_OFF_3H      RA3 input enabled, MCLR disabled
   *  _STVREN_ON_4L      reset on Stack full or underflow
   *  _LVP_OFF_4L        Single-Supply ICSP disabled
   *  _XINST_OFF_4L      extended instruction set disabled
   *  _DEBUG_OFF_4L      debugger off, RA0 + RA1 available
   */
   

   #pragma CLOCK_FREQ 16000000  // 16-MHz INTOSC

  /******************************************************************
   *  function prototypes                                           *
   ******************************************************************/
  /******************************************************************
   *  variables                                                     *
   ******************************************************************/

   char flags = 0;              // assorted flag bits

  /******************************************************************
   *  defines/constants                                             *
   ******************************************************************/

   #define line1 128+0          // lcd ddram address for line 1
   #define line2 128+64         // lcd ddram address for line 2

   #define clk  lata.1          // 595 'sck' & 'ser' + lcd 'rs'
   #define ena  lata.2          // 595 'rck' + lcd 'e' lines
   #define rs   flags.0         // lcd 'rs' flag bit

  /******************************************************************
   *  low level drivers & functions                                 *
   ******************************************************************/

  /*                                                                *
   *  K8LH 2-Pin 8-Bit 74HC595 LCD low level driver (isochronous)   *
   *                                                                */
   void PutLCD(char work)       // write byte to 74HC595 & LCD
   { char bitctr = 8;           //
     do                         // start of bit clock cycle
     { if(!work.7)              // if b7 is a '0' bit
         clk = 0;               // start clock cycle for a '0'
       delay_us(9);             // charge or drain cap to 3t
       clk = 0;                 // start clock cycle for a '1'
       clk = 1;                 // clock out the '0' or '1'
       work <<= 1;              // shift next bit into b7
     } while(--bitctr);         // until all 8 bits clocked out
     if(rs == 0) clk = 0;       // make clk pin = rs flag
     ena = 1; ena = 0;          // latch 595, pulse lcd 'e' pin
     clk = 1;                   // always leave clk pin high
   }

   void PutCMD(char pdata)      // lcd command (RS=0)
   { rs = 0; PutLCD(pdata);     // rs = 0, send command
   }                            //

   void PutDAT(char pdata)      // lcd data (RS=1)
   { rs = 1; PutLCD(pdata);     // rs = 1, send data
   }                            //

   void PutDAT(char *pdata)     // lcd data (RS=1) strings
   { while(*pdata)              //
       PutDAT(*pdata++);        //
   }                            //

  /*                                                                *
   *  initialize lcd (8-bit interface mode)                         *
   *                                                                */
   void lcdinit()               //
   { delay_ms(100);             //
     PutCMD(0x38);              // 8-bit, 2-lines, 5x7 font
     PutCMD(0x0C);              // display on, currsor & blink off
     PutCMD(0x06);              // cursor inc, shift off
     PutCMD(0x01);              // clear display
     delay_ms(2);               // required delay
   }                            //


  /******************************************************************
   *  main init                                                     *
   ******************************************************************/

   void main()                  //
   { 
     ansel = 0;                 //
     anselh = 0;                //
     osccon = 0b01110010;       // INTOSC = 16-MHz
     trisa = 0b00000000;        // porta all outputs
     trisb = 0b00000000;        // portb all outputs
     trisc = 0b00000000;        // portc all outputs
     porta = 1<<RA2;            // RA2 (clk) pin must be high
     portc = 0b00000000;        // preset lcd rc lines

     lcdinit();                 // init LCD in 4-bit interface mode
     PutDAT("DVM Project");     // 

  /******************************************************************
   *  main loop                                                     *
   ******************************************************************/

     while(1)                   //
     { 
       delay_ms(500);           // 500 msec update intervals
     }                          // loop forever
   }                            //
Last Edit: 10 months 2 weeks ago by MMcLaren.

Re: 74HC595-driven LCD Interface - 2 Pin 8 Bit Versions 4 years 2 months ago #12884

  • be80be
  • be80be's Avatar
  • Offline
  • Senior Boarder
  • Posts: 79
  • Thanks received: 90
Nice work Mike.

Re: 74HC595-driven LCD Interface - 2 Pin 8 Bit Versions 4 years 2 months ago #12918

  • lespic
  • lespic's Avatar
  • Offline
  • Junior Boarder
  • Posts: 36
  • Thanks received: 35
LCD modules go well on an MCP23008 , I2C expander (slave) I had the LCD working well on its own, but it could be expanded to include a LED BL control and 4 switches (or 8 switches and no BL) , it has the advantage of not only 2 wire but an interrupt for the switches. (There is also a 16 bit 28 pin version MCP23017)
Attachments:
The following user(s) said Thank You: Graham Mitchell, Jon Chandler

Re: 74HC595-driven LCD Interface - 2 Pin 8 Bit Versions 10 months 3 weeks ago #17760

  • MMcLaren
  • MMcLaren's Avatar
  • Offline
  • Fresh Boarder
  • Posts: 12
  • Thanks received: 30
I just started playing with an Arduino a few weeks ago and decided to port that PIC demo program to an Arduino sketch which works a treat.



/*********************************************************************
 *  Mike McLaren's 2-pin 8-bit 74HC595/74HC164 LCD Backpack Demo     *
 *                                                                   *
 *  Mike McLaren, 04-Jun-16    Arduino 1.6.9 / Arduino Nano          *
 *********************************************************************/

   #include <avr/io.h>

   #define clk PORTC2           // 'clk' on PC2 (A2) pin
   #define lat PORTC3           // 'lat' on PC3 (A3) pin

   #define line1 (0x80+0x00)
   #define line2 (0x80+0x40)
   #define line3 (0x80+0x14)
   #define line4 (0x80+0x54)

   bool rs = 0;                 // 'rs' flag
   
   #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~(1<<bit))  // clear bit
   #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= 1<<bit)     // set bit

  /*                                                                *
   *  K8LH 2-Pin 8-Bit 74HC595 LCD low level driver                 *
   *                                                                */
   void PutLCD(char work)       // write byte to 74HC595 & LCD
   { char bitctr = 8;           //
     do                         // start of bit clock cycle
     { if(!(work & 128))        // if b7 is a '0' bit
         cbi(PORTC,clk);        // start clock cycle for a '0'
       _delay_us(9);            // charge or drain cap to 3t
       cbi(PORTC,clk);          // start clock cycle for a '1'
       sbi(PORTC,clk);          // clock out the '0' or '1'
       work <<= 1;              // prep for next bit
     } while(--bitctr);         // until all 8 bits clocked out
     if(!rs) cbi(PORTC,clk);    // make clk pin = rs flag
     sbi(PORTC,lat);            // latch 595, pulse LCD 'E' pin
     cbi(PORTC,lat);            //  "
     sbi(PORTC,clk);            // always leave clk pin high
   }

   void PutCMD(char pdata)      // lcd command (RS=0)
   { rs = 0; PutLCD(pdata);     // rs = 0, send command
   }                            //

   void PutDAT(char pdata)      // lcd data (RS=1)
   { rs = 1; PutLCD(pdata);     // rs = 1, send data
   }                            //

   void PutDAT(char *pdata)     // lcd data (RS=1) strings
   { rs = 1; while(*pdata)      //
       PutLCD(*pdata++);        //
   }                            //

  /*                                                                *
   *  overload function for FlashStringHelper string constants      *
   *                                                                */
   void PutDAT(const __FlashStringHelper *ifsh)
   { rs = 1; PGM_P p = reinterpret_cast<PGM_P>(ifsh);
     while(unsigned char c = pgm_read_byte(p++)) PutLCD(c);
   }

  /*                                                                *
   *  initialize lcd (8-bit interface mode)                         *
   *                                                                */
   void InitLCD()               //
   { _delay_ms(100);            //
     PutCMD(0x38);              // 8-bit, 2-lines, 5x7 font
     PutCMD(0x0C);              // display on, currsor & blink off
     PutCMD(0x06);              // cursor inc, shift off
     PutCMD(0x01);              // clear display
     _delay_ms(2);              // required delay
   }                            //


  /******************************************************************
   *  main                                                          *
   ******************************************************************/

   int main()                   //
   { DDRC = 1<<clk|1<<lat;      // make 'clk' and 'lat' outputs
     cbi(PORTC,lat);            // lat = 0
     sbi(PORTC,clk);            // clk = 1 
     InitLCD();                 // 8-bit mode, cursor inc & off
     PutDAT(F("K8LH Backpack"));

     while(1)                   //
     {                          // 
     }                          // loop forever
   }                            //
Last Edit: 10 months 2 weeks ago by MMcLaren.
The following user(s) said Thank You: hop

Re: 74HC595-driven LCD Interface - 2 Pin 8 Bit Versions 10 months 2 weeks ago #17763

  • hop
  • hop's Avatar
  • Online
  • Platinum Boarder
  • Posts: 364
  • Thanks received: 45
MMcLaren wrote:
I just started playing with an Arduino a few weeks ago and decided to port that PIC demo program to an Arduino sketch which works a treat.

It's about time! :)

Re: 74HC595-driven LCD Interface - 2 Pin 8 Bit Versions 10 months 2 weeks ago #17766

  • MMcLaren
  • MMcLaren's Avatar
  • Offline
  • Fresh Boarder
  • Posts: 12
  • Thanks received: 30
Hi, hop.

The problem was I could never get any samples from Atmel. I finally took the plunge when I saw the prices dip below $2.00 for the Chinese Nano clones on AliExpress. I got the Nano pictured in my previous post for $1.75 (including shipping) along with that Screw Terminal Adapter Kit for 82 cents (including shipping).

I was also motivated and inspired after reading several articles on David Johnson-Davies' Technoblogy blog. He's an excellent technical writer and his work includes many innovative and insightful hardware and software solutions.

Cheerful regards, Mike
Last Edit: 10 months 2 weeks ago by MMcLaren.
  • Page:
  • 1
  • 2
Time to create page: 0.423 seconds