基于单片机计数器及出租车计费器.docx
《基于单片机计数器及出租车计费器.docx》由会员分享,可在线阅读,更多相关《基于单片机计数器及出租车计费器.docx(34页珍藏版)》请在冰豆网上搜索。
基于单片机计数器及出租车计费器
基于MCU的计数和计程车计费器
题目:
基于MCU的计数和计程车计费器
任务:
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刷新计费一次,在8位数码管中,前3位显示数码管显示里程数,后3位数码管显示价钱(角,元,十元,百元)
硬件资源:
89S51芯片
3-8译码器74HC138
共阴极数码管
脉冲信号发生器
10K电阻若干
硬件资源介绍:
利用89S51芯片为设计的主体,通过P2口的前三位(P2.0,P2.1,P2.2)通过3-8译码器进行译码,从而控制位选,在利用P0口进行段选,从而在数码管上显示所需要的数字。
二、设计过程
1.设计255计数器
利用T1定时器的第二工作方式2,C/T为1,利用其计数功能,当计数到255后,下一位自动变成0(自动重装初值的功能)
软件设计
C语言:
#include"reg52.h"
unsignedcharcodenum_table[10]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsignedcharcodebit_table[6]={0x00,0x01,0x02,0x03,0x04,0x05};
unsignedcharnum;
voiddisplay();
voiddelay(unsignedintaa);
voidinit_timer()//进行定时器的初始化
{
TMOD=0X60;
TH1=0;
TL1=0x00;
TR1=1;
//TF1=0;
}
voidmain()
{
P2=0xff;
P0=0X00;
init_timer();
while
(1)
{
num=TL1;
display();
delay
(1);
}
}
/*----------------------------------------------------
显示函数
-------------------------------------------------------*/
voiddisplay()
{
unsignedcharx,y,z;
x=num%10;
y=(num%100)/10;
z=num/100;
P2=0x02;
P0=num_table[z];
delay
(1);
P2=0x01;
P0=num_table[y];
delay
(1);
P2=0x00;
P0=num_table[x];
delay
(1);
}
voiddelay(unsignedintaa)
{
unsignedinti,j;
for(i=0;i{
for(j=0;j<110;j++);
}
}
汇编:
ORG0000H
LJMPMAIN
ORG0030H
MAIN:
MOVTMOD,#60H;初始化
SETBTR1
MOVA,TL1
LCALLBCD
LCALLDISPLAY
LJMPMAIN
BCD:
MOVB,#64H
DIVAB
MOV72H,A
XCHA,B
MOVB,#0AH
DIVAB
MOV71H,A
MOV70H,B
RET
DISPLAY:
MOVR1,#70H;显示模块
MOVR5,#00H
LOOP1:
MOVA,R5
MOVP2,A
MOVDPTR,#TAB
MOVA,@R1
MOVCA,@A+DPTR
MOVP0,A
LCALLDELAY
INCR1
INCR5
CJNER5,#03H,LOOP1
RET
DELAY:
MOVR6,#4
D1:
MOVR7,#248
DJNZR7,$
DJNZR6,D1
RET
TAB:
DB03FH,006H,05BH,04FH,66H,6DH,7DH,007H,7FH,6FH
END
Protues仿真结果
2.0~50000计数
利用T1定时器的工作方式1进行计数,当TL1=0时表示没有有效脉冲的输入,当TL1=1时,通过间接的函数对计数进加1,同时利用动态显示的功能在数码管上显示出来。
软件设计:
C语言
#include
unsignedintcodenum_table[10]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsignedcharcodebit_table[6]={
0x00,0x01,0x02,0x03,0x04,0x05};
unsignedintnum=100;
unsignedinti,j,k,x,y,z;
voidBCD();
voiddisplay();
voiddelay(unsignedintaa)
{
unsignedchari,j;
for(i=0;i{
for(j=0;j<110;j++);
}
}
/*--------------------------------------------------
系统初始化
----------------------------------------------------*/
voidinit()
{
TMOD=0X50;
TH1=0X00;
TL1=0X00;
TR1=1;
//x=0;y=0,z=0;
//display();
while
(1)
{
if(TL1!
=0X00)
BCD();
display();
}
}
voidBCD()
{
TL1=0;
num++;
}
voiddisplay()
{
if(num==50000)
{
num=0;
}
i=num/100000;
j=num/10000%10;
k=num/1000%10;
x=num/100%10;
y=num/10%10;
z=num%10;
P2=0x05;
P0=num_table[i];
delay
(1);
P2=0x04;
P0=num_table[j];
delay
(1);
P2=0x03;
P0=num_table[k];
delay
(1);
P2=0x02;
P0=num_table[x];
delay
(1);
P2=0x01;
P0=num_table[y];
delay
(1);
P2=0x00;
P0=num_table[z];
delay
(1);
}
voidmain()
{
init();
}
汇编:
ORG0000H
LJMPMAIN
ORG0030H
MOV70H,#00H
MOV71H,#00H
MOV72H,#00H
MOV73H,#00H
MOV74H,#00H
MOV75H,#00H
MAIN:
MOVTMOD,#50H
MOVTL1,#00H
SETBTR1
LCALLDISPLAY
MOVA,TL1
JZMAIN
LCALLBCD
LJMPMAIN
DISPLAY:
MOVR1,#70H
MOVR5,#00H
LOOP1:
MOVA,R5
MOVP2,A
MOVA,@R1
MOVDPTR,#TAB
MOVCA,@A+DPTR
MOVP0,A
LCALLDELAY
INCR5
INCR1
CJNER5,#06H,LOOP1
RET
BCD:
MOVTL1,#00H
MOVR1,#70H
MOVR0,#75H
LOOP2:
MOVA,@R1
INCA
CJNEA,#0AH,LOOP4
MOV@R1,#00H
INCR1
CJNER1,#76H,LOOP2
LJMPLOOP3
LOOP4:
MOV@R1,A
LOOP3:
RET
DELAY:
MOVR6,#4
D1:
MOVR7,#248
DJNZR7,$
DJNZR6,D1
RET
TAB:
DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
PROTUES仿真结果:
3.出租车计费器
利用T1定时器的工作方式1,当TL1=0时表示没有有效脉冲的输入,当TL1=1时通过间接的函数对计数进加1,TL1清零;起步价为5元(2km以内),2km后,0.8元/0.5km;要求每500m刷新计费一次,在8位数码管中,前3位显示数码管显示里程数,后3位数码管显示价钱(角,元,十元,百元)
软件设计
C语言:
#include
unsignedcharcodetable1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
unsignedcharcodetable2[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsignedintw,x,y,z,i,j,k,km,money;
voiddelay(unsignedintaa);
voidinit();
voidBCD();
voiddisplay1();
voiddisplay2();
/*---------------------------------------------------
主函数
-----------------------------------------------------*/
voidmain()
{
init();
}
voiddelay(unsignedintaa)
{
unsignedcharm,n;
for(m=0;m{
for(n=0;n<110;n++);
}
}
/*----------------------------------------------------
初始化函数
------------------------------------------------------*/
voidinit()
{
TMOD=0X50;
TH1=0X00;
TL1=0X00;
TR1=1;
km=0;
money=50;
//display1();
//display2();
while
(1)
{
while(TL1==0X00)//动态扫描
{
display1();
display2();
}
km++;
BCD();
}
}
/*------------------------------------------------------
出租车的计费系统进行设置
--------------------------------------------------------*/
voidBCD()
{
TL1=0x00;
if(km<=20)//2KM以内起步价5元
{
money=50;
display1();
delay
(1);
display2();
}
else//2km后0.8元/0.5km且每500米计费刷新一次
{
if((km%10)%5==0)
money=money+8;
if((money/100)>9)
{
money=50;
km=0;
}
else;
display1();
delay
(1);
display2();
}
}
voiddisplay1()//显示里程
{
w=km/1000;
x=km/100%10;
y=km/10%10;
z=km%10;
P2=0x07;
P0=table2[w];
delay
(1);
P2=0x06;
P0=table2[x];
delay
(1);
P2=0x05;
P0=table1[y];//这一位后有小数点
delay
(1);
P2=0x04;
P0=table2[z];
delay
(1);
}
voiddisplay2()//显示费用
{
i=money/100;
j=money/10%10;
k=money%10;
P2=0x02;
P0=table2[i];
delay
(1);
P2=0x01;
P0=table1[j];//这一位后有小数点
delay
(1);
P2=0x00;
P0=table2[k];
delay
(1);
}
汇编:
ORG0000H
SJMPMAIN
ORG0030H
MOV70H,#00H
MOV71H,#00H
MOV72H,#00H
MOV73H,#00H
MOV74H,#00H
MOV75H,#00H
MAIN:
MOVTMOD,#50H
MOVTL1,#00H
SETBTR1
LOOP:
MOVR3,#00H
MOVA,TL1
JZLOOP
LCALLBCD
LCALLMOMEY
LCALLDISPLAY
BCD:
INCR3
MOVTL1,#00H
MOVA,R3
MOVB,#0AH
DIVAB
MOV70H,B
ZZZ:
CJNEA,#0AH,LOOP1
INCR4
MOVR3,#00H
MOV72H,R4
RET
LOOP1:
MOV71H,A
;SJMPBCD
RET
MONEY:
CC:
CJNER3,#14H,LOOP2
L2:
MOVA,70H
XRLA,#00H
JZLOOP5
XRLA,#05H
JZLOOP5
LOOP5:
ADDA,#08H
MOVR5,A
RET
LOOP2:
JBCY,L1
JNBCY,L2
L1:
RET
DISPLAY:
MOVP2,#00H
MOVDPTR,#TAB2
MOVA,70H
MOVCA,@A+DPTR
MOVP0,A
ACALLDELAY
MOVP2,#01H
MOVDPTR,#TAB1
MOVA,71H
MOVCA,@A+DPTR
MOVP0,A
ACALLDELAY
MOVP2,#02H
MOVDPTR,#TAB2
MOVA,72H
MOVCA,@A+DPTR
MOVP0,A
ACALLDELAY
MOVP2,#03H
MOVDPTR,#TAB2
MOVA,73H
MOVCA,@A+DPTR
MOVP0,A
ACALLDELAY
MOVP2,#04H
MOVDPTR,#TAB1
MOVA,74H
MOVCA,@A+DPTR
MOVP0,A
ACALLDELAY
MOVP2,#05H
MOVDPTR,#TAB2
MOVA,75H
MOVCA,@A+DPTR
MOVP0,A
ACALLDELAY
RET
DELAY:
MOVR4,#10
LOOP2:
MOVR5,#100
LOOP3:
DJNZR5,LOOP3
DJNZR4,LOOP2
RET
TAB1:
DB0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef
TAB2:
DB0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
END
仿真结果PROTUES
三.硬件实现
1.0~255计数器
程序:
#include"reg52.h"
unsignedcharcodetable[10]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsignedcharcodebit_table[6]={0x00,0x01,0x02,0x03,0x04,0x05};
unsignedcharnum,flag;
voiddisplay();
voiddelay(unsignedintaa);
sbitdula=P2^6;
sbitwela=P2^7;
//sbitD=P3^5;
sbitD1=P1^0;
/*---------------------------------------------------------------------
系统初始化
-----------------------------------------------------------------------*/
voidinit_timer()
{
TMOD=0X61;
TH1=0x00;
TL1=0x00;
TR1=1;
TH0=-50000/256;
TL0=-50000%256;
ET0=1;
TR0=1;
EA=1;
//TF1=0;
}
voidmain()
{
//P2=0xff;
//P0=0X00;
init_timer();
while
(1)
{
num=TL1;
display();
delay
(1);
}
}
voiddisplay()
{
unsignedintbai,shi,ge;
bai=num/100;
shi=num%100/10;
ge=num%10;
wela=1;
P0=0xfe;
wela=0;
P0=0x00;
dula=1;
P0=table[bai];
dula=0;
P0=0xff;
delay
(1);
wela=1;
P0=0xfd;
wela=0;
P0=0x00;
dula=1;
P0=table[shi];
dula=0;
P0=0xff;
delay
(1);
wela=1;
P0=0xfb;
wela=0;
P0=0x00;
dula=1;
P0=table[ge];
dula=0;
P0=0xff;
delay
(1);
}
voiddelay(unsignedintaa)
{
unsignedinti,j;
for(i=0;i{
for(j=0;j<110;j++);
}
}
voidQUF()interrupt1
{
if(flag==0)
{
D1=0;
flag=1;
}
else
{
D1=1;
flag=0;
}
TH0=-50000/256;
TL0=-50000%256;
}
硬件实现图:
2.0~50000计数器
程序:
#include
unsignedintcodetable[10]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsignedcharcodebit_table[6]={
0x00,0x01,0x02,0x03,0x04,0x05};
sbitdula=P2^6;
sbitwela=P2^7;
unsignedintnum=0,flag;
sbitD1=P1^0;
unsignedinti,j,k,x,y,z;
voidBCD();
voiddisplay();
voiddelay(unsignedintaa)
{
unsignedchari,j;
for(i=0;i{
for(j=0;j<110;j++);
}
}
/*--------------------------------------------------
系统初始化
----------------------------------------------------*/
voidinit()
{
TMOD=0X51;
TH1=0X00;
TL1=0X00;
TR1=1;
TH0=-5000/256;
TL0=-5000%256;
ET0=1;
TR0=1;
EA=1;
x=0;y=0,z=0;
display();
while
(1)
{
if(TL1!
=0X00)
BCD();
display();
}
}
voidBCD()
{
TL1=0;
num++;
}
voiddisplay()
{
if(num==50000)
{
num=0;
}
i=num/100000;
j=num/10000%10;
k=num/1000%10;
x=num/100%10;
y=num/10%10;
z=num%10;
wela=1;
P0=0xfe;
wela=0;
P0=0x00;
dula=1;
P0=table[i];
dula=0;
P0=0xff;
delay
(1);
wela=1;
P0=0xfd;
wela=0;
P0=0x00;
dula=1;
P0=table[j];
dula=0;
P0=0xff;
delay
(1);
wela=1;