?? lcd.c.txt
字號:
00001 /*! \file lcd.c \brief Character LCD driver for HD44780/SED1278 displays. */
00002 //*****************************************************************************
00003 //
00004 // File Name : 'lcd.c'
00005 // Title : Character LCD driver for HD44780/SED1278 displays
00006 // (usable in mem-mapped, or I/O mode)
00007 // Author : Pascal Stang
00008 // Created : 11/22/2000
00009 // Revised : 4/30/2002
00010 // Version : 1.1
00011 // Target MCU : Atmel AVR series
00012 // Editor Tabs : 4
00013 //
00014 // This code is distributed under the GNU Public License
00015 // which can be found at http://www.gnu.org/licenses/gpl.txt
00016 //
00017 //*****************************************************************************
00018
00019 #include <avr/io.h>
00020 #include <avr/pgmspace.h>
00021
00022 #include "global.h"
00023 #include "timer.h"
00024
00025 #include "lcd.h"
00026
00027 // custom LCD characters
00028 unsigned char __attribute__ ((progmem)) LcdCustomChar[] =
00029 {
00030 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, // 0. 0/5 full progress block
00031 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, // 1. 1/5 full progress block
00032 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, // 2. 2/5 full progress block
00033 0x00, 0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x00, // 3. 3/5 full progress block
00034 0x00, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x00, // 4. 4/5 full progress block
00035 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 5. 5/5 full progress block
00036 0x03, 0x07, 0x0F, 0x1F, 0x0F, 0x07, 0x03, 0x00, // 6. rewind arrow
00037 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 7. stop block
00038 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, // 8. pause bars
00039 0x18, 0x1C, 0x1E, 0x1F, 0x1E, 0x1C, 0x18, 0x00, // 9. fast-forward arrow
00040 0x00, 0x04, 0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x00, // 10. scroll up arrow
00041 0x00, 0x1F, 0x1F, 0x0E, 0x0E, 0x04, 0x04, 0x00, // 11. scroll down arrow
00042 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 12. blank character
00043 0x00, 0x0E, 0x19, 0x15, 0x13, 0x0E, 0x00, 0x00, // 13. animated play icon frame 0
00044 0x00, 0x0E, 0x15, 0x15, 0x15, 0x0E, 0x00, 0x00, // 14. animated play icon frame 1
00045 0x00, 0x0E, 0x13, 0x15, 0x19, 0x0E, 0x00, 0x00, // 15. animated play icon frame 2
00046 0x00, 0x0E, 0x11, 0x1F, 0x11, 0x0E, 0x00, 0x00, // 16. animated play icon frame 3
00047 };
00048
00049 /*************************************************************/
00050 /********************** LOCAL FUNCTIONS **********************/
00051 /*************************************************************/
00052
00053 void lcdInitHW(void)
00054 {
00055 // initialize I/O ports
00056 // if I/O interface is in use
00057 #ifdef LCD_PORT_INTERFACE
00058 // initialize LCD control lines
00059 cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
00060 cbi(LCD_CTRL_PORT, LCD_CTRL_RW);
00061 cbi(LCD_CTRL_PORT, LCD_CTRL_E);
00062 // initialize LCD control lines to output
00063 sbi(LCD_CTRL_DDR, LCD_CTRL_RS);
00064 sbi(LCD_CTRL_DDR, LCD_CTRL_RW);
00065 sbi(LCD_CTRL_DDR, LCD_CTRL_E);
00066 // initialize LCD data port to input
00067 // initialize LCD data lines to pull-up
00068 #ifdef LCD_DATA_4BIT
00069 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
00070 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit)
00071 #else
00072 outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit)
00073 outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit)
00074 #endif
00075 #else
00076 // enable external memory bus if not already enabled
00077 sbi(MCUCR, SRE); // enable bus interface
00078 #endif
00079 }
00080
00081 void lcdBusyWait(void)
00082 {
00083 // wait until LCD busy bit goes to zero
00084 // do a read from control register
00085 #ifdef LCD_PORT_INTERFACE
00086 cbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "control"
00087 #ifdef LCD_DATA_4BIT
00088 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
00089 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit)
00090 #else
00091 outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit)
00092 outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit)
00093 #endif
00094 sbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read"
00095 sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00096 LCD_DELAY; // wait
00097 while(inb(LCD_DATA_PIN) & 1<<LCD_BUSY)
00098 {
00099 cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00100 LCD_DELAY; // wait
00101 LCD_DELAY; // wait
00102 sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00103 LCD_DELAY; // wait
00104 LCD_DELAY; // wait
00105 #ifdef LCD_DATA_4BIT // do an extra clock for 4 bit reads
00106 cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00107 LCD_DELAY; // wait
00108 LCD_DELAY; // wait
00109 sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00110 LCD_DELAY; // wait
00111 LCD_DELAY; // wait
00112 #endif
00113 }
00114 cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00115 // leave data lines in input mode so they can be most easily used for other purposes
00116 #else
00117 // memory bus read
00118 // sbi(MCUCR, SRW); // enable RAM waitstate
00119 // wait until LCD busy bit goes to zero
00120 while( (*((volatile unsigned char *) (LCD_CTRL_ADDR))) & (1<<LCD_BUSY) );
00121 // cbi(MCUCR, SRW); // disable RAM waitstate
00122 #endif
00123 }
00124
00125 void lcdControlWrite(u08 data)
00126 {
00127 // write the control byte to the display controller
00128 #ifdef LCD_PORT_INTERFACE
00129 lcdBusyWait(); // wait until LCD not busy
00130 cbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "control"
00131 cbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "write"
00132 #ifdef LCD_DATA_4BIT
00133 // 4 bit write
00134 sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00135 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0); // set data I/O lines to output (4bit)
00136 outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) ); // output data, high 4 bits
00137 LCD_DELAY; // wait
00138 LCD_DELAY; // wait
00139 cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00140 LCD_DELAY; // wait
00141 LCD_DELAY; // wait
00142 sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00143 outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) ); // output data, low 4 bits
00144 LCD_DELAY; // wait
00145 LCD_DELAY; // wait
00146 cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00147 #else
00148 // 8 bit write
00149 sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00150 outb(LCD_DATA_DDR, 0xFF); // set data I/O lines to output (8bit)
00151 outb(LCD_DATA_POUT, data); // output data, 8bits
00152 LCD_DELAY; // wait
00153 LCD_DELAY; // wait
00154 cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00155 #endif
00156 // leave data lines in input mode so they can be most easily used for other purposes
00157 #ifdef LCD_DATA_4BIT
00158 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
00159 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit)
00160 #else
00161 outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit)
00162 outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit)
00163 #endif
00164 #else
00165 // memory bus write
00166 //sbi(MCUCR, SRW); // enable RAM waitstate
00167 lcdBusyWait(); // wait until LCD not busy
00168 *((volatile unsigned char *) (LCD_CTRL_ADDR)) = data;
00169 //cbi(MCUCR, SRW); // disable RAM waitstate
00170 #endif
00171 }
00172
00173 u08 lcdControlRead(void)
00174 {
00175 // read the control byte from the display controller
00176 register u08 data;
00177 #ifdef LCD_PORT_INTERFACE
00178 lcdBusyWait(); // wait until LCD not busy
00179 #ifdef LCD_DATA_4BIT
00180 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
00181 outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0); // set pull-ups to on (4bit)
00182 #else
00183 outb(LCD_DATA_DDR, 0x00); // set data I/O lines to input (8bit)
00184 outb(LCD_DATA_POUT, 0xFF); // set pull-ups to on (8bit)
00185 #endif
00186 cbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "control"
00187 sbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read"
00188 #ifdef LCD_DATA_4BIT
00189 // 4 bit read
00190 sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00191 LCD_DELAY; // wait
00192 LCD_DELAY; // wait
00193 data = inb(LCD_DATA_PIN)&0xF0; // input data, high 4 bits
00194 cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00195 LCD_DELAY; // wait
00196 LCD_DELAY; // wait
00197 sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00198 LCD_DELAY; // wait
00199 LCD_DELAY; // wait
00200 data |= inb(LCD_DATA_PIN)>>4; // input data, low 4 bits
00201 cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00202 #else
00203 // 8 bit read
00204 sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00205 LCD_DELAY; // wait
00206 LCD_DELAY; // wait
00207 data = inb(LCD_DATA_PIN); // input data, 8bits
00208 cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00209 #endif
00210 // leave data lines in input mode so they can be most easily used for other purposes
00211 #else
00212 //sbi(MCUCR, SRW); // enable RAM waitstate
00213 lcdBusyWait(); // wait until LCD not busy
00214 data = *((volatile unsigned char *) (LCD_CTRL_ADDR));
00215 //cbi(MCUCR, SRW); // disable RAM waitstate
00216 #endif
00217 return data;
00218 }
00219
00220 void lcdDataWrite(u08 data)
00221 {
00222 // write a data byte to the display
00223 #ifdef LCD_PORT_INTERFACE
00224 lcdBusyWait(); // wait until LCD not busy
00225 sbi(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "data"
00226 cbi(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "write"
00227 #ifdef LCD_DATA_4BIT
00228 // 4 bit write
00229 sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
00230 outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0); // set data I/O lines to output (4bit)
00231 outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) ); // output data, high 4 bits
00232 LCD_DELAY; // wait
00233 LCD_DELAY; // wait
00234 cbi(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
00235 LCD_DELAY; // wait
00236 LCD_DELAY; // wait
00237 sbi(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -