|
下面给出了采用4-bit数据宽度带动LCD显示器的整套 (子)程序, (使用WINAVR编译):
/***********************************************************************
LCD.C
LCD routines that are base on 4-bit data bus operation. (implemented on AT90S2313, PORTB[3..0] connected LCD D7..D4)
***********************************************************************/ #include <string.h> #include <avr/pgmspace.h> #include <avr/io.h> #include <avr/ina90.h> #include "define.h" #include "lcd.h" #include "timer.h"
#define LCD_RS 5 // pin-5 on PORTD #define LCD_RW 3 // pin-3 on PORTD #define LCD_E 4 // pin-4 on PORTD
#define SET_LCD_E sbi (PORTD, LCD_E) // LCD: E = 1 #define CLR_LCD_E cbi (PORTD, LCD_E) // LCD: E = 0 #define SET_LCD_RW sbi (PORTD, LCD_RW) // LCD: R/W = 1 (read) #define CLR_LCD_RW cbi (PORTD, LCD_RW) // LCD: R/W = 0 (write) #define SET_LCD_RS sbi (PORTD, LCD_RS) // LCD: R/S = 1 (data reg) #define CLR_LCD_RS cbi (PORTD, LCD_RS) // LCD: R/S = 0 (status reg)
//////////////////////////////////////////////////////////////////////// u08 LCD_Clock (void) { u08 ret_code;
SET_LCD_E; _NOP (); _NOP (); // make a delay ret_code = PINB & 0x0f; // read bus[7:4] CLR_LCD_E;
return ret_code; }
//////////////////////////////////////////////////////////////////////// u08 LCD_BusyStat (void) { u08 n;
DDRB &= 0xf0; // PORTB[3:0] input
SET_LCD_RW; // R/W = 1 CLR_LCD_RS; // R/S = 0
n = LCD_Clock () & 0x08;// bit7..4 LCD_Clock (); // bit3..0
return n; }
//////////////////////////////////////////////////////////////////////// void LCD_WriteStat1 (u08 byte) { DDRB |= 0x0f; // PORTB[3:0] output
CLR_LCD_RW; // R/W = 0 CLR_LCD_RS; // R/S = 0
PORTB = byte & 0x0f; LCD_Clock (); }
//////////////////////////////////////////////////////////////////////// void LCD_WriteStat2 (u08 byte) { while ( LCD_BusyStat () );
LCD_WriteStat1 (byte >> 4); LCD_WriteStat1 (byte); }
//////////////////////////////////////////////////////////////////////// void LCD_WriteData1 (u08 byte) { PORTB = byte & 0x0f; // PORTB[3:0] = data DDRB = 0x0f; // PORTB[3:0] = output
CLR_LCD_RW; // R/W = 0 SET_LCD_RS; // R/S = 1
LCD_Clock (); }
//////////////////////////////////////////////////////////////////////// void LCD_WriteData2 (u08 byte) { while ( LCD_BusyStat () );
LCD_WriteData1 (byte >> 4); LCD_WriteData1 (byte); }
//////////////////////////////////////////////////////////////////////// void LCD_Init (void) { sbi (DDRD, LCD_E); // LCD E: output cbi (PORTD, LCD_E); // LCD E = 0 sbi (DDRB, LCD_RW); // LCD R/W (Read/Write) sbi (DDRB, LCD_RS); // LCD R/S (Reg/Status)
TMR0_DelayMs (100); LCD_WriteStat1 (0x3); // 4-bit data bus TMR0_DelayMs (10); LCD_WriteStat1 (0x3); TMR0_DelayMs (5); LCD_WriteStat1 (0x3);
while ( LCD_BusyStat () ); LCD_WriteStat1 (0x2);
LCD_WriteStat2 (0x28); // 2-line, 5x8 font LCD_WriteStat2 (0x0c); // LCD on, no cursor & blinking LCD_WriteStat2 (0x06); // }
//////////////////////////////////////////////////////////////////////// void LCD_SetPosition (u08 row, u08 col) { if ( row & 1 ) /* mark 2nd line bit */ col |= 0x40;
LCD_WriteStat2 (col | 0x80); }
//////////////////////////////////////////////////////////////////////// void LCD_DisplayStrROM (u08 row, u08 col, PGM_P str) { LCD_SetPosition (row, col);
for (;;) { u08 c = __LPM (str++);
if ( c == 0 ) return;
LCD_WriteData2 (c); } }
//////////////////////////////////////////////////////////////////////// void LCD_DisplayStr (u08 row, u08 col, char *str) { if ( (row < 2) && (col < 16) ) LCD_SetPosition (row, col);
for (;;) { u08 c = *str++;
if ( c == 0 ) return;
LCD_WriteData2 (c); } }
//////////////////////////////////////////////////////////////////////// void LCD_DisplayChar (u08 row, u08 col, char chr) { LCD_SetPosition (row, col); LCD_WriteData2 (chr); }
//////////////////////////////////////////////////////////////////////// void LCD_Clear (void) { LCD_WriteStat2 (0x01); }
//////////////////////////////////////////////////////////////////////// void LCD_SlideStrROM (u08 row, PGM_P str) { u08 i, j, col;
for (i = 16; i--;) { j = 0; LCD_SetPosition (row, i);
for (col = i; col < 16; col++) { u08 c = __LPM (&str[j]);
if ( c == 0 ) c = ' '; else j++;
LCD_PrintChar (c); }
if ( i ) TMR0_DelayMs (200); } }
|