液晶点阵显示屏课程设计报告 通信09235-宗慧

更新时间:2024-06-05 23:26:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

J I A N G S U U N I V E R S I T Y 单片机原理及应用

课程设计

学院名称: 计算机学院 专业班级: 通信0902 学生姓名: 宗慧 学生学号: 3090601035 指导教师姓名: 熊 书 明

2012 年 01 月

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

点阵式液晶显示屏的显示程序设计

宗慧

通信0902班 3090601035

一.设计目的

1.熟练掌握C51系统仿真开发系统的应用。

2.加强单片机的综合运用能力、提高单片机的软件编程和调试能力,为以后的学习和开发工作打下良好基础。

3.掌握的液晶的工作原理以及应用设计。 4.掌握小系统开发设计的流程以及设计思路。

二.设计要求

1)从下到上滚动显示:“江苏大学计算机学院”然后交替显示:“单片机

课程设计”“液晶点阵显示屏程序设计”“作者姓名、班级、学号”

2)能进行正常的模拟量采样值显示(温度、压力、电位) 。 3) 改变字库的内容,显示其它汉字。

4) 改变页地址或列地址,使显示的内容改变位置。

5)其它功能(如左、右移,上下卷、显示图片等)。

三.系统整体结构

由于实验指导书中做过液晶显示和模数转换得实验,根据两个实验的功能实现和流程原理进行设计

将程序分成三个模块:

主函数模块main.c 模数转换模块ADC.c 液晶显示模块KS0108.c

其中让主函数模块做一些初始化和函数调用工作,模数转换模块主要是将温度,压力,点位的值转化为数字量供液晶显示用,液晶显示模块得到模数转换模块传递过来的数字量显示到液晶面板上。 程序流程图: 1系统主流程图如下

1

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

开始 主函数模块 显示模块 模数转换模块

2主函数流程图

开始 开中断 初始化系统时钟使能DAC 初始化定时器初始化IO端使能片内参考电压 初始化SPI0 使能比较器1

3 显示模块流程图

2

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

开始 初始化LCD 滚屏显示江苏大学计算机学院 显示课程设计题目、班级、姓名 健值是否1.2.3 调用模数转换得到值 读取数字量并显示

4 模数转换模块流程图

开始 读取No和模拟量 No=1? No=2? No=3? 返回温度 返回点位 返回压力 结束

四.设计和实现

㈠主函数模块main.c

#include \ #include

3

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

void Delay1us(unsigned char us) {

while (us) {

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); --us; } }

//初始化系统时钟,使用22.1184MHZ晶体作为时钟源 void SYSCLK_Init (void) {

int i; // delay counter

OSCXCN = 0x67; // 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 }

#define PRT0CF P0MDOUT #define PRT1CF P1MDOUT #define PRT2CF P2MDOUT void 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推挽输出 P&=0xc3; //P1.2-P1.5=0 }

