c - Best practices for HD44780 instruction calls -
i'm first time poster, long time forum searcher... taking look.
my current embedded project uses 16x2 lcd controlled hd44780 standard controller. pic18 speaks lcd via adafruit lcd serial backpack (schematic link). chose spi interface.
the hd44780 controlled through various instruction writes 8 data pins (db0-7), read/write pin (r/w), register select pin (rs), , enable pin (e). link instruction set.
the instructions composed of bits indicate settings... configuration parameters lack of better term.
everything working expected, however, question relates best practices. in order best organize code readability , flexibility have tried follow following approach:
- assign each hd44780 configuration parameter via #define directive in header file
- build array of char type each instruction , load appropriate configuration parameters
execute instructions passing instruction array via pointer , using shift operations construct spi output in order expected serial backpack
this , good, however, have nagging feeling storing instructions arrays not best approach. appreciate advice on how approach issue bent towards clarity , efficiency.
my header , .c files below, main.c not included calls lcd_send via instruction aliases.
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 */ // guard condition contents of file not included // more once. #ifndef lcd_spi_16x2_v2_h #define lcd_spi_16x2_v2_h #include <xc.h> // include processor files - each processor file 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 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 not blink #define _sc 0 // 1-> shift display 0-> shift cursor #define _rl 0 // 1-> shift left 0-> shift 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
/* * 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 upper 4bits of command upper |= (*(cmd+4))<<6; upper |= (*(cmd+3))<<5; upper |= (*(cmd+2))<<4; upper |= _bl; //set light bit lower |= (*(cmd))<<2; //set rs bit lower |= (*(cmd+1))<<1; //set rw bit lower |= (*(cmd+9))<<7; //set data bits lower 4bits of command lower |= (*(cmd+8))<<6; lower |= (*(cmd+7))<<5; lower |= (*(cmd+6))<<4; lower |= _bl; //set 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 e pin high __delay_ms(2); _cs = 1; //clock data out of lcd backpack shift register __delay_ms(2); //delay hd44780 process _cs = 0; //chip select = 0 ssp1buf = data; //send out data e pin low set hd44780 __delay_ms(2); _cs = 1; //clock data out of lcd backpack shift register __delay_ms(2); }
Comments
Post a Comment