《单片机课程设计点阵式液晶显示屏的显示程序设计.doc》由会员分享,可在线阅读,更多相关《单片机课程设计点阵式液晶显示屏的显示程序设计.doc(18页珍藏版)》请在三一办公上搜索。
1、点阵式液晶显示屏的显示程序设计一、设计目的1熟练掌握C51系统仿真开发系统的应用。2加强单片机的综合运用能力、提高单片机的软件编程和调试能力,为以后的学习和开发工作打下良好基础。3掌握的液晶的工作原理以及应用设计。4掌握小系统开发设计的流程以及设计思路。二、设计方案 实验要求:1)从下到上滚动显示:“江苏大学计算机学院”然后交替显示:“单片机课程设计”“液晶点阵显示屏程序设计”“作者姓名、班级、学号” 2)能进行正常的模拟量采样值显示(温度、压力、电位) 。 3) 改变字库的内容,显示其它汉字。 4) 改变页地址或列地址,使显示的内容改变位置。 5)其它功能(如左、右移,上下卷、显示图片等)。
2、设计思路:由于实验指导书中做过液晶显示和模数转换得实验,根据两个实验的功能实现和流程原理进行设计将程序分成三个模块:主函数模块main.c模数转换模块ADC.c液晶显示模块KS0108.c其中让主函数模块做一些初始化和函数调用工作,模数转换模块主要是将温度,压力,点位的值转化为数字量供液晶显示用,液晶显示模块得到模数转换模块传递过来的数字量显示到液晶面板上。程序流程图:1系统主流程图如下开始主函数模块显示模块模数转换模块2主函数流程图开始使能比较器1开中断初始化系统时钟钟初始化定时器0初始化IO端口初始化SPI0使能片内参考电压使能DAC3 显示模块流程图开始初始化LCD滚屏显示江苏大学计算机
3、学院读取数字量并显示调用模数转换得到值显示课程设计题目、班级、姓名健值是否1.2.34 模数转换模块流程图开始读取No和模拟量返回温度返回点位结束返回压力No=2?No=3?No=1? 主要的源程序及注释主函数:#include c8051f020.h #include void Delay1us(unsigned char us)/延时uswhile (us) _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); -us;void SYSCLK_Init (void)/系统时钟初始化 int i; / delay counter OSCXCN = 0x67
4、; / start external oscillator with / 18.432MHz crystal for (i=0; i 256; i+) ; / Wait for osc. to start up while (!(OSCXCN & 0x80) ; / Wait for crystal osc. to settle OSCICN = 0x88; / select external oscillator as SYSCLK / source and enable missing clock / detector/OSCICN = 0x07; /interal 16MHZ#defin
5、e PRT0CF P0MDOUT#define PRT1CF P1MDOUT#define PRT2CF P2MDOUTvoid PORT_Init (void) /串口初始化 XBR0 = 0x07; / Enable SMBus, SPI0, and UART0 XBR1 = 0x00; XBR2 = 0x44; / Enable crossbar and weak pull-ups EMI0CF = 0x27; EMI0TC = 0x21; P74OUT = 0xFF; P0MDOUT = 0x15; P1MDOUT |= 0x3C; /P1.2-P1.5推挽输出 P1 &= 0xc3;
6、/P1.2-P1.5=0void SPI0_Init (void) /spi0初始化 SPI0CFG = 0x07; / data sampled on 1st SCK rising edge / 8-bit data words SPI0CFG|=0xC0;/CKPOL =1; SPI0CN = 0x03; / Master mode; SPI enabled; flags / cleared SPI0CKR = SYSCLK/2/8000000-1; / SPI clock 8; / set Timer0 to overflow in 1ms TL0 = -SYSCLK/1000; TR0
7、 = 1; / START Timer0 IE|= 0x2; void Timer0_ISR (void) interrupt 1 /1ms TH0 = (-SYSCLK/1000) 8; TL0 = -SYSCLK/1000;if (Count1ms) Count1ms-;void Delay1ms(unsigned char T) /延时1msCount1ms=T;while (Count1ms);void Delay1s(unsigned char T) /延时1swhile (T)Delay1ms(200);Delay1ms(200);Delay1ms(200);Delay1ms(20
8、0);Delay1ms(200);T-;void TestLCD(void);/测试初始画面char GetKeyValue(void);/获取键值void init_adc(void);unsigned int GetADCValue(char No);void Display (char *DispBuf,char ShowDot,char x,char y);void menulcd ();void zuoyouyi();void caiji ();void main (void) char i;unsigned int u;char Num;WDTCN = 0xde;WDTCN = 0
9、xad; /关看门狗SYSCLK_Init (); /初始化时钟Timer0_Init();/初始化定时器PORT_Init (); /初始化IO口SPI0_Init (); /初始化SPI0 init_adc();CPT1CN|=0x80;/使能比较器1REF0CN = 0x07; /使能片内参考电压DAC0CN |= 0x80;/使能DAC0DAC0H=0;DAC0L=0; EA=1;/开中断 Num=0; menulcd ();u= GetADCValue(Num);/获取按键值for (;)i=GetKeyValue();if (i3)Num=i;Delay1ms(100);if (N
10、um=0)menulcd ();/按0显示主菜单else if(Num=4) TestLCD();/按4显示开始画面else if(Num=5)zuoyouyi();/按5汉字,图画左右移动else if(Num=6)caiji ();/按6采集温度,电压,压力u = GetADCValue(Num);KS0108模块:#include c8051F020.h#include #include dianzhen.c/所有用到的汉字,图画点阵#define LCD_DATA P2#define LCD_RS P30#define LCD_RW P31#define LCD_E P32#defin
11、e LCD_CS1 P33#define LCD_CS2 P34#define LCD_RST P35sbitHD7279_DAT=P17;sbitHD7279_CLK=P16;#define NOSELECT7279 P5 |= 0x80/SPICS4(P57)=1#define SELECT7279 P5 &= (0x80) /SPICS4(P57)=0;#define Set7279DAT HD7279_DAT=1#define Clr7279DAT HD7279_DAT=0#define Set7279CLK HD7279_CLK=1#define Clr7279CLK HD7279_
12、CLK=0/7279模块void Delay1ms(unsigned char T);void Delay1s(unsigned char T);void Delay1us(unsigned char T);void Send7279Byte(unsigned char ch)/发送char i;SELECT7279; /置CS低电平 Delay1us(50);/延时50for (i=0;i8;i+)if (ch&0x80)/输出7位到HD7279A的DATA端 Set7279DAT;elseClr7279DAT;Set7279CLK;/置CLK高电平 ch=ch1;/待发数据左移 Delay
13、1us(8);/延时8Clr7279CLK;/置CLK低电平 Delay1us(8);/延时50Clr7279DAT;/发送完毕,DATA端置低,返回 unsigned char Receive7279Byte(void)/接收unsigned char i,ch;ch=0;Set7279DAT;/DATA端置为高电平,输入状态Delay1us(50);/延时50for (i=0;i8;i+)Set7279CLK;/置CLK高电平Delay1us(8);/延时8ch=ch1;/接收数据左移1位if (HD7279_DAT)ch+=1;/接收1位数据Clr7279CLK;/置CLK低电平Dela
14、y1us(8);/延时8Clr7279DAT;/接收完毕,DATA端重新置成低电平(输出状态)return ch;unsigned char code BdSeg=0x7e,0x30,0x6d,0x79, / 0 1 2 3 0x33,0x5b,0x5f,0x70, / 4 5 6 7 0x7f,0x7b,0x77,0x1f, / 8 9 a b 0x4e,0x3d,0x4f,0x47, / c d e f 0x00,0x01; char GetKeyValue(void)/获取键值char KeyValue;if (CPT1CN&0x40) return -1;/无键按下 Send7279B
15、yte(0x15);/发读键盘指令 KeyValue=Receive7279Byte();NOSELECT7279; /置CS高电平 return KeyValue; /KS0108模块#define SELECTCS 0void LCD_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;void LCD_WaitReady2(void) /判断LCD控制芯片KS0
16、108是否忙LCD_DATA=0xff;_nop_();LCD_CS1=SELECTCS;LCD_RW=1;LCD_RS=0;LCD_E=1;while (LCD_DATA&0x80);LCD_CS1=!SELECTCS;void LCD_WriteCommand1(char ch) /向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;void LCD_WriteCommand2(char ch)/向LCD控制
17、芯片KS0108发送控制命令LCD_WaitReady2();LCD_CS1=SELECTCS;LCD_RW=0;LCD_RS=0;LCD_DATA=ch;LCD_E=1;LCD_E=0;LCD_CS1=!SELECTCS;void LCD_WriteData1(char ch)/向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;void LCD_WriteData2(char ch)/向LCD控制芯片KS01
18、08发送数据命令LCD_WaitReady2();LCD_CS1=SELECTCS;LCD_RW=0;LCD_RS=1;LCD_DATA=ch;LCD_E=1;LCD_E=0;LCD_CS1=!SELECTCS;void LCD_WriteHZ(char x,char y,char *Dot) /显示16*16点阵汉字char i;for (i=0;i32;i+)if (x+i%16)64)LCD_WriteCommand1(0xB8+y+i/16);LCD_WriteCommand1(0x40+x+i%16);LCD_WriteData1(Doti);elseLCD_WriteCommand
19、2(0xB8+y+i/16);LCD_WriteCommand2(0x40+x-64+i%16);LCD_WriteData2(Doti);void LCD_WriteHZcircle(char x,char y,char *Dot) /显示循环汉字char i;for (i=0;i32;i+)if (x+i%16)63&(x+i%16)=127)LCD_WriteCommand2(0xB8+y+i/16);LCD_WriteCommand2(0x40+x-64+i%16);LCD_WriteData2(Doti);elseLCD_WriteCommand1(0xB8+y+i/16);LCD_
20、WriteCommand1(0x40+(x+i%16)%128);LCD_WriteData1(Doti); void InitLCD(void) /初始化LCDchar i,j;LCD_RST=0;Delay1ms(1);LCD_RST=1; LCD_WriteCommand1(0xc0);LCD_WriteCommand2(0xc0);LCD_WriteCommand1(0x3f); /开显示LCD_WriteCommand2(0x3f);for (j=0;j8;j+)/清屏LCD_WriteCommand1(0xB8+j);/清左半屏LCD_WriteCommand1(0x40);for
21、 (i=0;i64;i+)LCD_WriteData1(0x00); LCD_WriteCommand2(0xB8+j);/清右半屏LCD_WriteCommand2(0x40);for (i=0;i64;i+)LCD_WriteData2(0x00);void DispBmp(char *buf,int n)/显示一幅位图int i,j;for (j=0;j8;j+)/显示位图LCD_WriteCommand1(0xB8+j+n);LCD_WriteCommand1(0x40);for (i=0;i64;i+)LCD_WriteData1(buf(j*2)*64+i);LCD_WriteCo
22、mmand2(0xB8+j+n);LCD_WriteCommand2(0x40);for (i=0;i64;i+)LCD_WriteData2(buf(j*2+1)*64+i);void DispBmp1(char *buf,int n,int m)/显示一幅位图/128*16,n为页值,m为列值int i,j;for (j=0;j2;j+)/显示位图if(m=63) LCD_WriteCommand1(0xB8+j+n);LCD_WriteCommand1(0x40);for(i=128-m;i=127;i+) LCD_WriteData1(bufi+128*j);for(i=0;i=63-
23、m;i+) LCD_WriteData1(bufi+128*j);LCD_WriteCommand2(0xB8+j+n);LCD_WriteCommand2(0x40);for(i=64-m;i=127-m;i+)LCD_WriteData2(buf128*j+i);else LCD_WriteCommand2(0xB8+j+n);LCD_WriteCommand2(0x40);for(i=192-m;i=127;i+)LCD_WriteData2(buf128*j+i);for(i=0;i=127-m;i+) LCD_WriteData2(buf128*j+i);LCD_WriteComma
24、nd1(0xB8+j+n);LCD_WriteCommand1(0x40);for(i=128-m;i=191-m;i+)LCD_WriteData1(bufi+128*j);void Display (char *DispBuf,char ShowDot,char x,char y) /液晶屏显示温度、电压,压力值char i,ch,j=-16;ShowDot-;for (i=2;i6;i+)j+=16;ch=DispBufi;switch(ch)case 0: LCD_WriteHZ(x+j,y,led0); break; case 1: LCD_WriteHZ(x+j,y,led1);
25、break;case 2: LCD_WriteHZ(x+j,y,led2); break;case 3: LCD_WriteHZ(x+j,y,led3); break;case 4: LCD_WriteHZ(x+j,y,led4); break;case 5: LCD_WriteHZ(x+j,y,led5); break;case 6: LCD_WriteHZ(x+j,y,led6); break;case 7: LCD_WriteHZ(x+j,y,led7); break;case 8: LCD_WriteHZ(x+j,y,led8); break;case 9: LCD_WriteHZ(x
26、+j,y,led9); break;default: LCD_WriteHZ(x+j,y,led); break;if(i=ShowDot)LCD_WriteHZ(x+j+8,y,Dot);unsigned int GetADCValue(char No);char GetKeyValue(void);void menulcd () /显示菜单InitLCD();DispBmp(menu,0);void TestLCD(void) /开头文字的显示char i;InitLCD();DispBmp(ss,1);/江苏大学计算机学院 Delay1s(0.5);for (i=0;i64;i+)Del
27、ay1ms(100);LCD_WriteCommand1(0xc0+i%64);/设置起始行,实现向上滚动LCD_WriteCommand2(0xc0+i%64);Delay1s(2); InitLCD();DispBmp(ss1,1);/单片机课程设计Delay1s(2); InitLCD();DispBmp(ss2,1);/液晶点阵显示屏程序设计Delay1s(2);InitLCD();DispBmp(ss3,1);/作者:陈帅 班级:计算机0802 学号:48Delay1s(2);void zuoyouyi()/汉字,图画左右移动char i,j,k;k=1; for (j=0;j8;j
28、+)/汉字从左向右滚动for(i=0;i=0;j-)/汉字从右向左滚动for(i=0;i=0)&(i=3)/如果按键大于3,则不读入键值No=i;Delay1ms(250);buf0= No;buf1= ;buf2=(w%10000)/1000;buf3=(w%1000)/100;buf4=(w%100)/10;buf5=(w%10);if (No=1)InitLCD();DispBmp(tem,1);/按1采集到温度Display(buf,4,50,4);else if (No=2)InitLCD();DispBmp(volte,1);/按2采集到电压Display(buf,3,50,4);
29、 else if (No=3)InitLCD();DispBmp(pres,1);/按3采集到压力Display(buf,4,50,4);else break;/按0回到主菜单 w = GetADCValue(No);ADC模块:#include c8051F020.h#include /*压力应变片ADC试验运行此程序,压力值将在数码管上显示.用手触摸应变片观察压力变化.*/#define MUX_TEMP0x08#define MUX_VOLT0x01#define MUX_PRESS0x02unsigned int idata Temp, Press, Volt;unsigned cha
30、r idata mux_select;sfr16 ADC0 = 0xbe; / ADC0 datavoid init_adc(void)ADC0CN = 0x81; / ADC0 enabled; normal tracking / mode; ADC0 conversions are initiated / on write to AD0BUSY; ADC0 data is / left-justifiedREF0CN = 0x07; / enable temp sensor, on-chip VREF, / and VREF output buffermux_select = MUX_TE
31、MP; / CPU on-chip temp sensorAMX0SL = MUX_TEMP; ADC0CF = (SYSCLK/2500000) 3; / ADC conversion clock = 2.5MHz/ADC0CF |= 0x01; / PGA gain = 2EIE2 &= 0x02; / disable ADC0 EOC interruptEIE1 &= 0x04; / disable ADC0 window compare interrupt/ On-chip temperature/ AN1. 电位器/ AN2. 应变片void read_analog_inputs(v
32、oid)long temp_long; AD0INT = 0; / clear conversion complete indicator AD0BUSY = 1; / initiate conversion while (AD0INT = 0); / wait for conversion completeswitch (mux_select)case MUX_TEMP: temp_long = ADC0 - 42380/2; temp_long = (temp_long * 200L) / 156;Temp=temp_long;AMX0SL = MUX_VOLT;/ Select AIN1
33、 for next readmux_select = MUX_VOLT;break; case MUX_VOLT:temp_long = ADC0;Volt = 24*temp_long/655;AMX0SL = MUX_PRESS;/ Select on-chip temp sensormux_select = MUX_PRESS;break; case MUX_PRESS:temp_long = ADC0;temp_long = 24*temp_long/655;Press = temp_long; AMX0SL = MUX_TEMP; mux_select = MUX_TEMP;brea
34、k;default:AMX0SL = MUX_TEMP;mux_select = MUX_TEMP;break; unsigned int GetADCValue(char No)/采集数据read_analog_inputs();read_analog_inputs();read_analog_inputs();switch (No)case 1:return Temp;case 2:return Volt;case 3:if (Press10) Press=0;return Press;3、调试过程将如下源文件main.c,c8051F020.h,ADC.c,KS0108.c加入到开发工具
35、中,调试程序,并下载到单片机中运行,首先有“江苏大学计算机学院”一行字向上滚动,然后显示“液晶点阵显示屏程序设计,班级,姓名”当这些字显示完毕后,进入温度、压力、电位显示模块中,按1键,液晶屏上将显示温度*.*;按2键,液晶屏上将显示电位*.*;按3键,液晶屏上将显示压力*.*。*代表数字。注意由于延时等原因,有时候按键后并不能转换为另一种要求的显示。系统基本按照课程设计的要求实现了所有功能,在程序设计和调试过程中,遇到和解决了以下几个问题:第一个就是在取字模的时候对于连续几行字的取模老是不成功,后来我采用了在画图板中把字排好版,然后用取模软件打开位图进行取模;第二个问题是刚开始的时候,用LCD_WriteJSDX(char x,char y,char *Dot)