void SPI0_Init(void) {

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 <= 8MHz (limited by

4

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

// EEPROM spec.) }

unsigned char Count1ms; void Timer0_Init (void) {

CKCON|=0x8; //定时器按系统时钟频率计数 TMOD|=0x1; //方式一 16Bit Count1ms=10;

TR0=0; // 禁止T0计数 STOP Timer0

TH0=(-SYSCLK/1000) >> 8; // 定时器赋初值 65536-1000us overflow in 1ms

TL0=-SYSCLK/1000;

TR0=1; // 开始计数 START Timer0 IE|=0x2; //IE置1 }

void Timer0_ISR(void)interrupt 1 //产生1ms的中断服务程序 {

TH0=(-SYSCLK/1000)>>8; //f=1000,T=1ms TL0=-SYSCLK/1000; if (Count1ms) Count1ms--; }

void Delay1ms(unsigned char T) {

Count1ms=T;

while (Count1ms); }

void Delay1s(unsigned char T) {

while (T) {

Delay1ms(200); Delay1ms(200); Delay1ms(200); Delay1ms(200); Delay1ms(200); T--; } }

char GetKeyValue(void); void init_adc(void);

unsigned int GetADCValue(char No); void TestLCD(void);

void DispLCD(char *DispBuf,char num); void InitLCD(void);//初始化LCD

5

set Timer0 to 《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

void ShowWenDu(void); void ShowDianYa(void); void ShowYaLi(void); void showniu(); void showfu();

void showdsheshidu(); void main (void) {

unsigned int w; char No,i,buf[5]; No=1;

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; //开中断 //Test7279(0); loop: TestLCD(); InitLCD(); No=0;

//w = GetADCValue(1); for (;;) {

i=GetKeyValue(); if((i>=1)&&(i<=4)) {

No=i;

switch(No) {

case 1:

ShowWenDu();break; case 2:

ShowDianYa();break; case 3:

ShowYaLi();break; case 4:goto loop;break; default:

6

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

break; } }

w = GetADCValue(No); Delay1ms(30); switch(No) {

case 1:

buf[0]=(w000)/1000; buf[1]=(w00)/100; buf[2]=' ';

buf[3]=(w0)/10; buf[4]=(w); DispLCD(buf,1); showsheshidu(); break; case 2:

//ShowDianYa();

buf[0]=(w000)/1000; buf[1]=' ';

buf[2]=(w00)/100; buf[3]=(w0)/10; buf[4]=(w); DispLCD(buf,2); showfu(); break; case 3: //ShowYaLi();

buf[0]=(w000)/1000; buf[1]=(w00)/100; buf[2]=(w0)/10; buf[3]=' ';

buf[4]=(w); DispLCD(buf,3); showniu(); break;

default: break; } } }

㈡液晶显示模块KS0108.c

#include \

7

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

#include /*

液晶点阵显示试验 -128*64,控制器KS0108 试验准备:将拨码开关S1和S2置于ON位置. */

#define LCD_DATA P2 #define LCD_RS P30 #define LCD_RW P31 #define LCD_E P32 #define LCD_CS1 P34 #define LCD_CS2 P33 #define LCD_RST P35

void Delay1ms(unsigned char);

char code screen[]={}; //江苏大学计算机学院 /*-- 宽度x高度=128x64 --*/

char code screen1[]={}; //2010单片机课程设计 /*-- 宽度x高度=128x64 --*/

char code screen2[]={}; //液晶点阵显示屏程序设计

char code screen3[]={}; //作者姓名:宗慧 ;班级:通信0902;学号:3090601035; #define SELECTCS 0

void LCD_WaitReady1(void) //判断LCD控制芯片KS0108是否忙 {

LCD_DATA=0xff; _nop_();

LCD_CS1=SELECTCS; //前64列 LCD_RW=1; //读 LCD_RS=0;

LCD_E=1; //读写使能有效 while (LCD_DATA&0x80); LCD_CS1=!SELECTCS; }

void LCD_WaitReady2(void) //判断LCD控制芯片KS0108是否忙 {

LCD_DATA=0xff; _nop_();

LCD_CS2=SELECTCS; //后64列 LCD_RW=1; //读 LCD_RS=0;

LCD_E=1; //读写使能有效 while (LCD_DATA&0x80); LCD_CS2=!SELECTCS; }

void LCD_WriteCommand1(char ch) //向LCD控制芯片KS0108发送控制命令 {

8

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

LCD_WaitReady1(); LCD_CS1=SELECTCS; LCD_RW=0; LCD_RS=0; LCD_DATA=ch; LCD_E=1; LCD_E=0;

LCD_CS1=!SELECTCS; }

void LCD_WriteCommand2(char ch) //向LCD控制芯片KS0108发送控制命令 {

LCD_WaitReady2(); LCD_CS2=SELECTCS; LCD_RW=0; LCD_RS=0; LCD_DATA=ch; LCD_E=1; LCD_E=0;

LCD_CS2=!SELECTCS; }

void LCD_WriteData1(char ch) //向LCD控制芯片KS0108发送数据命令 {

LCD_WaitReady1(); LCD_CS1=SELECTCS; LCD_RW=0; LCD_RS=1; LCD_DATA=ch; LCD_E=1; LCD_E=0;

LCD_CS1=!SELECTCS; }

void LCD_WriteData2(char ch) //向LCD控制芯片KS0108发送数据命令 {

LCD_WaitReady2(); LCD_CS2=SELECTCS; LCD_RW=0; LCD_RS=1; LCD_DATA=ch; LCD_E=1; LCD_E=0;

LCD_CS2=!SELECTCS; }

void LCD_WriteHZ(char x,char y,char *Dat) //显示16*16点阵汉字 {

9

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

char i;

