C51-LCD1602

STC12C5A60S2调试LCD1602

国庆假期,闲来无事,突然想起我还有几片STC12C5A60S2 [datasheet],还有一片STC12L5A60S2 [datasheet],对了,还有两片STC15FWA60S2 [datashet],其实,根据STC系列单片机命名方法,STCC5A60S2和STC12L5A60S2是一样的,只是供电电压有所不同,“C5”代表供电电压是5V,“L5”代表供电电压是3.3v的。芯片最高频率和芯片引脚的速度也有所不同。还有几片LCD1602,想来很久之前,没能驱动成功,这次再次发起挑战。

  • LCD1602接口定义:

    1.RS——寄存器选择输入端

    • RS=1:指向数据寄存器
    • RS=0:指向指令寄存器

    2.RW——读写控制输入端

    • RW=1:读操作
    • RW=0:写操作

    3.E(EN)使能端

    • 读操作时,高电平有效
    • 写操作时,下降沿有效

    4.D0-D7:数据输入输出端

  • LCD1602操作时序图:

  • 底层函数

    1.使能函数(必须使能LCD1602才能执行命令)

    static void LCD_pulseEnable(void){    
        LCD_EN=0;
        Delay_us(10);
        LCD_EN=1;
        Delay_us(10);
        LCD_EN=0;
        Delay_us(10);
    //    LCD_EN=1;
    }

2.IO口操作函数

    static void LCD_write4bits(unsigned char value){
        DP=value&0xf0;
        LCD_pulseEnable();
    }
    static void LCD_write8bits(unsigned char value){
        DP=value&0xff;
        LCD_pulseEnable();
    }

3.数据输出函数

    static void LCD_send(unsigned char value, unsigned char mode){
        LCD_RW=1;
        Delay_us(10);
        LCD_RS=mode;
        LCD_RW=0;
        if(displayFunction&LCD_8BITMODE){
            LCD_write8bits(value);
        }else{
            LCD_write4bits((value));
            LCD_write4bits(value<<4);
        }
        LCD_RW=1;
        LCD_RS=(!mode);
    }

4.写命令

    void LCD_Command(unsigned char value){
        LCD_send(value, W_COMMAND);
    }

5.写数据

    char LCD_Write(unsigned char value){

        LCD_send(value, W_DATA);
        return 1;
    }
  • 硬件抽象层函数

    1.初始化函数

    • 初始化行数和列数
        void LCD_Begin(unsigned char cols, unsigned char lines){
          unsigned char dotsize=LCD_5x8DOTS;
            pinInit(0, 0, PIN_MODE_OP);
            portInit(1);
            portInit(2);
          if (lines > 1) {
            displayFunction |= LCD_2LINE;
          }
          numLines = lines;
            lcdCol=cols;
          LCD_SetRowOffsets(0x00, 0x40, 0x00 + cols, 0x40 + cols);  

          // for some 1 line displays you can select a 10 pixel high font
          if ((dotsize != LCD_5x8DOTS) && (lines == 1)) {
            displayFunction |= LCD_5x10DOTS;
          }
          // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
          // according to datasheet, we need at least 40ms after power rises above 2.7V
          // before sending commands. Arduino can turn on way before 4.5V so we'll wait 50
          Delay_ms(5); 
            LCD_RS=0;
            LCD_EN=0;
          LCD_RW=0;
          //put the LCD into 4 bit or 8 bit mode
          if (!(displayFunction & LCD_8BITMODE)){
            // this is according to the hitachi HD44780 datasheet
            // figure 24, pg 46
            // we start in 8bit mode, try to set 4 bit mode
            LCD_write4bits(0x03);
        //    delayMicroseconds(4500); // wait min 4.1ms
                Delay_us(4500);
            // second try
            LCD_write4bits(0x03);
        //    delayMicroseconds(4500); // wait min 4.1ms
            Delay_us(4500);
            // third go!
            LCD_write4bits(0x03); 
        //    delayMicroseconds(150);
                Delay_us(150);
            // finally, set to 4-bit interface
            LCD_write4bits(0x02); 
          }else{
            // this is according to the hitachi HD44780 datasheet
            // page 45 figure 23

            // Send function set command sequence
            LCD_Command(LCD_FUNCTIONSET | displayFunction);
        //    delayMicroseconds(4500);  // wait more than 4.1ms
                Delay_us(4500);
            // second try
            LCD_Command(LCD_FUNCTIONSET | displayFunction);
        //    delayMicroseconds(150);
                Delay_us(150);
            // third go
            LCD_Command(LCD_FUNCTIONSET | displayFunction);
          }

          // finally, set # lines, font size, etc.
          LCD_Command(LCD_FUNCTIONSET | displayFunction);  

          // turn the display on with no cursor or blinking default
          displayControl = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;  
          LCD_Display();

          // clear it off
          LCD_Clear();

          // Initialize to default text direction (for romance languages)
          displayMode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
          // set the entry mode
          LCD_Command(LCD_ENTRYMODESET | displayMode);
        }
  • 初始化数据线(四线制或八线制)
    void LCD_Init(unsigned char fourbitmode){
        if(fourbitmode)
            displayFunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
          else 
                displayFunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;

        LCD_Begin(16, 1);  
    }

