基于8155的LCD显示电子码表设计

51单片机软件设计报告

——基于8155的LCD显示电子码表设计一、实验目的

本次课程设计是基于51单片机在理论课程的基础上,通过电路设计、理论计算、实际编程、调试、测试、分析查找故障,解决在实际设计中的问题,

使设计好的电路能正常工作。学习在理论课程的基础上,重点培养动手能力,

通过电路设计、理论计算、实际编程、调试、测试、分析查找故障,解决在实

际设计中的问题。学习Proteus软件的MCS51单片机仿真。

学习和完成的任务:

1.实验板的原理图结构研究

2.51单片机的编程技术

二、实验设备

(1)计算机一台

(2)Proteus软件平台

(3)KeiuVision软件平台

三、实验内容

电子码表类:基于8155的LCD显示电子码表设计

基本要求:

1 设计秒表功能,精度为0。01秒。

2 可同时记录和存储10个秒表数据。(连续记录并显示已存储记录数)

3 秒表记录数据查询和清除功能。

发挥部分:

1 外部脉冲数据记录(一信道,快速脉冲信号)。

2 外部记录触发信号输入(二信道,慢速存储信号)

3 自动存储和手动回放。

动态显示格式:

自定

四、实验原理

本次课程设计是在理论课程的基础上,目的在于培养我们的动手能力,通过电路设计、理论计算、实际编程、调试、测试、分析查找故障,解决在实际设计中的问题,使设计好的电路能正常工作,并可能结合实际的实验板进行下载测试。在此基础上根据实验大纲的要求,按“51单片机课程设计选题表”每人一题(随机分配),实现其功能。

单片机微型计算机简称单片机,是指在一块芯片体上集成了中央处理器CPU、随机存储器RAM、程序存储器ROM或EPROM、定时器/计数器、中断控制器以及串行和并行I/O 接口等部件,构成一个完整的微型计算机。目前,新型单片机内还有A/D及D/A转换器、高速输入/输出部件、DMA通道、浮点运算等特殊功能部件。由于它的结构和指令功能都是按工业控制设计要求设计的,特别适用于工业控制及其数据处理场合,因此,确切的称谓是微控制器,单片机只是习惯称呼。

(1)单片机的特点

1)有优异的性能价值比。

2)集成度高、体积小、有很高的可靠性。单片机把各个功能部件集成在一块芯片上,内部采用总线结构,减少了各芯片之间的连线,大大提高了单片机的可靠性与抗干扰能力。另外,其体积小,对于强磁场环境易于采取措施,适合于恶劣环境下工作;也易于产品化。

3)控制功能强。为了满足工业控制的要求,一般单片机的指令系统中均有及其丰富的转移指令、I/O口逻辑操作及位处理指令。一般来说,单片机的逻辑控制功能及运行速度高于同意档次的微机。

4)单片机的系统扩展和系统配置都比较典型、规范,而且非常容易构成各种规模的应用系统。

(2)单片机并行I/O接口的扩展

单片机与外部交换信息是通过I/O接口电路来实现的。A T89C51单片机本身有4个8位的并行I/O口P0-P3,但实际使用时往往再增加些I/O口,以便与外部设备交换数据。AT89C51单片机外部RAM和扩展I/O接口是统一编址的。用户可以把外部64KB RAM空间的一部分作为扩展I/O接口地址空间,每一个I/O接口相当于一个RAM存储单元,访问外部RAM存储单元就像访问外部I/O接口,即用“MOVX”指令对扩展I/O接口进行输入输出操作。

查询式键盘属于独立式键盘,键盘的各个按键之间彼此是独立的且是最简单的键盘电路。每个键地接入一根数据输入线。如图所示。注意:由于每一个按键均需要一根I/O口线,当键盘按键数量比较多时,需要的I/O口线也较多,因此独立式键盘只适合于按键较少的应用场合。一般情况下,按键数等于占用I/O端口数。

查询式键盘的结构图如图所示:

图2-5 查询式键盘的接口电路

查询式键盘可以工作在多种方式下,中断方式、程序查询方式、定时查询发送和中断查询方式。

在中断模式下,按键的数量受到外部中断源的限制。在有特殊需要的场合,还可以借用内部的定时器中断。所以在这种模式下,按键的数目小于外部中断源和单片机定时器数量之和。

程序查询和定时查询类似,都是通过读I/O状态,当有键被按下时相应的I/O口线变为低电平,而未被按下的键对应的I/O口线保持为高电平,这样通过读I/O口状态可判断是否有键按下和哪一个键被按下。

1.键盘定义

K1:开始、暂停记时

K2:记录数据

K3:计数器清零

K4:查看存储数据

2.流程图

(1)主流程图

(2)扫描键盘流程图

3.主程序

/***********************基于8155的LCD显示电子表设计************************************************/

#include

#include

#include

/*******************************************宏定义

***************************************************/

#define uint unsigned int

#define uchar unsigned char

/*******************************************定义8155地址

***********************************************/

#define COM8155 XBYTE[0X7FF8] //8155的命令口

#define PA8155 XBYTE[0X7FF9] //8155的PA

#define PB8155 XBYTE[0X7FFA] //8155的PB

#define PC8155 XBYTE[0X7FFB] //8155的PC

/*************************************************************延迟****************************************/

void delay_ms(uint z)

{

uint y;

for(;z>0;z--)

for(y=110;y>0;y--);

}

/*************************************************************向8155的输出端写入数据****************************************/

void write_com(unsigned char com)

PB8155=0x00;

PA8155=com ;

delay_ms(2);

PB8155=0x02;

delay_ms(2);

PB8155=0x00;

}

void write_data(unsigned char da)

{

PB8155=0x01;

PA8155=da ;

delay_ms(2);

PB8155=0x03;

delay_ms(2);

PB8155=0x01;

}