for (i=0;i<32;i++) {

if ((x+i)<64) //x代表列,显示在左半屏 {

LCD_WriteCommand1(0xB8+y+i/16); LCD_WriteCommand1(0x40+x+i); LCD_WriteData1(Dat[i]); } else {

LCD_WriteCommand2(0xB8+y+i/16); //因为一个字占16行,0xb8表示0页 LCD_WriteCommand2(0x40+x-64+i); //因为一个字占16列,0x40表示0列 LCD_WriteData2(Dat[i]); } } }

void LCD_WriteSZ(char x,char y,char *Dat) //显示16*8点阵数字 {

char i;

for (i=0;i<16;i++) {

if ((x+i%8)<64) //x代表列, 一个数字占8列,显示在左半屏 {

LCD_WriteCommand1(0xB8+y+i/8); //设置页地址 y表示页

LCD_WriteCommand1(0x40+x+i%8); //设置列地址 x表示列,一个数字占8列 LCD_WriteData1(Dat[i]); } else {

LCD_WriteCommand2(0xB8+y+i/8);

LCD_WriteCommand2(0x40+x-64+i%8); //减去64列,表示写在右半屏 LCD_WriteData2(Dat[i]); } } }

void InitLCD(void) //初始化LCD {

char i,j;

LCD_RST=0; //正常状态 Delay1ms(1);

LCD_RST=1; //正处于复位初始化状态

LCD_WriteCommand1(0xc0); //设置起始行 LCD_WriteCommand2(0xc0); //设置起始行

10

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

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); } }

void DispBmp(char *buf) //显示一幅位图 {

int i,j;

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]); LCD_WriteCommand2(0xB8+j); LCD_WriteCommand2(0x40); for (i=0;i<64;i++)

LCD_WriteData2(buf[(j*2+1)*64+i]); } }

void DispBmpLeft(char *buf) //显示一幅位图 {

int i,j,k;

for (k=0;k<128;k++) {

for (j=0;j<8;j++) //显示位图 {

LCD_WriteCommand1(0xB8+j); LCD_WriteCommand1(0x40);

for (i=0;i<64;i++) //左移 {

if((i+k)<128)

LCD_WriteData1(buf[(j*2)*64+i+k]); else

LCD_WriteData1(buf[(j*2)*64+i+k-128]);

11

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

}

LCD_WriteCommand2(0xB8+j); LCD_WriteCommand2(0x40); for (i=0;i<64;i++) {

if((i+k)<64)

LCD_WriteData2(buf[(j*2+1)*64+i+k]); else

LCD_WriteData2(buf[(j*2+1)*64+i+k-128]); } } } }

void DispBmpRight(char *buf) //显示一幅位图 {

int i,j,k;

for (k=0;k<128;k++) {

for (j=0;j<8;j++) //显示位图 {

LCD_WriteCommand1(0xB8+j); LCD_WriteCommand1(0x40); for (i=0;i<64;i++) //右移 {

if((i-k)>0)

LCD_WriteData1(buf[(j*2)*64+i-k]); else

LCD_WriteData1(buf[(j*2)*64+i-k+128]); }

LCD_WriteCommand2(0xB8+j); LCD_WriteCommand2(0x40); for (i=0;i<64;i++) {

if((i-k)>-64)

LCD_WriteData2(buf[(j*2+1)*64+i-k]); else

LCD_WriteData2(buf[(j*2+1)*64+i-k+128]); } } } }

char code zero[]={ }; //0 char code one[]={ }; //1 char code two[]={ }; //2

12

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

char code three[]={}; //3 char code four[]={ }; //4 char code five[]={ }; //5 char code six[]={ }; //6 char code seven[]={ }; //7 char code eight[]={ }; //8 char code nine[]={ }; //9

char code maohao[]={ }; //冒号 char code dot[]={ }; //点 char code wen[]={ }; //温 char code du[]={ }; //度 char code dian[]={ };//电 char code ya[]={ };//压 char code li[]={ }; //力 char code C[]={ }; //℃ char code N[]={ }; //N char code hao[]={ }; //m char code V[]={ }; //V

char code screen4[]={ }; //请选择:1.温度;2.电;3.压力; char code jiang[]={};//江 char code su[]={};//苏 char code da[]={};//大 char code xue[]={};//学 char code huan[]={};//欢 char code ying[]={};//迎 char code nin[]={};//您

char code gantanhao[]={};//!