2.在指定位置显示一个字节

    void LCD_DisplayChr(unsigned char col, unsigned char row, unsigned char value){

        LCD_SetCursor(col,row);
        LCD_Write(value);
    }

3.在指定位置显示字符串

    void LCD_DisplayStr(unsigned char col, unsigned char     row, unsigned char code* str){    
        unsigned char i=0;
        while(str[i]>=0x20){
            LCD_DisplayChr(col+i, row, str[i]);
            Delay_us(10);
            if(i>(lcdCol-col) && ((numLines-row)>=1)){
                LCD_DisplayChr((i-lcdCol+col-1), row+1, str[i]);
                Delay_us(10);
            }
            i++;
        }
    }
  • 测试

    main.c文件

    void main(void){
        unsigned char i,len=sizeof(t);

        P00=0;
        Delay_ms(1000);
        P00=1;
        LCD_Init(LINES_4);
        LCD_Begin(16, 2);
        LCD_Clear();
        LCD_SetCursor(0,0);
        LCD_DisplayChr(0, 0, 'A');
        Delay_ms(100);
        LCD_DisplayChr(1, 0, 'B');
            Delay_ms(100);
        LCD_DisplayChr(2, 0, 'C');
            Delay_ms(100);
        LCD_DisplayChr(3, 0, 'D');
            Delay_ms(100);
        LCD_DisplayChr(4, 0, 'E');
                Delay_ms(100);
        LCD_DisplayChr(0, 1, 'F');
                Delay_ms(100);
        LCD_DisplayChr(1, 1, 'G');
        LCD_DisplayStr(0, 1, t);                //通过
    //    LCD_DisplayStr(0, 1, "test,LCD!";        //通过
        while(1);
    }

ceshitu

源码文件

code.zip 源码文件

2018/10/6 22:17:54 2018/10/6 22:17:55


  转载请注明: XIAOSENLUO C51-LCD1602

 上一篇
电脑开启卓越性能 电脑开启卓越性能
win10系统(版本号在1803以上)开启性能模式win10升级到1803后,微软将电源管理现在的“性能模式”等同于原先的“平衡模式”,所以想要更好的发挥电脑性能,就要开启隐藏的卓越模式。 以“管理员身份”运行Windows shell。
2018-10-06
下一篇 
My First Blogs My First Blogs
一件有意义的事 这是我的第一篇博客,昨晚和林式说了之后,我问她,你猜我要写什么?她说,这是我的第一篇博客,应该记录一些有意义的事。其实我早已想好。 我之前在Aigirl看到一篇连载,《我想做能在你的葬礼上描述你一生的人》。有个评论:
2018-10-03 小森洛
  目录