void write_str(unsigned char *str,unsigned char num) {

unsigned char i;

for(i=0;i

write_data(str[i]);

void lcd_init()

{

PB8155=0x00;

write_com(0x38);//设置16X2 5X7点阵

write_com(0x0c);//开显示不显示光标

write_com(0x06);//写一个字符后地址指针加1

write_com(0x01);//lcd清屏

}

void lcd_pos(unsigned char X,unsigned char Y) //第一行和第二行

{

unsigned char pos;

if(X==0) X=0x80;

if(X==1) X=0x80+0x40;

pos=X+Y;

write_com(pos);

}

/*******************************************初始化程序

***********************************************/

void initial()

{

COM8155=0x03;

lcd_init(); //lcd初始化

}

/*******************************************定义lcd显示的码值**************************************/

uchar dis_buf[8]={0}; //lcd显示缓存

/*******************************************定义系统变量

***************************************************/

bit flag=0; //计时状态标志位

bit flag1=0,flag2=0,flag3=0,flag4=0; //按键状态标志位

uchar num,second,minute,hour; //秒表变量

uchar count=0; //计数器变量

uchar num_store[10],second_store[10],minute_store[10]; //储存秒表数据变量

uchar x; //记录数据计数器

/*******************************************键盘扫描程序

***********************************************/

void keyscan()

{

uchar m;

m=PC8155;

m=m&0x0f;

if(m!=0x0f)

{

delay_ms(20); //延时消抖

m=PC8155;

m&=0x0f;

if(m!=0x0f) //有键被按下

{

m=PC8155;

m&=0x0f;

switch(m)

{

case(0x0e):flag1=1;break; //按键一被按下,其标志位置1

case(0x0d):flag2=1;break; //按键二被按下,其标志位置1

case(0x0b):flag3=1;break; //按键三被按下,其标志位置1

case(0x07):flag4=1;break; //按键四被按下,其标志位置1

}

}

while(PC8155!=0x0f); //判断键是否松开

}

if(flag1==1) //按键一被按下,开始计时或停止计时

{

TR0=~TR0; //计时开关取反

flag=0;

flag1=0; //按键一标志位清零

}

if(flag2==1) //按键二被按下

{

if(TR0==1) //秒表计时,记录数据

{

if(x<10)

{

minute_store[x]=minute;

second_store[x]=second;

num_store[x]=num; //记录秒表值

x++; //计数器加1

}

}

else //秒表停止,删除正在查看被记录的数据

{

if(flag==1)

{

minute_store[count-1]=0;

second_store[count-1]=0;

num_store[count-1]=0; //删除当前查看的记录数据

}

}

flag2=0; //按键二标志位清零

}

if(flag3==1) //按键三被按下,计时数据清零

{

if(TR0==0)

{

num=0;

second=0;

minute=0;

flag=0; //数据清零

}

flag3=0; //按键三标志位清零

}

if(flag4==1) //按键四被按下,查询记录的数据

{

if(TR0==0) //判断计时状态

{

flag=1;

count++; //计数器加1,查看下一个被记录的数据

if(count>=11) //判断计数器是否超过范围

count=1;

}

flag4=0; //按键四标志位清零

}

}

void trans_data()

{

if(flag==0) //判断秒表是否处于计时状态

{

if(hour==0&&minute<59)

{

dis_buf[0]=minute/10;

dis_buf[1]=minute%10;

dis_buf[3]=second/10;

dis_buf[4]=second%10;

dis_buf[6]=num/10;

dis_buf[7]=num%10; //计时小于1小时,数据转换

}

else

{

dis_buf[0]=hour/10;

dis_buf[1]=hour%10;

dis_buf[3]=minute/10;

dis_buf[4]=minute%10;

dis_buf[6]=second/10;

dis_buf[7]=second%10; //计时超过1小时,数据转换

}

}

else

{

dis_buf[0]=minute_store[count-1]/10;

dis_buf[1]=minute_store[count-1]%10;

dis_buf[3]=second_store[count-1]/10;

dis_buf[4]=second_store[count-1]%10;

dis_buf[6]=num_store[count-1]/10;

dis_buf[7]=num_store[count-1]%10; //对记录数据进行转换

}

}

/******************************************定时器*初始化程序***********************************************/

void init()

{

TMOD=0x11; //定义定时器的工作方式

TH0=(65536-10000)/256;

TL0=(65536-10000)%256; //给T0装初值

//TH1=(65536-100)/256;

//TL1=(65536-100)%256; //给T1装初值

ET0=1; //开T0的中断

//ET1=1; //开T1的中断

EA=1; //开总中断

TR0=0; //关闭T0

TR1=1; //开T0

hour=0;

minute=0;

second=0;

num=0; //秒表变量初始化}

/*******************************************主程序***************************************************/

void main()

{

initial();

init();

while(1)

{

keyscan();

trans_data();

lcd_pos(0,0x03);

write_data(dis_buf[0]+48);

write_data(dis_buf[1]+48);

write_data(':');

write_data(dis_buf[3]+48);

write_data(dis_buf[4]+48);

write_data(':');

write_data(dis_buf[6]+48);

write_data(dis_buf[7]+48);

}

}

/*******************************************T0中断程序

*************************************************/

void timer0() interrupt 1

{

TH0=(65536-10000)/256;

TL0=(65536-10000)%256; //给T0装初值

num++; //0.01秒到,计数器加1

if(num==100) //判断1s时间是否到

{ //1s到,num清零

num=0; //计数

second++; //秒加1,

if(second==60) //判断1分钟是否到

{

second=0; //秒清零

minute++; //分钟加1

if(minute==60) //判断1小时是否到

{

minute=0;

hour++;

if(hour==24)

hour=0;

}

}

}

}

五、实验过程及其记录

1.实验连接图

2.运行

3.K1闭合,开始计时,

4.K2点击两次记录两次数据,K1暂停计时

5.K4查看记录数据

相关主题
相关文档
最新文档