void DispLCD(char *DispBuf,char num) {

int i;

for(i=0;i<5;i++) {

if((num==1)&&(i==2)) {

LCD_WriteSZ(56+8*i,3,dot); Delay1ms(100); i++; }

if((num==2)&&(i==1)) {

LCD_WriteSZ(56+8*i,3,dot); Delay1ms(100); i++; }

13

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

if((num==3)&&(i==3)) {

LCD_WriteSZ(56+8*i,3,dot); Delay1ms(100); i++; }

switch(DispBuf[i]) {

case 0:

LCD_WriteSZ(56+8*i,3,zero); Delay1ms(100);break; case 1:

LCD_WriteSZ(56+8*i,3,one); Delay1ms(100);break; case 2:

LCD_WriteSZ(56+8*i,3,two); Delay1ms(100);break; case 3:

LCD_WriteSZ(56+8*i,3,three); Delay1ms(100);break; case 4:

LCD_WriteSZ(56+8*i,3,four); Delay1ms(100);break; case '5':

LCD_WriteSZ(56+8*i,3,five); Delay1ms(100);break; case 6:

LCD_WriteSZ(56+8*i,3,six); Delay1ms(100);break; case 7:

LCD_WriteSZ(56+8*i,3,seven); Delay1ms(100);break; case 8:

LCD_WriteSZ(56+8*i,3,eight); Delay1ms(100);break; case 9:

LCD_WriteSZ(56+8*i,3,nine); Delay1ms(100);break; /*case ':':

LCD_WriteSZ(48+8*i,3,maohao); Delay1ms(100);break; case '.':

LCD_WriteSZ(48+8*i,3,dot); Delay1ms(100);break;*/

14

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

default: break; } } }

void Delay1s(unsigned char T); void TestLCD(void) {

char i; InitLCD();

DispBmp(screen); Delay1s(1);

for (i=0;i<64;i++) {

Delay1ms(100);

LCD_WriteCommand1(0xc0+id); //设置起始行,实现向上滚动 LCD_WriteCommand2(0xc0+id); }

Delay1s(3); DispBmp(screen1); Delay1s(5);

for (i=63;i>=0;i--) {

Delay1ms(10);

LCD_WriteCommand1(0xc0+id); //设置起始行,实现向下滚动 LCD_WriteCommand2(0xc0+id); }

Delay1s(3);

DispBmpRight(screen2); Delay1s(6);

DispBmpLeft(screen3); Delay1s(6); InitLCD();

LCD_WriteHZ(0,3,jiang); //显示16*16点阵汉字'江' Delay1ms(100);

LCD_WriteHZ(16,3,su); //显示16*16点阵汉字'苏' Delay1ms(100);

LCD_WriteHZ(32,3,da); //显示16*16点阵汉字'大' Delay1ms(100);

LCD_WriteHZ(48,3,xue); //显示16*16点阵汉字'学' Delay1ms(100);

LCD_WriteHZ(64,3,huan); //显示16*16点阵汉字'欢' Delay1ms(100);

LCD_WriteHZ(80,3,ying); //显示16*16点阵汉字'迎'

15

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

Delay1ms(100);

LCD_WriteHZ(96,3,nin); //显示16*16点阵汉字'您' Delay1ms(100);

LCD_WriteHZ(112,3,gantanhao); //显示16*16点阵汉字'!' Delay1s(5);

DispBmp(screen4); Delay1s(3); }

void ShowWenDu(void) {

InitLCD();

LCD_WriteHZ(16,3,wen); Delay1ms(100);

LCD_WriteHZ(32,3,du); Delay1ms(100);

LCD_WriteSZ(48,3,maohao); Delay1ms(100); }

void ShowDianYa(void) {

InitLCD();

LCD_WriteHZ(16,3,dian); Delay1ms(100);

LCD_WriteHZ(32,3,ya); Delay1ms(100);

LCD_WriteSZ(48,3,maohao); Delay1ms(100); }

void ShowYaLi(void) {

InitLCD();

LCD_WriteHZ(16,3,ya); Delay1ms(100); LCD_WriteHZ(32,3,li); Delay1ms(100);

LCD_WriteSZ(48,3,maohao); Delay1ms(100); }

void showniu(void) {

LCD_WriteSZ(96,3,N); Delay1ms(100); }

void showfu(void)

16

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

{

LCD_WriteSZ(96,3,hao); Delay1ms(100);

LCD_WriteSZ(104,3,V); Delay1ms(100); }

void showsheshidu(void) {

LCD_WriteSZ(96,3,C); Delay1ms(100); }

㈢模数转换模块ADC.c

#include \ #include /*

压力应变片ADC试验

运行此程序,压力值将在数码管上显示.用手触摸应变片 观察压力变化. */

#define MUX_TEMP 0x08 #define MUX_VOLT 0x01 #define MUX_PRESS 0x02

unsigned int idata Temp,Press,Volt; unsigned char idata mux_select;

sfr16 ADC0=0xbe; // ADC0 data void init_adc(void) {

ADC0CN=0x81; // ADC0 enabled; normal tracking

// mode; ADC0 conversions are initiated // on write to AD0BUSY; ADC0 data is // left-justified

REF0CN=0x07; // enable temp sensor, on-chip VREF, // and VREF output buffer mux_select=MUX_TEMP; // CPU on-chip temp sensor AMX0SL=MUX_TEMP;

ADC0CF=(SYSCLK/2500000) << 3; // ADC conversion clock = 2.5MHz //ADC0CF |= 0x01; // PGA gain = 2

EIE2&=~0x02; // 禁止ADC0转换结束中断 disable ADC0 EOC interrupt

EIE1&=~0x04; // 禁止ADC0窗口比较中断 disable ADC0 window compare interrupt }

// On-chip temperature

17

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

// AN1. 电位器 // AN2. 应变片

void read_analog_inputs(void) {

long temp_long;

AD0INT=0; // clear conversion complete indicator AD0BUSY=1; // initiate conversion

while(AD0INT==0); // wait for conversion complete switch(mux_select) {

case MUX_TEMP:

temp_long=ADC0-42380/2;

temp_long=(temp_long*200L)/156; Temp=temp_long;

AMX0SL=MUX_VOLT; // Select AIN1 for next read mux_select=MUX_VOLT; break;

case MUX_VOLT: temp_long=ADC0;

Volt=24*temp_long/655;

AMX0SL=MUX_PRESS; // Select on-chip temp sensor mux_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; break; default:

AMX0SL=MUX_TEMP; mux_select=MUX_TEMP; break; } }

unsigned int GetADCValue(char No) {

read_analog_inputs(); read_analog_inputs(); read_analog_inputs();

18

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

switch (No) {

case 1:

return Temp; case 2:

return Volt; case 3:

if (Press<10) Press=0; return Press; } }

Test7279部分

#include \ #include

sbit HD7279_DAT=P1^7; sbit HD7279_CLK=P1^6;

#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_CLK=0 //HD7279测试/演示程序 //I/O口初始化

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); //延时50μ for (i=0;i<8;i++) {

