//*************************************************************************** // File........: lcd_lib.c // // Author(s)...: Pashgan http://ChipEnable.Ru // // Target(s)...: ATMega... // // Compiler....: IAR EWAAVR 5.11a // // Description.: Драйвер знакосинтезирующего жк дисплея // // Data........: 28.10.09 // //*************************************************************************** #include "lcd_lib.h" //макросы для работы с битами #define ClearBit(reg, bit) reg &= (~(1<<(bit))) #define SetBit(reg, bit) reg |= (1<<(bit)) #define FLAG_BF 7 //макросы для задержек #define _delay_us(us) __delay_cycles((F_CPU / 1000000) * (us)); #define _delay_ms(ms) __delay_cycles((F_CPU / 1000) * (ms)); //общая функция #pragma inline = forced void LCD_CommonFunc(unsigned char data) { #ifdef BUS_4BIT unsigned char tmp; tmp = PORT_DATA & 0x0f; tmp |= (data & 0xf0); PORT_DATA = tmp; //вывод старшей тетрады SetBit(PORT_SIG, EN); _delay_us(2); ClearBit(PORT_SIG, EN); data = __swap_nibbles(data); tmp = PORT_DATA & 0x0f; tmp |= (data & 0xf0); PORT_DATA = tmp; //вывод младшей тетрады SetBit(PORT_SIG, EN); _delay_us(2); ClearBit(PORT_SIG, EN); #else PORT_DATA = data; //вывод данных на шину индикатора SetBit(PORT_SIG, EN); //установка E в 1 _delay_us(2); ClearBit(PORT_SIG, EN); //установка E в 0 - записывающий фронт #endif } //функция ожидания готовности lcd #pragma inline = forced void LCD_Wait(void) { #ifdef CHECK_FLAG_BF #ifdef BUS_4BIT unsigned char data; DDRX_DATA &= 0x0f; //конфигурируем порт на вход PORT_DATA |= 0xf0; //включаем pull-up резисторы SetBit(PORT_SIG, RW); //RW в 1 чтение из lcd ClearBit(PORT_SIG, RS); //RS в 0 команды do{ SetBit(PORT_SIG, EN); _delay_us(2); data = PIN_DATA & 0xf0; //чтение данных с порта ClearBit(PORT_SIG, EN); data = __swap_nibbles(data); SetBit(PORT_SIG, EN); _delay_us(2); data |= PIN_DATA & 0xf0; //чтение данных с порта ClearBit(PORT_SIG, EN); data = __swap_nibbles(data); }while((data & (1<<FLAG_BF))!= 0 ); ClearBit(PORT_SIG, RW); DDRX_DATA |= 0xf0; #else unsigned char data; DDRX_DATA = 0; //конфигурируем порт на вход PORT_DATA = 0xff; //включаем pull-up резисторы SetBit(PORT_SIG, RW); //RW в 1 чтение из lcd ClearBit(PORT_SIG, RS); //RS в 0 команды do{ SetBit(PORT_SIG, EN); _delay_us(2); data = PIN_DATA; //чтение данных с порта ClearBit(PORT_SIG, EN); }while((data & (1<<FLAG_BF))!= 0 ); ClearBit(PORT_SIG, RW); DDRX_DATA = 0xff; #endif #else _delay_us(40); #endif } //функция записи команды void LCD_WriteCom(unsigned char data) { LCD_Wait(); ClearBit(PORT_SIG, RS); //установка RS в 0 - команды LCD_CommonFunc(data); } //функция записи данных void LCD_WriteData(unsigned char data) { LCD_Wait(); SetBit(PORT_SIG, RS); //установка RS в 1 - данные LCD_CommonFunc(data); } //функция инициализации void LCD_Init(void) { #ifdef BUS_4BIT DDRX_DATA |= 0xf0; PORT_DATA |= 0xf0; DDRX_SIG |= (1<<RW)|(1<<RS)|(1<<EN); PORT_SIG |= (1<<RW)|(1<<RS)|(1<<EN); ClearBit(PORT_SIG, RW); _delay_ms(40); LCD_WriteCom(0x28); //4-ех разрядная шина, 2 строки #else DDRX_DATA |= 0xff; PORT_DATA |= 0xff; DDRX_SIG |= (1<<RW)|(1<<RS)|(1<<EN); PORT_SIG |= (1<<RW)|(1<<RS)|(1<<EN); ClearBit(PORT_SIG, RW); _delay_ms(40); LCD_WriteCom(0x38); //0b00111000 - 8 разрядная шина, 2 строки #endif LCD_WriteCom(0xf); //0b00001111 - дисплей, курсор, мерцание включены LCD_WriteCom(0x1); //0b00000001 - очистка дисплея _delay_ms(2); LCD_WriteCom(0x6); //0b00000110 - курсор движется вправо, сдвига нет } //функция вывода строки из флэш памяти void LCD_SendStringFlash(unsigned char __flash *str) { unsigned char data; while (*str) { data = *str++; LCD_WriteData(data); } } //функция вывда строки из ОЗУ void LCD_SendString(char *str) { unsigned char data; while (*str) { data = *str++; LCD_WriteData(data); } }