HD44780指令调用的最佳做法

时间:2017-04-07 14:57:38

标签: c spi lcd xc8 hd44780

我是第一次海报,长时间的论坛搜索者...感谢您一起来看看。

我目前的嵌入式项目使用由HD44780标准控制器控制的16x2 LCD。我的PIC18通过Adafruit LCD系列背包(schematic link)与液晶显示屏通话。我选择了SPI接口。

HD44780通过对8个数据引脚(DB0-7),读/写引脚(R / W),寄存器选择引脚(RS)和使能引脚(E)的各种指令写操作进行控制。 Link to the instruction set

指令由指示某些设置的位组成......配置参数缺少更好的术语。

一切都按预期工作,但是,我的问题与最佳实践有关。为了最好地组织我的代码以提高可读性和灵活性,我尝试遵循以下方法:

  1. 通过头文件
  2. 中的#define指令分配每个HD44780配置参数
  3. 为每条指令构建一个char类型数组,并使用适当的配置参数
  4. 加载它
  5. 通过指针传递指令数组并使用移位操作以串行背包所需的顺序构造SPI输出来执行指令

    这一切都很好,然而,我有一种唠叨的感觉,将指令存储为数组并不是最好的方法。对于如何以明确和高效的方式解决这个问题,我将不胜感激。

  6. 我的标题和.c文件在下面,不包括main.c但是通过指令别名调用LCD_send。

    HEADER FILE

    /* 
     * File:   LCD_SPI_16x2.h
     * Author: rbs
     * Comments:
     * Revision history: 
     */
    
    /*Hardware configuration:
     *
     *  Adafruit LCD serial backpack bit configuration:
     *  [DB4 | DB5 | DB6 | DB7 | E | RS | RW | LITE]
     *
     *  HD44780 instruction set bit configuration (4-bit mode):
     *  [RS | RW | DB7 | DB6 | DB5 | DB4]
     * 
     *  HD44780 instruction set bit configuration (8-bit mode):
     *  [RS | RW | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0]
     * 
     *  PIC18 MSSP1 SPI peripheral:
     *  LSB first, clock = FOSC/4, SCK idle = low, TX on SCK low -> high, SDI not used
     */
    
    // This is a guard condition so that contents of this file are not included
    // more than once.  
    #ifndef LCD_SPI_16X2_V2_H
    #define LCD_SPI_16X2_V2_H
    
    #include <xc.h> // include processor files - each processor file is guarded. 
    
    //function prototypes
    //void LCD_init(void);
    void LCD_send(char *cmd);
    void LCD_spi_out(char data);
    //void LCD_send_string(const char * str);
    //void LCD_set_cursr(int row, int col);
    
    #define _E 0x08         //alias for HD44780 ENABLE bit
    
    //HD44780 LCD parameters
    #define _BL  1          //1-> backlight on       0-> backlight off
    
    #define _ID  1          // 1-> increment         0-> decrement
    #define _S   0          // 1-> display shift     0-> no shift
    #define _D   0          // 1-> display on        0-> display off
    #define _C   0          // 1-> cursor on         0-> cursor off
    #define _B   0          // 1-> cursor blinks     0-> cursor does not blink
    #define _SC  0          // 1-> shift display     0-> shift cursor
    #define _RL  0          // 1-> shift to the left 0-> shift to the right
    #define _N   1          // 1-> 2 lines           0-> 1 line
    #define _F   0          // 1-> 5x10 dot font     0-> 5x8 dot font
    #define _DL8 1          // 8-bit mode        
    #define _DL4 0          // 4-bit mode
    
    //HD44780 LCD instruction aliases
    #define _Clear         LCD_send(Clear_display)
    #define _Home          LCD_send(Home)
    #define _Entry_mode    LCD_send(Entry_mode)
    #define _Display_onOff LCD_send(Display_onOff))
    #define _Cursor_shift  LCD_send(Cursor_shift)
    #define _Function8     LCD_send(Function_set_8bit)
    #define _Function4     LCD_send(Function_set_4bit)
    
    //HD44780 LCD instruction set, see format note above
    char Clear_display[10]      = {0,0,0,0,0,0,0,0,0,1};
    char Home[10]               = {0,0,0,0,0,0,0,0,1,0};
    char Entry_mode[10]         = {0,0,0,0,0,0,0,1,_ID,_S};
    char Display_onOff[10]      = {0,0,0,0,0,0,1,_D,_C,_B};
    char Cursor_shift[10]       = {0,0,0,0,0,1,_SC,_RL,0,0};
    char Function_set_8bit[10]  = {0,0,0,0,1,_DL8,_N,_F,0,0};
    char Function_set_4bit[10]  = {0,0,0,0,1,_DL4,_N,_F,0,0};
    char Cursor_pos[10]         = {0,0,1,0,0,0,0,0,0,0};
    
    #endif  /* LCD_SPI_16X2_V2_H */
    

    .C文件

    /*
     * File:   LCD_SPI_16x2.c
     * Author: rbs
     *
     * Created on April 4, 2017, 10:00 PM
     */
    
    
    #include <xc.h>
    #include "system_initialize.h"
    #include "LCD_SPI_16x2_v2.h"
    
    
    void LCD_init(){
        //not completed yet
    }
    
    void LCD_send(char *cmd){
     /* Adafruit LCD serial backpack bit configuration:
      *  UPPER:
      *  [DB4 | DB5 | DB6 | DB7 | E | RS | RW | LITE]
      *  LOWER:
      *  [DB0 | DB1 | DB2 | DB3 | E | RS | RW | LITE]
      *  HD44780 incoming instruction configuration:
      *  [RS | RW | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0]
      */
        char Upper = 0x00;
        char Lower = 0x00;
    
        Upper |= (*(cmd))<<2;      //set RS bit
        Upper |= (*(cmd+1))<<1;    //set RW bit
        Upper |= (*(cmd+5))<<7;    //set data bits for upper 4bits of command 
        Upper |= (*(cmd+4))<<6;
        Upper |= (*(cmd+3))<<5;
        Upper |= (*(cmd+2))<<4;
        Upper |= _BL;              //set back light bit
    
        Lower |= (*(cmd))<<2;      //set RS bit
        Lower |= (*(cmd+1))<<1;    //set RW bit
        Lower |= (*(cmd+9))<<7;    //set data bits for lower 4bits of command
        Lower |= (*(cmd+8))<<6;
        Lower |= (*(cmd+7))<<5;
        Lower |= (*(cmd+6))<<4;
        Lower |= _BL;              //set back light bit
    
        LCD_spi_out(Upper);
        LCD_spi_out(Lower);
    }
    
    void LCD_spi_out(char data){
        _CS = 0;                   //chip select = 0
        SSP1BUF = (data|_E);       //send out data with E pin high
        __delay_ms(2);
        _CS = 1;                   //clock data out of LCD backpack shift register
        __delay_ms(2);             //delay for HD44780 to process
    
         _CS = 0;                  //chip select = 0
        SSP1BUF = data;            //send out data with E pin low to set HD44780
        __delay_ms(2);
        _CS = 1;                   //clock data out of LCD backpack shift register
        __delay_ms(2);
    }
    

0 个答案:

没有答案