if (ch&0x80) //输出7位到HD7279A的DATA端 {

Set7279DAT; } else {

Clr7279DAT; }

Set7279CLK; //置CLK高电平

19

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

ch=ch<<1; //待发数据左移 Delay1us(8); //延时8μ

Clr7279CLK; //置CLK低电平 Delay1us(8); //延时8μ }

Clr7279DAT; //发送完毕,DATA端置低,返回 }

unsigned char Receive7279Byte(void) {

unsigned char i,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端重新置成低电平(输出状态) return ch; }

void FlashLED(unsigned char No) {

char i;

Send7279Byte(0x88); //发闪烁指令 i=0x1; while (No) {

i=i<<1; No--; }

Send7279Byte(~i); //1闪烁

NOSELECT7279; //置CS高电平 } /*

void BlankLED(unsigned char ch) {

Send7279Byte(0x98); file://发消隐指令 Send7279Byte(ch); file://1-显示 0-消隐

20

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

NOSELECT7279; file://置CS高电平 } */

void MoveLeft(void) {

Send7279Byte(0xA1); //发左移指令 NOSELECT7279; //置CS高电平 }

void MoveRight(void) {

Send7279Byte(0xA0); //发右移指令 NOSELECT7279; //置CS高电平 }

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}; /*

; b6 ; ---- ; b1| b0 |b5

; ---- small ; b2| b3 |b4 ; ---- .b7 */

void DispLED(char *DispBuf,char ShowDot)//ShowDot 显示小数点位 {

char i,ch; ShowDot--; for (i=0;i<6;i++) {

ch=DispBuf[i];

if ((ch>='a') && (ch<='f')) {

ch-='a';ch+=0xa; }

if ((ch>='A') && (ch<='F')) {

ch-='A';ch+=0xa; }

Send7279Byte(0x90+5-i); //不译码 if (ch==' ')

21

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

Send7279Byte(0x00); else

if (ch=='-')

Send7279Byte(0x01); else {

if (ShowDot==i)

Send7279Byte(0x80|BdSeg[ch&0x0f]); else

Send7279Byte(BdSeg[ch&0x0f]); } }

NOSELECT7279; //置CS高电平 }

char GetKeyValue(void) {

char KeyValue;

if (CPT1CN&0x40) return -1; //无键按下 Send7279Byte(0x15); //发读键盘指令 KeyValue=Receive7279Byte();

NOSELECT7279; //置CS高电平 return KeyValue; }

void WaitKeyOff(void) {

while (!(CPT1CN&0x40)); }

void Test7279(bit LoopFlag) {

char i,KeyValue;

Delay1ms(25); //等待25ms复位时间 Send7279Byte(0xA4); //发复位指令 NOSELECT7279; //置CS高电平 if (LoopFlag==0) return;

DispLED(\ //显示123456 for (i=0;i<8;i++) {

Delay1s(1); MoveLeft(); }

DispLED(\显示123456 DispLED(\ //显示123456 DispLED(\ //显示123456 for (i=0;i<6;i++)

22

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

{

Delay1s(1); MoveRight(); }

DispLED(\ //显示123456 FlashLED(0); //第一位闪烁 Delay1s(1);

FlashLED(1); //第二位闪烁 Delay1s(1);

FlashLED(8);//关闪烁

//BlankLED(0x23); //注意:执行消隐后,键盘输入中断口不能恢复. for (;;) {

KeyValue=GetKeyValue(); if(KeyValue!=-1) {

Send7279Byte(0xC8); //发送键码值,按方式1译码下载显示 Send7279Byte(KeyValue);

NOSELECT7279; //置CS高电平 WaitKeyOff(); } } }

五.调试过程

将如下源文件c8051F020.h,main.c, ADC.c,KS0108.c,test7279.c加入到开发工具中,调试程序,并下载到单片机中运行,首先有“江苏大学计算机学院”一行字向上滚动,然后显示“2010年单片机课程设计”一行向下滚动,再显示“液晶点阵显示屏程序设计”向右滚动,再显示“姓名:宗慧;班级:通信 0902; 学号:3090601035;”向左滚动。当这些字显示完毕后,最后显示请选择:1.温度;2.电;3.压力;

在程序设计和调试过程中,遇到和解决了以下几个问题:

1)一开始在取模,我在文字输入区输入”江苏大学计算机学院“后,得到的点阵是一个字一个字的,并不像程序中原来的模板那样是一大串的,后来经过讨论和研究,应该将文字以128x64的图片的形式进行点阵输出。但是在使用图片时,我犯了一个错误,就是在截完图之后,我是先将它粘贴在QQ的对话框里,再进行另存,但是后果是出现了乱码,之后我直接在写完之后就保存为图片,再在软件中打开,就不会出现这种情况。之后我自己认为可能是粘贴到QQ中之后意义就不同了,它将是对这一整幅画进行点阵处理而不是那几个字,所以才会出现乱码。

六.运行结果

第一页从下到上滚动显示:江苏大学计算机学院

23

《C8051F单片机原理及应用》课程设计——日历时钟与键盘显示程序设计

第二页从下到上滚动显示:2010年单片机课程设计 第三页向右滚动显示:液晶点阵显示屏程序设计

第四页向左滚动显示:姓名:宗慧;班级:通信 0902; 学号:3090601035; 第五页显示:请选择:1.温度;2.电;3.压力; 按“1”显示温度:****℃ ; 按“2”显示电压:****mV; 按“3”显示压力:****N; 按“4”返回原画面。

七.心得体会

将平时学习到的单片机和C语言知识运用到实验中,使得我们对所掌握的单片机和C语言知识的一次很好的巩固和加深。不但如此,我们还收获了其他的一些平时不知道的内容。比如:对字模提取的软件的使用,一开始不了解如何取模,后来发现了取模软件,通过将一行字编辑为以“bmp\结尾的图片,通过在取模软件中打开图片,然后就生成一幅我们所需要的图片的字模。虽然程序老师已经给出,但是还是需要我们施加一些整改,在不断地报错又不断地修改中,最终还是将程序运行成功。虽然程序中我还有很多不了解和不懂,在老师的最终提问的问题中还有很多不会,但是我个人觉得我的这次课程设计的收获还是不错的,获得了不少知识。

24

本文来源:https://www.bwwdw.com/article/sah6.html

Top