液晶点阵显示屏程序设计.docx
《液晶点阵显示屏程序设计.docx》由会员分享,可在线阅读,更多相关《液晶点阵显示屏程序设计.docx(28页珍藏版)》请在冰豆网上搜索。
液晶点阵显示屏程序设计
液晶点阵显示屏程序设计
———单片机课程设计报告
一、设计题目:
液晶点阵显示屏程序设计
二、设计要求:
1能进行正常的模拟量采样值显示(温度、压力、电位),并将其显示到液晶面板上。
2LCD将从下到上滚动显示:
“江苏大学计算机学院”,然后显示:
“2006年单片机课程设计”“液晶点阵显示屏程序设计”“作者姓名、班级、学号”
3改变字库的内容,显示其它汉字。
4改变页地址或列地址,使显示的内容改变位置
5改变滚动显示模式,使显示内容左右、上下滚动;改变参数使滚动速度变化。
三、设计思路及实施步骤:
(一)设计思路:
由于实验指导书中做过液晶显示和模数转换得实验,根据两个实验的功能实现和流程原理进行设计
将程序分成三个模块:
主函数模块main.c
模数转换模块ADC.c
液晶显示模块KS0108.c
其中让主函数模块做一些初始化和函数调用工作,模数转换模块主要是将温度,压力,点位的值转化为数字量供液晶显示用,液晶显示模块得到模数转换模块传递过来的数字量显示到液晶面板上。
(二)系统流程图:
1系统主流程图如下:
2主函数流程图:
3显示模块流程图
4模数转换模块流程图
(三)系统部程序及功能说明(程序注释部分)
#include"c8051F020.h"
#include
液晶点阵显示试验-128*64,控制器KS0108
试验准备:
将拨码开关S1和S2置于ON位置.
运行此程序,LCD将从下到上滚动显示:
“江苏大学计算机学院”
然后交替显示:
“2010年单片机课程设计”“液晶点阵显示屏程序设计”“作者姓名、班级、学号”
*/
#defineLCD_DATAP2
#defineLCD_RSP30
#defineLCD_RWP31
#defineLCD_EP32
#defineLCD_CS1P33
#defineLCD_CS2P34
#defineLCD_RSTP35
#defineMUX_TEMP0x08
#defineMUX_VOLT0x01
#defineMUX_PRESS0x02
#defineNOSELECT7279P5|=0x80//SPICS4(P57)=1
#defineSELECT7279P5&=~(0x80)//SPICS4(P57)=0;
#defineSet7279DATHD7279_DAT=1
#defineClr7279DATHD7279_DAT=0
#defineSet7279CLKHD7279_CLK=1
#defineClr7279CLKHD7279_CLK=0
voidDelay1ms(unsignedchar);
/*--宽度x高度=128x64--*/
charcodescreen[]={江苏大学计算机学院};
/*--宽度x高度=128x64--*/
charcodescreen1[]={2010年单片机课程设计};
/*--宽度x高度=128x64--*/
charcodescreen2[]={液晶点阵显示屏程序设计};
/*--宽度x高度=128x64--*/};
charcodescreen3[]={作者姓名、班级、学号};
#defineSELECTCS0
//LCD
voidLCD_WaitReady1(void)//判断LCD控制芯片KS0108是否忙
{
LCD_DATA=0xff;
_nop_();
LCD_CS2=SELECTCS;//片学cs2
LCD_RW=1;//读写选择
LCD_RS=0;//数据指令选择
LCD_E=1;//读写使能
while(LCD_DATA&0x80);//等待空闲
LCD_CS2=!
SELECTCS;
}
voidLCD_WaitReady2(void)//判断LCD控制芯片KS0108是否忙
{
LCD_DATA=0xff;
_nop_();
LCD_CS1=SELECTCS;
LCD_RW=1;
LCD_RS=0;
LCD_E=1;
while(LCD_DATA&0x80);
LCD_CS1=!
SELECTCS;
}
voidLCD_WriteCommand1(charch)//向LCD控制芯片KS0108发送控制命令
{
LCD_WaitReady1();
LCD_CS2=SELECTCS;
LCD_RW=0;
LCD_RS=0;
LCD_DATA=ch;
LCD_E=1;
LCD_E=0;
LCD_CS2=!
SELECTCS;
}
voidLCD_WriteCommand2(charch)//向LCD控制芯片KS0108发送控制命令
{
LCD_WaitReady2();
LCD_CS1=SELECTCS;
LCD_RW=0;
LCD_RS=0;
LCD_DATA=ch;
LCD_E=1;
LCD_E=0;
LCD_CS1=!
SELECTCS;
}
voidLCD_WriteData1(charch)//向LCD控制芯片KS0108发送数据命令
{
LCD_WaitReady1();
LCD_CS2=SELECTCS;
LCD_RW=0;//写
LCD_RS=1;//数据、指令
LCD_DATA=ch;
LCD_E=1;//读写使能
LCD_E=0;
LCD_CS2=!
SELECTCS;
}
voidLCD_WriteData2(charch)//向LCD控制芯片KS0108发送数据命令
{
LCD_WaitReady2();
LCD_CS1=SELECTCS;
LCD_RW=0;
LCD_RS=1;
LCD_DATA=ch;
LCD_E=1;
LCD_E=0;
LCD_CS1=!
SELECTCS;
}
/*--文字:
温--*/
charcodeWen[]={};
/*--文字:
度--*/
charcodeDu[]={};
/*--文字:
压--*/
charcodeYa[]={};
/*--文字:
力--*/
charcodeLi[]={};
/*--文字:
电--*/
charcodeDian[]={};
/*--文字:
位--*/
charcodeWei[]={};
voidLCD_WriteHZ(charx,chary,char*Dot)//显示16*16点阵汉字
{
chari;
for(i=0;i<32;i++)
{
if((x+i%16)<64)//左半液晶屏显示
{
LCD_WriteCommand1(0xB8+y+i/16);//页数选择
LCD_WriteCommand1(0x40+x+i%16);//列数选择
LCD_WriteData1(Dot[i]);//一次写一字节
}
else//右半液晶屏显示
{
LCD_WriteCommand2(0xB8+y+i/16);
LCD_WriteCommand2(0x40+x-64+i%16);
LCD_WriteData2(Dot[i]);
}
}
}
/*--文字:
.--*/
charcodeDot[]={};
/*--文字:
0--*/
charcodeZero[]={};
/*--文字:
1--*/
charcodeOne[]={};
/*--文字:
2--*/
charcodeTwo[]={};
/*--文字:
3--*/
charcodeThree[]={};
/*--文字:
4--*/
charcodeFour[]={};
/*--文字:
5--*/
charcodeFive[]={};
/*--文字:
6--*/
charcodeSix[]={};
/*--文字:
7--*/
charcodeSeven[]={};
/*--文字:
8--*/
charcodeEight[]={};
/*--文字:
9--*/
charcodeNine[]={};
voidLCD_WriteSZ(charx,chary,intnum)//显示8*16点阵数字和点字符
{
char*Num_Dot;
chari;
switch(num)//根据需要选择要输出的数字
{
case0:
Num_Dot=Zero;break;
case1:
Num_Dot=One;break;
case2:
Num_Dot=Two;break;
case3:
Num_Dot=Three;break;
case4:
Num_Dot=Four;break;
case5:
Num_Dot=Five;break;
case6:
Num_Dot=Six;break;
case7:
Num_Dot=Seven;break;
case8:
Num_Dot=Eight;break;
case9:
Num_Dot=Nine;break;
case-1:
Num_Dot=Dot;break;
}
for(i=0;i<16;i++)
{
if((x+i%8)<64)
{
LCD_WriteCommand1(0xB8+y+i/8);选择地址显示数字
LCD_WriteCommand1(0x40+x+i%8);
LCD_WriteData1(Num_Dot[i]);
}
else
{
LCD_WriteCommand2(0xB8+y+i/8);
LCD_WriteCommand2(0x40+x-64+i%8);
LCD_WriteData2(Num_Dot[i]);
}
}
}
voidInitLCD(void)//初始化LCD
{
chari,j;
LCD_RST=0;
Delay1ms
(1);
LCD_RST=1;//复位信号把页地址计数器内容清零
LCD_WriteCommand1(0xc0);
LCD_WriteCommand2(0xc0);
LCD_WriteCommand1(0x3f);//开显示
LCD_WriteCommand2(0x3f);
for(j=0;j<8;j++)//清屏
{
LCD_WriteCommand1(0xB8+j);//清左半屏
LCD_WriteCommand1(0x40);
for(i=0;i<64;i++)
LCD_WriteData1(0x00);
LCD_WriteCommand2(0xB8+j);//清右半屏
LCD_WriteCommand2(0x40);
for(i=0;i<64;i++)
LCD_WriteData2(0x00);
}
}
voidDispBmp(char*buf)//显示一幅位图
{
inti,j;
//if(mode==0)
//{
for(j=0;j<8;j++)//显示位图
{
LCD_WriteCommand1(0xB8+j);
LCD_WriteCommand1(0x40);//Y地址读写后自动加1
for(i=0;i<64;i++)
LCD_WriteData1(buf[(j*2)*64+i]);//左半液晶屏显示
LCD_WriteCommand2(0xB8+j);
LCD_WriteCommand2(0x40);
for(i=0;i<64;i++)
LCD_WriteData2(buf[(j*2+1)*64+i]);//右半液晶屏显示
}
}
/*voidDispBmpUp(char*buf)//显示一幅位图,并上滚
{
inti;
DispBmp(buf);
for(i=0;i<64;i++)
{
Delay1ms(50);
LCD_WriteCommand1(0xc0+i%64);//设置起始行,实现上滚
LCD_WriteCommand2(0xc0+i%64);
}
}
voidDispBmpDown(char*buf)//显示一幅位图,并下滚
{
inti;
DispBmp(buf);
for(i=63;i>=0;i--)
{
Delay1ms(50);
LCD_WriteCommand1(0xc0+i%64);//设置起始行,实现下滚
LCD_WriteCommand2(0xc0+i%64);
}
}
voidDispBmpLeft(char*buf)//显示一幅位图,并左滚
{
inti,j,k;
for(k=0;k<128;k++)
{
Delay1ms(30);
for(j=0;j<8;j++)
{
LCD_WriteCommand1(0xB8+j);
LCD_WriteCommand1(0x40);
for(i=0;i<64;i++)
{
LCD_WriteData1(buf[(j*2)*64+(i+k)%128]);
}
LCD_WriteCommand2(0xB8+j);
LCD_WriteCommand2(0x40);
for(i=0;i<64;i++)
{
LCD_WriteData2(buf[(j*2)*64+(i+k+64)%128]);
}
}
}
}
voidDispBmpRight(char*buf)//显示一幅位图,并右滚
{
inti,j,k;
for(k=128;k>0;k--)
{
Delay1ms(30);
for(j=0;j<8;j++)
{
LCD_WriteCommand1(0xB8+j);
LCD_WriteCommand1(0x40);
for(i=0;i<64;i++)
{
LCD_WriteData1(buf[(j*2)*64+(i+k)%128]);
}
LCD_WriteCommand2(0xB8+j);
LCD_WriteCommand2(0x40);
for(i=0;i<64;i++)
{
LCD_WriteData2(buf[(j*2)*64+(i+k+64)%128]);
}
}
}
}
*/
voidDelay1s(unsignedcharT);
unsignedintGetADCValue(charNo);
charGetKeyValue(void);
voidWaitKeyOff(void);
voidTestLCD(void)
{
chari,j,buf[4],flag,keyvalue;//flag为小数点输出标志
unsignedintw;
InitLCD();
DispBmp(screen);//显示第一幅
for(i=0;i<64;i++)
{
Delay1ms(50);
LCD_WriteCommand1(0xc0+i%64);//设置起始行地址,实现向上滚动,第i行数据放在LCD的第一行显示
LCD_WriteCommand2(0xc0+i%64);
}
DispBmp(screen1);//显示第二幅图
for(i=0;i<64;i++)
{
Delay1ms(50);
LCD_WriteCommand1(0xc0+i%64);//设置起始行,实现向上滚动
LCD_WriteCommand2(0xc0+i%64);
}
DispBmp(screen2);//显示第三幅图
for(i=0;i<64;i++)
{
Delay1ms(50);
LCD_WriteCommand1(0xc0+i%64);//设置起始行,实现向上滚动
LCD_WriteCommand2(0xc0+i%64);
}
DispBmp(screen3);//显示第四幅图
for(i=0;i<64;i++)
{
Delay1ms(50);
LCD_WriteCommand1(0xc0+i%64);//设置起始行,实现向上滚动
LCD_WriteCommand2(0xc0+i%64);
}
Delay1ms(10);
InitLCD();
LCD_WriteHZ(0,0,Wen);//显示参数的中文字
LCD_WriteHZ(16,0,Du);
LCD_WriteHZ(0,2,Ya);
LCD_WriteHZ(16,2,Li);
LCD_WriteHZ(0,4,Dian);
LCD_WriteHZ(16,4,Wei);
for(i=0,flag=0;;i=(i+1)%3,flag=0)
{
w=GetADCValue(i+1);//获取温度,电压或压力
Delay1ms(250);
buf[0]=(w%10000)/1000;//取出各位上的数值
buf[1]=(w%1000)/100;
buf[2]=(w%100)/10;
buf[3]=(w%10);
if(i==2)//要输出的是电压,需要输出小数点的位置需改变一下
{
for(j=0;j<5;j++)//5个符号输出
{
if(j==1)
{
LCD_WriteSZ(32+j*8,i*2,-1);//显示数字,参数为-1输出小数点;
flag=1;
}
else
{
LCD_WriteSZ(32+j*8,i*2,buf[j-flag]);//利用flag来控制数据位
}
}
}
else//输出温度和压力数据
{
for(j=0;j<5;j++)
{
if(j==2)
{
LCD_WriteSZ(32+j*8,i*2,-1);//显示数字参数为-1输出小数点;
flag=1;
}
else
{
LCD_WriteSZ(32+j*8,i*2,buf[j-flag]);
}
}
}
}
}
ADC:
unsignedintidataTemp,Press,Volt;
unsignedcharidatamux_select;
sfr16ADC0=0xbe;//ADC0data
voidinit_adc(void)
{
ADC0CN=0x81;//ADC0enabled;normaltracking
//mode;ADC0conversionsareinitiated
//onwritetoAD0BUSY;ADC0datais
//left-justified
REF0CN=0x07;//enabletempsensor,on-chipVREF,
//andVREFoutputbuffer
mux_select=MUX_TEMP;//CPUon-chiptempsensor
AMX0SL=MUX_TEMP;
ADC0CF=(SYSCLK/2500000)<<3;//ADCconversionclock=2.5MHz
//ADC0CF|=0x01;//PGAgain=2
EIE2&=~0x02;//disableADC0EOCinterrupt
EIE1&=~0x04;//disableADC0windowcompareinterrupt
}
//On-chiptemperature
//AN1.电位器
//AN2.应变片
voidread_analog_inputs(void)
{
longtemp_long;
AD0INT=0;//clearconversioncompleteindicator
AD0BUSY=1;//initiateconversion
while(AD0INT==0);//waitforconversioncomplete
switch(mux_select)//通过每次的调用来获取电压,温度和压力值
{
caseMUX_TEMP:
temp_long=ADC0-42380/2;
temp_long=(temp_long*200L)/156;
Temp=temp_long;
AMX0SL=MUX_VOLT;//SelectAIN1fornextread
mux_select=MUX_VOLT;
break;
caseMUX_VOLT:
temp_long=ADC0;
Volt=24*temp_long/655;
AMX0SL=MUX_PRESS;//Selecton-chiptempsensor
mux_select=MUX_PRESS;
break;
caseMUX_PRESS:
temp_long=ADC0;
temp_long=24*temp_long/655;
Press=temp_long;
AMX0SL=MUX_TEMP;
mux_select=MUX_TEMP;
break;