单片机课程设计液晶显示陈帅.docx
《单片机课程设计液晶显示陈帅.docx》由会员分享,可在线阅读,更多相关《单片机课程设计液晶显示陈帅.docx(25页珍藏版)》请在冰豆网上搜索。
单片机课程设计液晶显示陈帅
JIANGSUUNIVERSITY
单片机原理及应用
学院名称:
计算机
专业班级:
计算机0802
学生姓名:
陈帅
学生学号:
3080602048
指导教师姓名:
陈向益
2011年6月
点阵式液晶显示屏的显示程序设计
一、设计目的
1.熟练掌握C51系统仿真开发系统的应用。
2.加强单片机的综合运用能力、提高单片机的软件编程和调试能力,为以后的学习和开发工作打下良好基础。
3.掌握的液晶的工作原理以及应用设计。
4.掌握小系统开发设计的流程以及设计思路。
二、设计方案
实验要求:
1)从下到上滚动显示:
“江苏大学计算机学院”然后交替显示:
“单片机课程设计”“液晶点阵显示屏程序设计”“作者姓名、班级、学号”
2)能进行正常的模拟量采样值显示(温度、压力、电位)。
3)改变字库的内容,显示其它汉字。
4)改变页地址或列地址,使显示的内容改变位置。
5)其它功能(如左、右移,上下卷、显示图片等)。
设计思路:
由于实验指导书中做过液晶显示和模数转换得实验,根据两个实验的功能实现和流程原理进行设计
将程序分成三个模块:
主函数模块main.c
模数转换模块ADC.c
液晶显示模块KS0108.c
其中让主函数模块做一些初始化和函数调用工作,模数转换模块主要是将温度,压力,点位的值转化为数字量供液晶显示用,液晶显示模块得到模数转换模块传递过来的数字量显示到液晶面板上。
程序流程图:
1系统主流程图如下
2主函数流程图
3显示模块流程图
4模数转换模块流程图
主要的源程序及注释
主函数:
#include"c8051f020.h"
#include
voidDelay1us(unsignedcharus)//延时us
{
while(us)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
--us;
}
}
voidSYSCLK_Init(void)//系统时钟初始化
{
inti;//delaycounter
OSCXCN=0x67;//startexternaloscillatorwith
//18.432MHzcrystal
for(i=0;i<256;i++);//Waitforosc.tostartup
while(!
(OSCXCN&0x80));//Waitforcrystalosc.tosettle
OSCICN=0x88;//selectexternaloscillatorasSYSCLK
//sourceandenablemissingclock
//detector
//OSCICN=0x07;//interal16MHZ
}
#definePRT0CFP0MDOUT
#definePRT1CFP1MDOUT
#definePRT2CFP2MDOUT
voidPORT_Init(void)//串口初始化
{
XBR0=0x07;//EnableSMBus,SPI0,andUART0
XBR1=0x00;
XBR2=0x44;//Enablecrossbarandweakpull-ups
EMI0CF=0x27;
EMI0TC=0x21;
P74OUT=0xFF;
P0MDOUT=0x15;
P1MDOUT|=0x3C;//P1.2-P1.5推挽输出
P1&=0xc3;//P1.2-P1.5=0
}
voidSPI0_Init(void)//spi0初始化
{
SPI0CFG=0x07;//datasampledon1stSCKrisingedge
//8-bitdatawords
SPI0CFG|=0xC0;//CKPOL=1;
SPI0CN=0x03;//Mastermode;SPIenabled;flags
//cleared
SPI0CKR=SYSCLK/2/8000000-1;//SPIclock<=8MHz(limitedby
//EEPROMspec.)
}
unsignedcharCount1ms;
voidTimer0_Init(void)//计数器0初始化
{
CKCON|=0x8;
TMOD|=0x1;//16Bit
Count1ms=10;
TR0=0;//STOPTimer0
TH0=(-SYSCLK/1000)>>8;//setTimer0tooverflowin1ms
TL0=-SYSCLK/1000;
TR0=1;//STARTTimer0
IE|=0x2;
}
voidTimer0_ISR(void)interrupt1//1ms
{
TH0=(-SYSCLK/1000)>>8;
TL0=-SYSCLK/1000;
if(Count1ms)Count1ms--;
}
voidDelay1ms(unsignedcharT)//延时1ms
{
Count1ms=T;
while(Count1ms);
}
voidDelay1s(unsignedcharT)//延时1s
{
while(T)
{
Delay1ms(200);
Delay1ms(200);
Delay1ms(200);
Delay1ms(200);
Delay1ms(200);
T--;
}
}
voidTestLCD(void);//测试初始画面
charGetKeyValue(void);//获取键值
voidinit_adc(void);
unsignedintGetADCValue(charNo);
voidDisplay(char*DispBuf,charShowDot,charx,chary);
voidmenulcd();
voidzuoyouyi();
voidcaiji();
voidmain(void)
{
chari;
unsignedintu;
charNum;
WDTCN=0xde;
WDTCN=0xad;//关看门狗
SYSCLK_Init();//初始化时钟
Timer0_Init();//初始化定时器
PORT_Init();//初始化IO口
SPI0_Init();//初始化SPI0
init_adc();
CPT1CN|=0x80;//使能比较器1
REF0CN=0x07;//使能片内参考电压
DAC0CN|=0x80;//使能DAC0
DAC0H=0;DAC0L=0;
EA=1;//开中断
Num=0;
menulcd();
u=GetADCValue(Num);//获取按键值
for(;;)
{
i=GetKeyValue();
if((i<1)||(i>3))
Num=i;
Delay1ms(100);
if(Num==0)
{
menulcd();//按0显示主菜单
}
elseif(Num==4)
{
TestLCD();//按4显示开始画面
}
elseif(Num==5)
{
zuoyouyi();//按5汉字,图画左右移动
}
elseif(Num==6)
{
caiji();//按6采集温度,电压,压力
}
u=GetADCValue(Num);
}
}
KS0108模块:
#include"c8051F020.h"
#include
#include"dianzhen.c"//所有用到的汉字,图画点阵
#defineLCD_DATAP2
#defineLCD_RSP30
#defineLCD_RWP31
#defineLCD_EP32
#defineLCD_CS1P33
#defineLCD_CS2P34
#defineLCD_RSTP35
sbitHD7279_DAT=P1^7;
sbitHD7279_CLK=P1^6;
#defineNOSELECT7279P5|=0x80//SPICS4(P57)=1
#defineSELECT7279P5&=~(0x80)//SPICS4(P57)=0;
#defineSet7279DATHD7279_DAT=1
#defineClr7279DATHD7279_DAT=0
#defineSet7279CLKHD7279_CLK=1
#defineClr7279CLKHD7279_CLK=0
//7279模块
voidDelay1ms(unsignedcharT);
voidDelay1s(unsignedcharT);
voidDelay1us(unsignedcharT);
voidSend7279Byte(unsignedcharch)//发送
{
chari;
SELECT7279;//置CS低电平
Delay1us(50);//延时50μ
for(i=0;i<8;i++)
{
if(ch&0x80)//输出7位到HD7279A的DATA端
{
Set7279DAT;
}
else
{
Clr7279DAT;
}
Set7279CLK;//置CLK高电平
ch=ch<<1;//待发数据左移
Delay1us(8);//延时8μ
Clr7279CLK;//置CLK低电平
Delay1us(8);//延时50μ
}
Clr7279DAT;//发送完毕,DATA端置低,返回
}
unsignedcharReceive7279Byte(void)//接收
{
unsignedchari,ch;
ch=0;
Set7279DAT;//DATA端置为高电平,输入状态
Delay1us(50);//延时50μ
for(i=0;i<8;i++)
{
Set7279CLK;//置CLK高电平
Delay1us(8);//延时8μ
ch=ch<<1;//接收数据左移1位
if(HD7279_DAT)
ch+=1;//接收1位数据
Clr7279CLK;//置CLK低电平
Delay1us(8);//延时8μ
}
Clr7279DAT;//接收完毕,DATA端重新置成低电平(输出状态)
returnch;
}
unsignedcharcodeBdSeg[]={
0x7e,0x30,0x6d,0x79,//0123
0x33,0x5b,0x5f,0x70,//4567
0x7f,0x7b,0x77,0x1f,//89ab
0x4e,0x3d,0x4f,0x47,//cdef
0x00,0x01};
charGetKeyValue(void)//获取键值
{
charKeyValue;
if(CPT1CN&0x40)return-1;//无键按下
Send7279Byte(0x15);//发读键盘指令
KeyValue=Receive7279Byte();
NOSELECT7279;//置CS高电平
returnKeyValue;
}
//KS0108模块
#defineSELECTCS0
voidLCD_WaitReady1(void)//判断LCD控制芯片KS0108是否忙
{
LCD_DATA=0xff;
_nop_();
LCD_CS2=SELECTCS;
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;
}
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]);
}
}
}
voidLCD_WriteHZcircle(charx,chary,char*Dot)//显示循环汉字
{
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]);
}
elseif((x+i%16)>63&&(x+i%16)<=127)
{
LCD_WriteCommand2(0xB8+y+i/16);
LCD_WriteCommand2(0x40+x-64+i%16);
LCD_WriteData2(Dot[i]);
}
else
{
LCD_WriteCommand1(0xB8+y+i/16);
LCD_WriteCommand1(0x40+(x+i%16)%128);
LCD_WriteData1(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,intn)//显示一幅位图
{
inti,j;
for(j=0;j<8;j++)//显示位图
{
LCD_WriteCommand1(0xB8+j+n);
LCD_WriteCommand1(0x40);
for(i=0;i<64;i++)
LCD_WriteData1(buf[(j*2)*64+i]);
LCD_WriteCommand2(0xB8+j+n);
LCD_WriteCommand2(0x40);
for(i=0;i<64;i++)
LCD_WriteData2(buf[(j*2+1)*64+i]);
}
}
voidDispBmp1(char*buf,intn,intm)//显示一幅位图//128*16,n为页值,m为列值
{
inti,j;
for(j=0;j<2;j++)//显示位图
{
if(m<=63)
{
LCD_WriteCommand1(0xB8+j+n);
LCD_WriteCommand1(0x40);
for(i=128-m;i<=127;i++)
LCD_WriteData1(buf[i+128*j]);
for(i=0;i<=63-m;i++)
LCD_WriteData1(buf[i+128*j]);
LCD_WriteCommand2(0xB8+j+n);
LCD_WriteCommand2(0x40);
for(i=64-m;i<=127-m;i++)
LCD_WriteData2(buf[128*j+i]);
}
else
{
LCD_WriteCommand2(0xB8+j+n);
LCD_WriteCommand2(0x40);
for(i=192-m;i<=127;i++)
LCD_WriteData2(buf[128*j+i]);
for(i=0;i<=127-m;i++)
LCD_WriteData2(buf[128*j+i]);
LCD_WriteCommand1(0xB8+j+n);
LCD_WriteCommand1(0x40);
for(i=128-m;i<=191-m;i++)
LCD_WriteData1(buf[i+128*j]);
}
}
}
voidDisplay(char*DispBuf,charShowDot,charx,chary)//液晶屏显示温度、电压,压力值
{
chari,ch,j=-16;
ShowDot--;
for(i=2;i<6;i++)
{
j+=16;
ch=DispBuf[i];
switch(ch)
{case0:
LCD_WriteHZ(x+j,y,led0);break;
case1:
LCD_WriteHZ(x+j,y,led1);break;
case2:
LCD_WriteHZ(x+j,y,led2);break;
case3:
LCD_WriteHZ(x+j,y,led3);break;
case4:
LCD_WriteHZ(x+j,y,led4);break;
case5:
LCD_WriteHZ(x+j,y,led5);break;
case6:
LCD_WriteHZ(x+j,y,led6);break;
case7:
LCD_WriteHZ(x+j,y,led7);break;
case8:
LCD_WriteHZ(x+j,y,led8);break;
case9:
LCD_WriteHZ(x+j,y,led9);break;
default:
LCD_WriteHZ(x+j,y,led);break;
}
if(i==ShowDot)
{
LCD_WriteHZ(x+j+8,y,Dot);
}
}
}
unsignedintGetADCValue(charNo);
charGetKeyValue(void);
voidmenulcd()//显示菜单
{
InitLCD();
DispBmp(menu,0);
}
voidTestLCD(void)//开头文字的显示
{
chari;
InitLCD();
DispBmp(ss,1);//江苏大学计算机学院
Delay1s(0.5);
for(i=0;i<64;i++)
{
Delay1ms(100);
LCD_WriteCommand1(0xc0+i%64);/