KS0108 128X64 LCD C语言AVR程序
扫描二维码
随时随地手机看文章
KS0108 128X64LCDC语言AVR程序
/*
LCD引脚定义
1---GND
2---VCC
3---VLCD
4---D/I
5---R/W
6---E
7到14D0-D7
15--CS1
16--CS2
17--RESET
18--VEE
19--SW
20--NC
*/
#include
#include
unsignedcharCurOffset,CurRow,CurPage,CurCol;
/*常量定义*/
#defineLCD_STATUS_BUSY0x80
#defineSTART_LINE00xc0
#defineDISPLAY_ON0x3f
#defineDISPLAY_OFF0x3e
#definePARA10x40
//PORTA---数据口PORTB----控制口
volatileunsignedchar*LCD_DIR_PORT=&DDRA;
volatileunsignedchar*LCD_IP_PORT=&PINA;
volatileunsignedchar*LCD_OP_PORT=&PORTA;
volatileunsignedchar*LCD_EN_PORT=&PORTB;
volatileunsignedchar*LCD_CS2_PORT=&PORTB;
volatileunsignedchar*LCD_CS1_PORT=&PORTB;
volatileunsignedchar*LCD_RW_PORT=&PORTB;
volatileunsignedchar*LCD_DI_PORT=&PORTB;
charLCD_EN_BIT=BIT(4);
charLCD_CS2_BIT=BIT(3);
charLCD_CS1_BIT=BIT(2);
charLCD_RW_BIT=BIT(1);
charLCD_DI_BIT=BIT(0);
#defineSET_LCD_E*LCD_EN_PORT|=LCD_EN_BIT//LCD使能
#defineCLEAR_LCD_E*LCD_EN_PORT&=~LCD_EN_BIT//LCD禁止
#defineSET_LCD_DATA*LCD_DI_PORT|=LCD_DI_BIT//选择指令端口
#defineSET_LCD_CMD*LCD_DI_PORT&=~LCD_DI_BIT//选择数据端口
#defineSET_LCD_READ*LCD_RW_PORT|=LCD_RW_BIT//读模式
#defineSET_LCD_WRITE*LCD_RW_PORT&=~LCD_RW_BIT//写模式
#defineSET_LCD_CS2*LCD_CS2_PORT|=LCD_CS2_BIT//左屏选择禁止
#defineCLEAR_LCD_CS2*LCD_CS2_PORT&=~LCD_CS2_BIT//左屏选择使能
#defineSET_LCD_CS1*LCD_CS1_PORT|=LCD_CS1_BIT//左屏选择禁止
#defineCLEAR_LCD_CS1*LCD_CS1_PORT&=~LCD_CS1_BIT//左屏选择使能
#defineLEFT0
#defineRIGHT1
#defineCMD0
#defineDATA1
voidLCD_BUSY(unsignedcharlr)//判断忙标志
{
unsignedcharstatus;
CLI();
if(lr==LEFT)
{
CLEAR_LCD_CS2;//cs2=0
SET_LCD_CS1;//cs1=1
}
else
{
SET_LCD_CS2;//cs2=1
CLEAR_LCD_CS1;//cs1=0
}
SET_LCD_CMD;
*LCD_DIR_PORT=0x00;
*LCD_OP_PORT=0xff;
SET_LCD_READ;
SET_LCD_E;
asm("nop");asm("nop");
asm("nop");asm("nop");
while((*LCD_IP_PORT)&LCD_STATUS_BUSY)
{
CLEAR_LCD_E;
asm("nop");asm("nop");
asm("nop");asm("nop");
SET_LCD_E;
asm("nop");asm("nop");
asm("nop");asm("nop");
}
CLEAR_LCD_E;
SET_LCD_WRITE;
*LCD_OP_PORT=0xff;
SEI();
}
voidwrite_LCD(unsignedcharlr,unsignedcharcd,unsignedchardata)/*写入指令或数据*/
{
CLI();
LCD_BUSY(lr);
if(cd==CMD)SET_LCD_CMD;
elseSET_LCD_DATA;
SET_LCD_WRITE;
SET_LCD_E;
*LCD_DIR_PORT=0xff;
*LCD_OP_PORT=data;
asm("nop");asm("nop");
asm("nop");asm("nop");
CLEAR_LCD_E;
*LCD_OP_PORT=0xff;
SEI();
}
unsignedcharread_LCD(unsignedcharlr)/*读显示数据*/
{
unsignedchardata;
CLI();
LCD_BUSY(lr);
SET_LCD_DATA;
*LCD_DIR_PORT=0x00;
*LCD_OP_PORT=0xff;
SET_LCD_READ;
SET_LCD_E;
asm("nop");asm("nop");
asm("nop");asm("nop");
data=*LCD_IP_PORT;
CLEAR_LCD_E;
SET_LCD_WRITE;
LCD_BUSY(lr);
SET_LCD_DATA;
*LCD_DIR_PORT=0x00;
*LCD_OP_PORT=0xff;
SET_LCD_READ;
SET_LCD_E;
asm("nop");asm("nop");
asm("nop");asm("nop");
data=*LCD_IP_PORT;
CLEAR_LCD_E;
SET_LCD_WRITE;
SEI();
returndata;
}
voidset_start_line_L(unsignedcharline)/*设置显示起始行*///0-63
{
write_LCD(LEFT,CMD,0xc0|line);
}
voidset_start_line_R(unsignedcharline)/*设置显示起始行*///0-63
{
write_LCD(RIGHT,CMD,0xc0|line);
}
voidset_page_L(unsignedcharpage)/*设置X地址设置页*///0-7
{
write_LCD(LEFT,CMD,0xb8|page);
}
voidset_page_R(unsignedcharpage)/*设置X地址设置页*///0-7
{
write_LCD(RIGHT,CMD,0xb8|page);
}
voidset_col_addr_L(unsignedcharcol)/*设置Y地址*///0-63
{
write_LCD(LEFT,CMD,0x40|col);
}
voidset_col_addr_R(unsignedcharcol)/*设置Y地址*///0-63
{
write_LCD(RIGHT,CMD,0x40|col);
}
voidinit_lcd(void)/*初始化函数*/
{
set_start_line_L(0);/*显示起始行为0*/
set_start_line_R(0);/*显示起始行为0*/
write_LCD(LEFT,CMD,DISPLAY_ON);/*开显示*/
write_LCD(RIGHT,CMD,DISPLAY_ON);/*开显示*/
}
voidclr_lcd(void)/*清屏函数*/
{
unsignedcharpages,i;
for(pages=0;pages<8;pages++)
{
set_page_L(pages);/*X页地址*/
set_page_R(pages);/*X页地址*/
for(i=0;i<64;i++)
{
set_col_addr_L(i);//Y
set_col_addr_R(i);//Y
write_LCD(LEFT,DATA,0x0);
write_LCD(RIGHT,DATA,0x0);
}
}
}
//ASCII字模宽度及高度
#defineASC_CHR_WIDTH8
#defineASC_CHR_HEIGHT12
typedefstructtypFNT_ASC16/*汉字字模显示数据结构*/
{
charIndex[1];
charMsk[16];
};
structtypFNT_ASC16constASC_16[]={/*显示为8*16Curier10常规*/
"1",0x00,0x00,0x08,0x08,0xFC,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x07,0x04,0x04,0x00,
"2",0x00,0x00,0x08,0x04,0x84,0x44,0x38,0x00,0x00,0x00,0x06,0x05,0x04,0x04,0x04,0x00,
"3",0x00,0x00,0x08,0x04,0x44,0x44,0xB8,0x00,0x00,0x00,0x02,0x04,0x04,0x04,0x03,0x00,
"4",0x00,0x00,0x80,0x60,0x18,0xFC,0x00,0x00,0x00,0x00,0x01,0x01,0x05,0x07,0x05,0x00,
"5",0x00,0x00,0x7C,0x44,0x44,0x44,0x84,0x00,0x00,0x00,0x02,0x04,0x04,0x04,0x03,0x00,
"6",0x00,0x00,0xF0,0x48,0x44,0x44,0x80,0x00,0x00,0x00,0x03,0x04,0x04,0x04,0x03,0x00,
"7",0x00,0x00,0x0C,0x04,0x84,0x64,0x1C,0x00,0x00,0x00,0x00,0x06,0x01,0x00,0x00,0x00,
"8",0x00,0x00,0xB8,0x44,0x44,0x44,0xB8,0x00,0x00,0x00,0x03,0x04,0x04,0x04,0x03,0x00,
"9",0x00,0x00,0x38,0x44,0x44,0x44,0xF8,0x00,0x00,0x00,0x00,0x04,0x04,0x02,0x01,0x00,
"0",0x00,0x00,0xF8,0x04,0x04,0x04,0xF8,0x00,0x00,0x00,0x03,0x04,0x04,0x04,0x03,0x00,
".",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
",",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x00,0x00,0x00,
":",0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
";",0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x00,0x00,0x00,
"-",0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
"_",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
"A",0x00,0x00,0x80,0x64,0x1C,0x60,0x80,0x00,0x00,0x04,0x07,0x05,0x01,0x05,0x07,0x04,
"B",0x00,0x04,0xFC,0x44,0x44,0x44,0x44,0xB8,0x00,0x04,0x07,0x04,0x04,0x04,0x04,0x03,
"C",0x00,0xF0,0x08,0x04,0x04,0x04,0x04,0x08,0x00,0x01,0x02,0x04,0x04,0x04,0x04,0x02,
"D",0x00,0x04,0xFC,0x04,0x04,0x04,0x08,0xF0,0x00,0x04,0x07,0x04,0x04,0x04,0x02,0x01,
"E",0x00,0x04,0xFC,0x44,0x44,0xE4,0x04,0x0C,0x00,0x04,0x07,0x04,0x04,0x04,0x04,0x06,
"F",0x00,0x04,0xFC,0x44,0x44,0xE4,0x04,0x0C,0x00,0x04,0x07,0x04,0x04,0x00,0x00,0x00,
"",0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
"=",0x00,0x00,0xA0,0xA0,0xA0,0xA0,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
"(",0x00,0x00,0x00,0xE0,0x18,0x04,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x10,0x00,0x00,
")",0x00,0x00,0x00,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x00,0x10,0x0C,0x03,0x00,0x00,
"V",0x00,0x04,0x3C,0xC4,0x00,0xC4,0x3C,0x04,0x00,0x00,0x00,0x01,0x06,0x01,0x00,0x00,
"m",0x00,0x20,0xE0,0x20,0xC0,0x20,0xC0,0x00,0x00,0x04,0x07,0x00,0x07,0x00,0x07,0x04,
"H",0x00,0x04,0xFC,0x44,0x40,0x44,0xFC,0x04,0x00,0x04,0x07,0x04,0x00,0x04,0x07,0x04,
"*",0x90,0x90,0x60,0xFC,0x60,0x90,0x90,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,
};
#defineASC_Hz_WIDTH12
//#defineASC_HZ_HEIGHT12
typedefstructtypFNT_GB16/*12*16汉字字模显示数据结构*/
{
charIndex[2];
charMsk[24];
};
structtypFNT_GB16constGB_16[]={/*宋体9显示为12*16*/
"科",0x8A,0x6A,0xFE,0x29,0x49,0x80,0x92,0xA4,0x80,0xFF,0x40,0x00,0x01,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,
"技",0x44,0x44,0xFF,0x24,0x00,0x64,0xA4,0x3F,0xA4,0x64,0x04,0x00,0x04,0x04,0x07,0x00,0x04,0x04,0x02,0x01,0x02,0x04,0x04,0x00,
"有",0x42,0x22,0x12,0xFA,0x4E,0x4B,0x4A,0x4A,0xFA,0x02,0x02,0x00,0x00,0x00,0x00,0x07,0x01,0x01,0x01,0x05,0x07,0x00,0x00,0x00,
"限",0xFF,0x81,0x99,0xE7,0x00,0xFF,0x25,0xE5,0x25,0xBF,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x07,0x04,0x02,0x01,0x02,0x04,0x00,
"公",0x20,0x10,0x08,0x07,0xC0,0x30,0x83,0x0C,0x10,0x20,0x20,0x00,0x00,0x04,0x06,0x05,0x04,0x04,0x02,0x03,0x06,0x00,0x00,0x00,
"司",0x08,0x09,0xE9,0x29,0x29,0x29,0xED,0x09,0x01,0xFF,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x04,0x04,0x07,0x00,0x00,
};
unsignedcharGetPage(void)/*得到当前页*/
{
returnCurPage;
}
unsignedcharGetCol(void)/*得到当前列*/
{
returnCurCol;
}
voidSetPageCol(unsignedcharupage,unsignedcharucol)/*设置液晶的页和列*/
{
CurPage=upage;
CurCol=ucol;
if(ucol<64)
{
set_page_L(upage);
set_col_addr_L(ucol);
}
else
{
set_page_R(upage);
set_col_addr_R(ucol-64);
}
}
/*设置当前显示的页和列*/
voidSetRowCol(unsignedcharurow,unsignedcharucol)
{
unsignedcharpage;
CurRow=urow;
CurCol=ucol;
switch(urow)
{
case1:
page=0;
CurOffset=1;
break;
case2:
page=1;
CurOffset=2;
break;
case3:
page=3;
CurOffset=1;
break;
case4:
page=4;
CurOffset=2;
break;
case5:
page=6;
CurOffset=1;
break;
}
SetPageCol(page,ucol);
}
voiddisp_ch(unsignedcharc)
{
unsignedchark,j,uPage,uCol,ch_r,ch_w;
unsignedcharwidth;
unsignedcharlen;
uPage=GetPage();
uCol=GetCol();
len=sizeof(ASC_16)/sizeof(ASC_16[0]);
for(k=0;k
if(c==ASC_16[k].Index[0])break;
}
if(k
if(c==’-’||c==’:’)
width=ASC_CHR_WIDTH-2;
elseif(c==’|’)
width=ASC_HZ_WIDTH-ASC_CHR_WIDTH;
else
width=ASC_CHR_WIDTH;
if(CurOffset==1)//下半部是写半个字节
{
for(j=0;j
SetPageCol(uPage,uCol+j);
ch_w=ASC_16[k].Msk[j];
if(uCol+j<64)write_LCD(LEFT,DATA,ch_w);
elsewrite_LCD(RIGHT,DATA,ch_w);
}
SetPageCol(uPage+1,uCol);
for(j=0;j
SetPageCol(uPage+1,uCol+j);
if(uCol+j<64)ch_r=read_LCD(LEFT);
elsech_r=read_LCD(RIGHT);
ch_r&=0xf0;
ch_w=ASC_16[k].Msk[ASC_CHR_WIDTH+j]&0x0f;
ch_w|=ch_r;
SetPageCol(uPage+1,uCol+j);
if(uCol+j<64)write_LCD(LEFT,DATA,ch_w);
elsewrite_LCD(RIGHT,DATA,ch_w);
}
}
else//上半部是写半个字节
{
for(j=0;j
SetPageCol(uPage,uCol+j);
if(uCol+j<64)ch_r=read_LCD(LEFT);
elsech_r=read_LCD(RIGHT);
ch_r&=0x0f;
ch_w=ASC_16[k].Msk[j];
ch_w=ch_w<<4;
ch_w|=ch_r;
SetPageCol(uPage,uCol+j);
if(uCol+j<64)write_LCD(LEFT,DATA,ch_w);
elsewrite_LCD(RIGHT,DATA,ch_w);
}
SetPageCol(uPage+1,uCol);
for(j=0;j
SetPageCol(uPage+1,uCol+j);
ch_r=ASC_16[k].Msk[j];
ch_w=ASC_16[k].Msk[ASC_CHR_WIDTH+j];
ch_r=ch_r>>4;
ch_w=ch_w<<4;
ch_w|=ch_r;
SetPageCol(uPage+1,uCol+j);
if(uCol+j<64)write_LCD(LEFT,DATA,ch_w);
elsewrite_LCD(RIGHT,DATA,ch_w);
}
}
}
SetPageCol(uPage,uCol+width);
}
voiddisp_hz(unsignedchar*hz)
{
unsignedchark,j,uPage,uCol,ch_r,ch_w;
uPage=GetPage();
uCol=GetCol();
for(k=0;k
if(hz[0]==GB_16[k].Index[0]&&hz[1]==GB_16[k].Index[1])
break;
}
if(CurOffset==1)
{
for(j=0;j{
SetPageCol(uPage,uCol+j);
ch_w=GB_16[k].Msk[j];
if(uCol+j<64)write_LCD(LEFT,DATA,ch_w);
elsewrite_LCD(RIGHT,DATA,ch_w);
}
SetPageCol(uPage+1,uCol);
for(j=0;j{
SetPageCol(uPage+1,uCol+j);
if(uCol+j<64)ch_r=read_LCD(LEFT);
elsech_r=read_LCD(RIGHT);
ch_r&=0xf0;
ch_w=GB_16[k].Msk[ASC_HZ_WIDTH+j]&0x0f;
ch_w|=ch_r;
SetPageCol(uPage+1,uCol+j);
if(uCol+j<64)write_LCD(LEFT,DATA,ch_w);
elsewrite_LCD(RIGHT,DATA,ch_w);
}
SetPageCol(uPage,uCol+ASC_HZ_WIDTH);
}
else//汉字上半部是写半个字节
{
for(j=0;j{
SetPageCol(uPage,uCol+j);
if(uCol+j<64)ch_r=read_LCD(LEFT);
elsech_r=read_LCD(RIGHT);
ch_r&=0x0f;
ch_w=GB_16[k].Msk[j];
ch_w=ch_w<<4;
ch_w|=ch_r;
SetPageCol(uPage,uCol+j);
if(uCol+j<64)write_LCD(LEFT,DATA,ch_w);
elsewrite_LCD(RIGHT,DATA,ch_w);
}
SetPageCol(uPage+1,uCol);
for(j=0;j{
SetPageCol(uPage+1,uCol+j);
ch_r=GB_16[k].Msk[j];
ch_w=GB_16[k].Msk[ASC_HZ_WIDTH+j];
ch_r=ch_r>>4;
ch_w=ch_w<<4;
ch_w|=ch_r;
SetPageCol(uPage+1,uCol+j);
if(uCol+j<64)write_LCD(LEFT,DATA,ch_w);
elsewrite_LCD(RIGHT,DATA,ch_w);
}
SetPageCol(uPage,uCol+ASC_HZ_WIDTH);
}
}
voiddisp_str(unsignedchar*p)
{
unsignedchari=0;
while(p[i]>0)
{
if(p[i]<128)
{/*ASCII*/
disp_ch(p[i]);
}
else
{/*中文*/
disp_hz(&p[i]);
i++;
}
i++;
}
}
/*************************************/
/*绘点函数*/
/*************************************/
/*XX--(0-128)YY--(0-63)FLAG=1绘点FLAG=0清点*/
voidpixel(unsignedcharxx,unsignedcharyy,unsignedcharflag)
{
unsignedinty,ch;
ch=yy%8;//余数
y=1;
for(;ch!=0;)
{
y=y*2;
ch--;
}
if(xx<64)
{
set_page_L(yy/8);
set_col_addr_L(xx);
ch=read_LCD(LEFT);
set_col_addr_L(xx);
if(flag)
write_LCD(LEFT,DATA,ch|y);
else
{
y=~y;
ch&=y;
write_LCD(LEFT,DATA,ch|y);
}
}
else
{
set_page_R(yy/8);
set_col_addr_R(xx-64);
ch=read_LCD(RIGHT);
set_col_addr_R(xx-64);
if(flag)
write_LCD(RIGHT,DATA,ch|y);
else
{
y=~y;
ch&=y;
write_LCD(RIGHT,DATA,ch|y);
}
}
}