1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

interfacing 74595 with 2x16 LCD in 8 bit mode

Discussion in 'AVR' started by tony64, Mar 4, 2017.

  1. tony64

    tony64 New Member

    Joined:
    Mar 4, 2017
    Messages:
    14
    Likes:
    0
    I have made some code for this but nothing can be seen on lcd.
    my hardware is ok.can any one suggest a soluotion to this please.
     
  2. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,245
    Likes:
    911
    Location:
    Rochdale UK
    ONLINE
    Then it must be your software... Can you post both schematic and code?
     
  3. tony64

    tony64 New Member

    Joined:
    Mar 4, 2017
    Messages:
    14
    Likes:
    0
    The schematic I can not draw here but I can say that I used porta for control of lcd and the shift register.my micro is atmega32a. at 8 mhz .Hope you can help.
    This is my code:

    Code (c):

    #include <io.h>
    #include <delay.h>
    #include <mega32a.h>
    /***************************************

    Configure Connections

    ****************************************/


    #define HC595_PORT   PORTA
    #define HC595_DDR    DDRA

    #define HC595_DS_POS PORTA.4      //Data pin (DS) pin location

    #define HC595_SH_CP_POS PORTA.5      //Shift Clock (SH_CP) pin location
    #define HC595_ST_CP_POS PORTA.6      //Store Clock (ST_CP) pin location

    //#define LCD_DATA PORTA.4 // LCD data port
    #define en PORTA.2 // enable signal
    #define rw PORTA.1 // read/write signal
    #define rs PORTA.0 // register select signal


    /***************************************
    Configure Connections ***ENDS***
    ****************************************/


    //Initialize HC595 System

    void HC595Init()
    {
       //Make the Data(DS), Shift clock (SH_CP), Store Clock (ST_CP) lines output
       HC595_DDR|=((1<<HC595_SH_CP_POS)|(1<<HC595_ST_CP_POS)|(1<<HC595_DS_POS));
    }


    //Low level macros to change data (DS)lines
    #define HC595DataHigh() (HC595_PORT|=(1<<HC595_DS_POS))

    #define HC595DataLow() (HC595_PORT&=(~(1<<HC595_DS_POS)))

    //Sends a clock pulse on SH_CP line
    void HC595Pulse()
    {
       //Pulse the Shift Clock

       HC595_PORT|=(1<<HC595_SH_CP_POS);//HIGH
       delay_ms(20);
       HC595_PORT&=(~(1<<HC595_SH_CP_POS));//LOW

    }

    //Sends a clock pulse on ST_CP line
    void HC595Latch()
    {
       //Pulse the Store Clock

       HC595_PORT|=(1<<HC595_ST_CP_POS);//HIGH
       delay_ms(10);

       HC595_PORT&=(~(1<<HC595_ST_CP_POS));//LOW
       delay_ms(10);
    }


    /*

    Main High level function to write a single byte to
    Output shift register 74HC595.

    Arguments:
       single byte to write to the 74HC595 IC

    Returns:
       NONE

    Description:
       The byte is serially transfered to 74HC595
       and then latched. The byte is then available on
       output line Q0 to Q7 of the HC595 IC.

    */

    //unsigned int data ;
    void HC595Write(unsigned int data)
     {
       //Send each 8 bits serially
        int i=0;
       //Order is MSB first
       for(i=0;i<8;i++)
       {
          //Output the data on DS line according to the
          //Value of MSB
          if(data & 0b10000000)
          {
             //MSB is 1 so output high

             HC595DataHigh();
          }
          else
          {
             //MSB is 0 so output high
             HC595DataLow();
          }

          HC595Pulse();  //Pulse the Clock line
          delay_ms(10);
          data=data<<1;  //Now bring next bit at MSB position

       }

       //Now all 8 bits have been transferred to shift register
       //Move them to output latch at one
       HC595Latch();
     
      }

    /*

    Simple Delay function approx 0.5 seconds

    */


    void Wait()
    {
    int i=0;
       for(i=0;i<30;i++)
       {
          delay_ms(10);
       }
    }
      int i=0;
     // uint_t data;     //Initialize HC595 system
    void main()
    {
     DDRB=0xff;
     PORTB=0xff;
     DDRA=0xff;
     PORTA=0xff;

      for(i=0;i<=3;i++) //Startup Led
      {
      PORTB.4=~PORTB.4;
      delay_ms(200);
      }          
      PORTB.4=1;
     // PORTA.7=0;
      PORTA.1=0;
       HC595Init();
       HC595Write(0x38);   //Write the data to HC595
             Wait();                 //Wait

      rs=0;rw=0;en=1; // RS and RW as LOW and EN as HIGH
        delay_ms(10);
       rs=0;rw=0;en=0;
       delay_ms(20);
     

     

       while(1)
       {
          PORTA.7=1;  // back light on/off
        delay_ms(1000);
             rs=1;rw=0;en=1; // RS and RW as LOW and EN as HIGH
        delay_ms(10);
             HC595Write(0x0f) ; //Write the data to HC595
             Wait();                 //Wait
       
       rs=1;rw=0;en=0;
       delay_ms(20);
    //     rs=1;rw=0;en=1; // RS and RW as LOW and EN as HIGH
    //    delay_ms(1000);
    //         HC595Write(0x14) ;   //Write the data to HC595
    //         Wait();                 //Wait
    //  
    //   rs=1;rw=0;en=0;
    //   delay_ms(20);
    //    rs=1;rw=0;en=1; // RS and RW as LOW and EN as HIGH
    //    delay_ms(10);
    //         HC595Write(0xff) ;   //Write the data to HC595
    //         Wait();                 //Wait
    //  
    //   rs=1;rw=0;en=0;
    //   delay_ms(20);
         PORTA.7=0;
        delay_ms(1000);  
       
       }

    }
     
     
    Last edited by a moderator: Mar 4, 2017
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,245
    Likes:
    911
    Location:
    Rochdale UK
    ONLINE

    Your Init of the LCD is a bit sparce...

    You have to send 0x30 three times before sending the 0x38 function set...

    I wrote a library here.. http://www.electro-tech-online.com/...4hc595-for-codevisionavr.150119/#post-1287394

    If you look at the init section you can see what is needed..
     
  6. tony64

    tony64 New Member

    Joined:
    Mar 4, 2017
    Messages:
    14
    Likes:
    0
    Hi Sir,I repeated the command 3 times but still no effect.
    This is my schematic (sorry a bit messy).
     

    Attached Files:

  7. polprog

    polprog New Member

    Joined:
    Mar 7, 2017
    Messages:
    6
    Likes:
    0
    Are you sure you've set the contrast properly on that LCD? I don't see the setting parts on that schematic (given the pin labels I'm assuming it's the regular Hitachi HD44780).

    Also, why do you connect together 595's pin 13 with R/W on the LCD and pin 39 on the AVR? This may casue problems since there are no resistors there, and if 595's pin happens to be logic 0 and AVR's pin happens to be logic 1 it's gonna be a short-circuit.
     
    Last edited: Mar 7, 2017
  8. tony64

    tony64 New Member

    Joined:
    Mar 4, 2017
    Messages:
    14
    Likes:
    0
    Yes contrast is ok and its HD44780.
    The reason why pin 13 &39 is connected together is obvious :pin 13 is the enable of 595 which must be zero to be selected .pin 39 is also zero in this case all the time.
    So to my opinion if even pin 39 goes high , no problem !is it?
     
  9. polprog

    polprog New Member

    Joined:
    Mar 7, 2017
    Messages:
    6
    Likes:
    0
    I get it, but I think that if a pin (an input pin ofc) is suposed to be always zero it should be tied to ground - it would be more readable and less error-prone.

    Please post your current code, what exactly do you want to diplsay as a test and what data, byte by byte are you sending. I suppose you checked that 595 handling code by attaching some test leads or LEDs to the 595 output?
     
  10. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,245
    Likes:
    911
    Location:
    Rochdale UK
    ONLINE
    This is displaying the 16th user defined graphic... But you haven't defined a graphic..

    Try HC595Write('A') ; and see if something happens..
     
  11. tony64

    tony64 New Member

    Joined:
    Mar 4, 2017
    Messages:
    14
    Likes:
    0
    Well thak you for your time.this is a part of a larger pcb hardware which some time we have to disable the 595 and also some time need to Read data instead of writing to lcd.
    So that why we have not tied them to Grnd.
    Now the problem is a bit confusing to me much more to you and others.You see I have set up a circuit on table by soldering pieces together ie 595 ,lcd,and atmega32 and run them on 8bit mode with good result ,but when I turn to actual framework it just dos,nt work.no character or any thing at all is seen.why ?I don.t know!
     
  12. tony64

    tony64 New Member

    Joined:
    Mar 4, 2017
    Messages:
    14
    Likes:
    0
    As I said it works ok on the set up but not on the other side.
     
  13. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,245
    Likes:
    911
    Location:
    Rochdale UK
    ONLINE
    Explain!! Do you mean the commands work but not the data?... If so how do you know??

    The code you posted will not show anything even if the LCD somehow boots to 8 bit...

    There is another command in the set up that turns the display on/off , writing 0xC0 will turn it on..
     
  14. polprog

    polprog New Member

    Joined:
    Mar 7, 2017
    Messages:
    6
    Likes:
    0
    Can you post some photos of the setup or something else that could let us get the whole picture?
     
  15. tony64

    tony64 New Member

    Joined:
    Mar 4, 2017
    Messages:
    14
    Likes:
    0
    Both command and data work.The only (or so far only) bug is that it would not go to the second line (0xC0) and there are one unwanted space between the characters.
    See this film!(sorry film didn,t upload)
    and this is the code:

    void main()
    {
    DDRA=0xff; // making LCD_DATA port as output port
    DDRB=0xff; // making signal as out put
    DDRC=0xff;

    PORTB=0xff;
    PORTB.4=0; //buzer
    delay_ms(200);
    PORTB.4=1;
    PORTB.0=0; //v0 lcd
    PORTA.1=0;//w
    PORTA.7=0;//enable 595
    HC595Init();
    delay_ms(10);

    init_LCD(); // initialization of LCD

    delay_ms(100); // delay of 50 milli seconds

    while(1)
    {

    lcd_gotoxy(2,0);//this dose not work
    LCD_write('A');
    LCD_write('B');
    LCD_write('C');
    LCD_write('D');
    LCD_write('E');
    // LCD_cmd(0x18);
    LCD_write('F');
    LCD_write('G');
    LCD_write('H');
    LCD_write('I');
    LCD_write('J');
    LCD_write('K');
    LCD_write('L');
    LCD_write('M');
    // LCD_cmd(0x18);
    LCD_write('N');
    delay_ms(2000);
    LCD_cmd(0x01);
    LCD_cmd(0xc0);//this dose not work
    LCD_write('O');
    LCD_write('P');
    LCD_write('Q');
    LCD_write('R');
    LCD_write('S');
    LCD_write('T');
    LCD_write('U');
    // LCD_cmd(0x18);
    LCD_write('V');
    LCD_write('W');
    LCD_write('X');
    LCD_write('Y');
    LCD_write('Z');
    LCD_write(' ');
    delay_ms(2000);
    LCD_cmd(0x01); //clear the screen
    delay_ms(1000);

    }
    }
    void init_LCD(void)
    {

    LCD_cmd(0x38); // initialization of 16X2 LCD in 8bit mode
    delay_ms(1);

    LCD_cmd(0x01); // clear LCD
    delay_ms(1);

    LCD_cmd(0x0E); // cursor ON
    delay_ms(1);

    //LCD_cmd(0x80); // ---8 go to first line and --0 is for 0th position
    //delay_ms(10);
    return;
    }

    void LCD_cmd(unsigned char cmd)
    {

    LCD_DATA=cmd;
    HC595Write(cmd);
    rs=0;rw=0;en=1;//ctrl =(0<<rs)|(0<<rw)|(1<<en); // RS and RW as LOW and EN as HIGH
    delay_ms(1);
    rs=0;rw=0;en=0;//ctrl =(0<<rs)|(0<<rw)|(0<<en); // RS, RW , LOW and EN as LOW
    delay_ms(5);
    return;
    }

    void LCD_write(unsigned char data)
    {
    LCD_DATA= data;
    HC595Write(data);
    rs=1;rw=0;en=1;//ctrl = (1<<rs)|(0<<rw)|(1<<en); // RW as LOW and RS, EN as HIGH
    delay_ms(1);
    rs=1;rw=0;en=0;//ctrl = (1<<rs)|(0<<rw)|(0<<en); // EN and RW as LOW and RS HIGH
    delay_ms(5); // delay to get things executed
    return ;
    }
     
  16. polprog

    polprog New Member

    Joined:
    Mar 7, 2017
    Messages:
    6
    Likes:
    0
    Ok, a bit of theory (please correct me if im wrong here), the command 0xC0 does not clear the display.
    The proper byte is 0x0C which tells the display to do theese things: turn on the LCD, cursor off, cursor blink off. To send it, the following pins must have the following states:
    Code (text):
    RS=0
    RW=0
    D[7-0]=0x0C
    You are using the method called lcd_gotoxy(x,y) which we don't know the code for. I suppose it's sending proper bits. It doesn't work because the topmost line of the LCD is line 0 not 1!
    For that space between the characters, i can't understand the LCD_write method.
    This part (and some other parts):
    Code (text):
    rs=1;rw=0;en=1;//ctrl = (1<<rs)|(0<<rw)|(1<<en); // RW as LOW and RS, EN as HIGH
    would probably not compile because it sets some variables called rs, rw and en whch are not defined, and the proper AVR pin setting code is after the first "//"

    And, for the future, please put the code inside [CODE] the program goes here [/CODE] blocks - it's easier to read!
     
  17. tony64

    tony64 New Member

    Joined:
    Mar 4, 2017
    Messages:
    14
    Likes:
    0
    Thanks ,you are right 0xC0 dose not clean the lcd .So I used 0x0C ,you won,t believe it! it corrected the space between the characters.
    I did not send the complete code ,rs,rd,en have been defined on top.
    now the problem is going to the second line and printing the numbers,which now it won,t do.
     
  18. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,245
    Likes:
    911
    Location:
    Rochdale UK
    ONLINE
    The command is correct... In his LCDinit we have LCD_cmd(0x0E); which includes the display on...

    The code isn't complete and it appears that the first code posted and the second bear no resemblance whatsoever!!

    I have reproduced the code on a pic..... I hate the bit shift defines nearly always don't work.

    This works fine..

    Code (c):

    #include<xc.h>

    #define _XTAL_FREQ 4000000

    #pragma config FOSC = INTRCIO
    #pragma config MCLRE = OFF
    #pragma config WDTE = OFF

    #define HC595_PORT   GPIO
    #define HC595_DDR    TRISIO

    #define HC595_DS_POS GPIO2      //Data pin (DS) pin location

    #define HC595_SH_CP_POS GPIO1     //Shift Clock (SH_CP) pin location
    #define HC595_ST_CP_POS GPIO0      //Store Clock (ST_CP) pin location

    //#define LCD_DATA PORTA.4 // LCD data port
    #define E GPIO4 // enable signal
    #define RW GPIO3 // read/write signal
    #define RS GPIO5 // register select signal

    #define HC595DataHigh() HC595_DS_POS = 1
    #define HC595DataLow() HC595_DS_POS  =0

    void HC595Init()
       {
       //Make the Data(DS), Shift clock (SH_CP), Store Clock (ST_CP) lines output
       HC595_DDR|=0;
       }

    void HC595Pulse()
       {
       //Pulse the Shift Clock

       HC595_SH_CP_POS=1;//HIGH
       __delay_us(20);
        HC595_SH_CP_POS=0; //
       }

    void HC595Latch()
       {
       //Pulse the Store Clock

       HC595_ST_CP_POS = 1;//HIGH
       __delay_us(10);
       HC595_ST_CP_POS = 0;//LOW
       __delay_us(10);
    }

    void HC595Write(unsigned int data)
       {
       //Send each 8 bits serially
       int i=0;
       //Order is MSB first
       for(i=0;i<8;i++)
           {
           //Output the data on DS line according to the
           //Value of MSB
           if(data & 0b10000000)
               {
               //MSB is 1 so output high

               HC595DataHigh();
               }
           else
               {
               //MSB is 0 so output high
               HC595DataLow();          
               }
           HC595Pulse();  //Pulse the Clock line
           __delay_us(10);
           data=data<<1;  //Now bring next bit at MSB position
           }
       //Now all 8 bits have been transferred to shift register
       //Move them to output latch at one
       HC595Latch();
       }

    void LCDcmd(unsigned char cmd)
       {
       RS = 0;
       HC595Write(cmd);
       E = 1;
       __delay_us(100);
       E = 0;  
       }
       
    void LCDdata(unsigned char data)
       {
       RS = 1;
       HC595Write(data);
       E=1;
       __delay_us(100);
       E =0;  
       }
       
    void LCDinit(void)
       {
       TRISIO = 0;
       __delay_ms(15);
       HC595Write(0x33);
       RS = 0;
       E = 1;
       __delay_ms(5);
       E = 0;
       __delay_ms(5);
       E = 1;
       __delay_ms(5);
       E = 0;
       LCDcmd(0x38);
       __delay_ms(5);
       LCDcmd(0x38);
       LCDcmd(0xC);
       LCDcmd(0x6);
       LCDcmd(0x1);
       }
       
    void LCDprint(const char* str)
       {
       while(*str != 0)
           LCDdata(*str++);
       }

    void LCDgoto(char x, char y)
       {
       char addr = 0x80;
       if(y==2) addr = 0xC0;
       if(y==3) addr = 0x94;
       if(y==4) addr = 0xD4;
       addr+=x;
       LCDcmd(addr);
       }
       
    void main(void)
       {
       ANSEL = 0;
       LCDinit();
       __delay_ms(10);
       LCDprint("Hello World");
       LCDgoto(0,2);
       LCDprint("Serial LCD driver");

       while(1);  
       }
       

     
     
    • Like Like x 1
  19. tony64

    tony64 New Member

    Joined:
    Mar 4, 2017
    Messages:
    14
    Likes:
    0
    You are great Rogers,
    Thank you very much ,it works fine.I did a few changes in your code and omitted xc.h .and it works fine.Thanks again
     
  20. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,245
    Likes:
    911
    Location:
    Rochdale UK
    ONLINE
    You are very welcome...
     

Share This Page