基于MCS51单片机的计数器及出租车计费器设计.docx

上传人:b****3 文档编号:863779 上传时间:2022-10-13 格式:DOCX 页数:15 大小:330.40KB
下载 相关 举报
基于MCS51单片机的计数器及出租车计费器设计.docx_第1页
第1页 / 共15页
基于MCS51单片机的计数器及出租车计费器设计.docx_第2页
第2页 / 共15页
基于MCS51单片机的计数器及出租车计费器设计.docx_第3页
第3页 / 共15页
基于MCS51单片机的计数器及出租车计费器设计.docx_第4页
第4页 / 共15页
基于MCS51单片机的计数器及出租车计费器设计.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

基于MCS51单片机的计数器及出租车计费器设计.docx

《基于MCS51单片机的计数器及出租车计费器设计.docx》由会员分享,可在线阅读,更多相关《基于MCS51单片机的计数器及出租车计费器设计.docx(15页珍藏版)》请在冰豆网上搜索。

基于MCS51单片机的计数器及出租车计费器设计.docx

基于MCS51单片机的计数器及出租车计费器设计

课程名称:

单片机课程设计

设计题目:

基于外部脉冲自动计数的出租车计费器设计

一、设计任务:

1.1外部脉冲自动计数,自动显示。

1.1.1设计一个255计数器:

0-255计数,计满后自动清0,重新计数(在数码管中显示)。

1.1.2设计一个50000计数器:

0-50000计数,计满后自动清0,重新计数(在数码管中显示)。

1.2设计一个出租车计费系统:

起步价为5元(2km以内),2km后,0.8元/0.5km;要求每500m刷新计费一次,在6位数码管中,前3位显示数码管显示里程数,后3位数码管显示价钱(角,元,十元,百元)

二、设计思路及源程序:

2.1、0-255计数器设计:

设计思路:

十进制数0-255可用8位二进制数来表示,定时器/计数器的四种工作方式均可实现0-255的计数功能(工作方式3只有定时器0可以实现)。

在此为了设计方便,我采用定时器/计数器T1工作方式2(可自动重装初值),外部脉冲由AT89S51的P3.5管脚引入,每来一个外部脉冲,计数器T1计数加一。

由此,只需对TL1的计数值进行相应的二进制---十进制转换,通过算法进行运算可得到百位,十位,各位,并存入相应变量中(对C51语言而言)。

选通相应数码管,再将各位数字的相应显示编码输入即可在数码管上显示计数结果。

源程序:

/***********************************************************************************程序功能描述:

计数器接受外部脉冲实现自动计数,计数范围0-255

计满数后自动清零,再重新循环计数。

说明:

主要硬件设备:

6位共阳极数码管,晶振频率:

12MHZ

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

#include"reg51.h"//C51头文件

unsignedcharcodeled_num[10]={0xc0,0xf9,0xa4,0xb0,0x99,

0x92,0x82,0xf8,0x80,0x90};//数码管显示数字的十六进制代码

unsignedcharcodeled_bit[6]={0xf8,0xf9,0xfa,0xfb,0xfc,0xfd};//位选代码,注意语句后的分号不能丢

/*********************************************************************************函数名称:

延时子程序

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

voiddelay(unsignedintdat)

{

unsignedintk,j;//定义局部无符号整形变量

for(k=0;k

{

for(j=0;j<2000;j++);//空循环,延时语句

}

}

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

********函数名称:

计数器初始设置函数

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

voidinit_timer1(void)

{

TMOD=0x60;//设置为计数器模式,工作方式2,自动重装初值

TH1=0x00;//计数器初值设为0

TL1=0x00;

TR1=1;//开启计数器

}

/**********************************************************************************函数名称:

主函数

说明:

先将计数器1的TL1中数据百位、十位、个位分离,并存于数组led[]中,再将对应数字的编码送入数码器显示出来

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

voidmain(void)

{

unsignedchari,j;

unsignedcharled[3];//用来存放要显示数字的百、十和个位上的数字

init_timer1();//计数器初始化

while

(1)

{

led[0]=TL1%10;//取个位数字存于字符数组

led[1]=TL1%100/10;//取十位数字

led[2]=TL1/100;//取百位数字

for(j=0;j<10;j++)//在显示上消耗时间,使三个数码管显示不中断.

{

for(i=0;i<3;i++)

{

P2=led_bit[i];//把led[i]表示的位置的位选通

P0=led_num[led[i]];//把相应位置的数显式出来

delay

(1);//延时

}

}

}

}

Proteus仿真效果图

图2.1、255计数器仿真效果图

 

2.2、0-50000计数器设计:

设计思路:

0-50000计数器设计方法与0-255计数器设计方法有很多地方相似,主要在一些地方作了一些技术处理。

由于十进制数0-50000用8位二进制已不能表示出来,在此只能选择定时器/计数器工作方式1。

在用16位计数器处理0-50000计数时,我们既可用单纯的定时器/计数器模式,也可采用定时器/计数器中断模式。

中断模式的优越之处在于它可在计数溢出时打断主程序的执行,通过在中断服务程序中编写显示清零程序,可以很精确的实现0-50000的计数。

而用定时器/计数器模式时有可能在计数满50000时显示不能及时清零,造成这种现象的原因主要是外部脉冲频率太大,程序来不及对每个脉冲进行处理。

因此非中断模式要受到外部脉冲的限制,考虑到现实中有些情况下脉冲频率也可能会很大,故本程序及下面的出租车计费器均采用中断模式,把计数清零语句放到中断服务程序中,以保证能精确实现0-50000的计数。

源程序:

/***************************************************************************************程序功能:

此程序为计数器1接受外部脉冲实现0-50000自动计数,计数快慢由外部脉冲的大小决定

说明:

主要硬件设备:

6位共阳极数码管。

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

#include"reg51.h"//头文件

unsignedcharcodeled_num[10]={0xc0,0xf9,0xa4,0xb0,0x99,

0x92,0x82,0xf8,0x80,0x90};//数码管显示数字的十六进制代码

unsignedcharcodeled_bit[6]={0xf8,0xf9,0xfa,0xfb,0xfc,0xfd};//位选代码

/*********************************************************************************函数名称:

延时子程序函数

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

voiddelay(unsignedintdat)

{

unsignedintk,j;

for(k=0;k

{

for(j=0;j<2000;j++);//空循环,延时语句

}

}

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

*******函数名称:

定时器1初始设置函数

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

voidinit_timer1(void)

{

TMOD=0x50;//设置为计数器模式,工作方式1

TH1=0x00;//计数器初值设为0

TL1=0x00;

TR1=1;//开启计数器

}

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

*********函数名称:

主函数

说明:

当第50001个脉冲来临时将计数器清零

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

voidmain(void)

{

unsignedchari,j;//定义控制循环的变量

unsignedinttemp;//定义一个整型变量用来存储两个字节的数据

unsignedcharled[5];//用来存放要显示数字的万、千、百、十和个位init_timer1();//计数器初始化

while

(1)

{

if((TH1==0xc3)&&(TL1>=0x51))//第50001个脉冲来临时将计数器清零

{

TH1=0x00;

TL1=0x00;

}

temp=TH1;

temp=temp<<8;//将TH1中数字左移8位再赋给temp

temp=temp|TL1;//将TH1和TL1中数据合到一个整形变量temp中

led[0]=temp%10;//存取个位数字

led[1]=temp%100/10;//存取十位数字

led[2]=temp%1000/100;//存取百位数字

led[3]=temp%10000/1000;//存取千位数字

led[4]=temp/10000;//存取万位数字

for(j=0;j<10;j++)//在显示上消耗时间,使三个数码管显示不中断

{

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

{

P2=led_bit[i];//把led[i]表示的位置的位选通

P0=led_num[led[i]];//把相应位置的数显式出来

delay

(1);//延时一个微小时

}

}

}

}

Proteus仿真效果图

图2.2、50000计数器仿真效果图

2.3、出租车计费设计:

设计思路:

出租车计费器的设计可在0-50000计数器的基础上扩充改写而成。

出租车上安装有一个霍尔传感器,车子轮胎每转动一圈,霍尔传感器便产生一个脉冲。

因此计数脉冲跟轮胎有直接的对应关系,考虑到车轮是按一定的规格生产的,在此我们将车程(汽车行驶距离)与车轮的直径及计数脉冲数联系起来。

因此车程可用计数脉冲的个数表示出来,因而车程的显示可转化为计数器显示问题。

而车程与收费之间的数学关系在设计要求中已明确。

我采用6位数码管来显示车程和收费。

其中前三个数码管显示车程,后三个数码管显示收费。

特别指出最好用中断处理计数脉冲数的临界值,否则很容易不能达到预期目标。

/********

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 建筑土木

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1