这个例子演示了LGM12864 液晶屏的汉字显示效果,该液晶屏使用KS0108控制芯片。
Proteus运行截图:
Atmel Studio6.2编译通过截图:
程序清单:
LCD:
/*
* GccApplication29.c
*
* Created: 2014-12-7 10:45:58
* Author: Administrator
*/
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <stdint.h>
#define LCD_START_ROW 0xc0
#define LCD_PAGE 0xB8
#define LCD_COL 0x40
#define RW PD0
#define DI PD1
#define E PD2
#define CS1 PD3
#define CS2 PD4
#define RST PD5
#define LCD_PORT PORTC
#define LCD_DDR DDRC
#define LCD_PIN PINC
#define LCD_CTRL PORTD
#define RW_1() LCD_CTRL |= _BV(RW)
#define RW_0() LCD_CTRL &=~_BV(RW)
#define DI_1() LCD_CTRL |= _BV(DI)
#define DI_0() LCD_CTRL &=~_BV(DI)
#define E_1() LCD_CTRL |= _BV(E)
#define E_0() LCD_CTRL &=~_BV(E)
#define CS1_1() LCD_CTRL |= _BV(CS1)
#define CS1_0() LCD_CTRL &=~_BV(CS1)
#define CS2_1() LCD_CTRL |= _BV(CS2)
#define CS2_0() LCD_CTRL &=~_BV(CS2)
#define RST_1() LCD_CTRL|= _BV(RST)
#define RST_0() LCD_CTRL &=~_BV(RST)
uint8_t Reverse_Display = 0;
void Wait_LCD_Ready()
{
Check_Busy:
LCD_DDR = 0x00;
LCD_PORT = 0xFF;
RW_1();asm("nop");DI_0();
E_1();asm("nop"); E_0();
if(LCD_PIN&0x80)goto Check_Busy;
}
void LCD_Write_Command(uint8_t cmd)
{
Wait_LCD_Ready();
LCD_DDR = 0xFF;
LCD_PORT = 0xFF;
RW_0();asm("nop");DI_0();
LCD_PORT = cmd;
E_1();asm("nop");E_0();
}
void LCD_Write_Data(uint8_t dat)
{
Wait_LCD_Ready();
LCD_DDR = 0xFF;
LCD_PORT = 0xff;
RW_0();asm("nop");DI_1();
if(!Reverse_Display) LCD_PORT=dat;else LCD_PORT = ~dat;
E_1();asm("nop");E_0();
}
void LCD_Initialize()
{
LCD_Write_Command(0x3F);_delay_ms(15);
}
//从第P页L列开始显示W个字节数据,数据在r所指向的缓冲
void Common_Show(uint8_t P,uint8_t L,uint8_t W,uint8_t *r)
{
uint8_t i;
if(L<64)
{
CS1_1();CS2_0();
LCD_Write_Command(LCD_PAGE + P);
LCD_Write_Command(LCD_COL + L);
if(L + W < 64)
{
for(i=0;i<W;i++) LCD_Write_Data(r[i]);
}
else
{
for(i=0;i<64 - L;i++) LCD_Write_Data(r[i]);
CS1_0();CS2_1();
LCD_Write_Command(LCD_PAGE + P);
LCD_Write_Command(LCD_COL);
for(i=64 - L;i<W;i++)LCD_Write_Data(r[i]);
}
}
else
{
CS1_0();CS2_1();
LCD_Write_Command(LCD_PAGE + P);
LCD_Write_Command(LCD_COL + L - 64);
for(i=0;i<W;i++)LCD_Write_Data(r[i]);
}
}
void Display_A_Char_8X16(uint8_t P,uint8_t L,uint8_t *M)
{
Common_Show(P, L, 8, M);
Common_Show(P + 1,L,8,M+8);
}
void Display_A_WORD(uint8_t P,uint8_t L,uint8_t *M)
{
Common_Show(P,L,16,M);
Common_Show(P+1,L,16,M+16);
}
void Display_A_WORD_String(uint8_t P,uint8_t L,uint8_t C,uint8_t *M)
{
uint8_t i;
for(i=0;i<C;i++)
{
Display_A_WORD(P,L+i * 16,M + i *32);
}
}
main:
#define F_CPU 2000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
extern void LCD_Initialize();
extern void Display_A_WORD_String(uint8_t P,uint8_t L,uint8_t C,uint8_t *M);
extern uint8_t Reverse_Display;
const uint8_t WORD_Dot_Matrix[] =
{
0x10,0x61,0x06,0xE0,0x18,0x84,0xe4,0x1c,0x84,0x65,0xEE,0x24,0xa4,0x64,0x04,0x00,
0x04,0x04,0xFF,0x00,0x01,0x00,0xFF,0x41,0x21,0x12,0x0c,0x1B,0x61,0xC0,0x40,0x00,
0x00,0x00,0x00,0x00,0x7e,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x7E,0x00,0x00,0x00,0x00,
0x00,0x7f,0x25,0x25,0x25,0x25,0x7f,0x00,0x00,0x7f,0x25,0x25,0x25,0x25,0x7F,0x00,
0x00,0x00,0xff,0x09,0x49,0x59,0xe9,0x49,0x49,0x49,0xe9,0x59,0x49,0x4f,0x00,0x00,
0x40,0x30,0x0f,0x82,0x42,0x32,0x0f,0x02,0x02,0x02,0xff,0x02,0x02,0x02,0x02,0x00,
0x08,0x31,0x86,0x60,0x00,0xfe,0x02,0xf2,0x02,0xfe,0x00,0xf8,0x00,0x00,0xff,0x00,
0x04,0xfc,0x03,0x00,0x80,0x47,0x30,0x0f,0x10,0x67,0x00,0x07,0x40,0x80,0x7F,0x00,
0x40,0x42,0xdc,0x08,0x00,0x90,0x90,0x90,0x90,0x90,0xff,0x10,0x12,0x1c,0x10,0x00,
0x00,0x00,0x7f,0x20,0x10,0x20,0x20,0x1F,0x10,0x10,0x01,0x06,0x18,0x20,0x78,0x00,
0x10,0x12,0xd2,0xFE,0x91,0x11,0x80,0xbf,0xa1,0xa1,0xa1,0xa1,0xbf,0x80,0x00,0x00,
0x04,0x03,0x00,0xef,0x00,0x41,0x44,0x44,0x44,0x7f,0x44,0x44,0x44,0x44,0x40,0x00,
0x00,0x00,0xfc,0x04,0x04,0x14,0x14,0x35,0x56,0x94,0x54,0x34,0x14,0x04,0x04,0x00,
0x80,0x60,0x1f,0x00,0x01,0x01,0x01,0x41,0x81,0x7f,0x01,0x01,0x01,0x03,0x01,0x00
};
int main()
{
DDRD = 0xFF; PORTD = 0xFF;
LCD_Initialize();
Display_A_WORD_String(2,8,7,(uint8_t*)WORD_Dot_Matrix);
Reverse_Display = 1;
Display_A_WORD_String(5,8,7,(uint8_t*)WORD_Dot_Matrix);
while(1);
}
|