单片机课程设计999999显示与出租车计费器包含汇编与C语言.docx
《单片机课程设计999999显示与出租车计费器包含汇编与C语言.docx》由会员分享,可在线阅读,更多相关《单片机课程设计999999显示与出租车计费器包含汇编与C语言.docx(32页珍藏版)》请在冰豆网上搜索。
单片机课程设计999999显示与出租车计费器包含汇编与C语言
湖南工业大学
课程设计
资料袋
电气与信息工程学院(系、部)2012~2013学年第2学期
课程名称单片机系统课程设计指导教师职称
学生姓名甘显豪专业班级自动化1004学号***********
题目出租车计费系统
成绩起止日期2012年12月31日~2013年1月11日
目录清单
序号
材料名称
资料数量
备注
1
课程设计任务书
2
课程设计说明书
3
课程设计图纸
张
4
5
6
湖南工业大学
课程设计任务书
电气与信息工程学院(系、部)自动化专业1004班级
课程名称:
单片机系统课程设计
设计题目:
出租车计费系统
完成期限:
自2012年12月31日至2013年1月11日共2周
内
容
及
任
务
1.1外部脉冲自动计数,自动显示。
1.1.1设计一个255计数器:
0-255计数,计满后自动清0,重新计数(在数码管中显示)。
1.1.2设计一个999999计数器:
0-999999计数,计满后自动清0,重新计数(在数码管中显示)。
1.2设计一个出租车计费系统:
起步价为5元(2km以内),2km后,0.8元/0.5km;要求每500m刷新计费一次,在8位数码管中,前三位显示数码管显示里程数,后三位数码管显示价钱(角,元,十元)
进
度
安
排
起止日期
工作内容
2012.12.31-2012.12.31
讲述设计内容及基本原理
2013.1.1-2013.1.10
单片机系统的设计
2013.1.11-2013.1.11
单片机课程设计验收
主
要
参
考
资
料
[1]刘苗生、潘宗预.单片机测控系统设计[M].北京:
中国物质出版社,2006
[2]李朝青.单片机原理及接口技术[M].北京:
北京航空航天大学出版社,2005
指导教师(签字):
年月日
系(教研室)主任(签字):
年月日
附件三
(单片机应用系统)
设计说明书
(题目)
出租车计费系统
起止日期:
2012年12月31日至2013年1月11日
学生姓名
甘显豪
班级
自动化1004
学号
10401701305
成绩
指导教师(签字)
电气与信息工程学院
2012年12月31日
一、设计任务:
1.1外部脉冲自动计数,自动显示。
1.1.1设计一个255计数器:
0-255计数,计满后自动清0,重新计数(在数码管中显示)。
1.1.2设计一个999999计数器:
0-999999计数,计满后自动清0,重新计数(在数码管中显示)。
1.2设计一个出租车计费系统:
起步价为5元(2km以内),2km后,0.8元/0.5km;要求每500m刷新计费一次,在8位数码管中,前3位显示数码管显示里程数,后3位数码管显示价钱(角,元,十元)
二、设计原理及思路
1.设计一个255计数器:
0-255计数,计满后自动清0,重新计数(在数码管中显示)。
设计原理:
这个用汇编和C语言都比较简单。
首先我确定用的是T0(TMOD=0x06)定时计数器,用查询计数模式,工作方式2(8位,可自动重新装初值),总中断不用开,赋初值255,来一个脉冲直接溢出,只要判断溢出标志位TF0是否为1即可,TF0为1则说明溢出,然后再用指令清0就OK了,然后给数码管显示加1(当然这里要先判断是否加到了255,若>255就显示清0)。
因为我这里定义要显示的数temp,用unsignedchar(无符号字符型),范围刚好是0到255,所以不用判断是否大于255也可以直接循环又从0开始计数。
C语言流程图:
N
Y
N
Y
2.设计一个999999计数器:
0-999999计数,计满后自动清0,重新计数(在数码管中显示)。
这个用C语言和255一样的原理,只是定义要显示的数temp范围要大于999999,所以我这里直接定义unsignedlongtemp(范围为0到2的32次方减1),后面必须加多判断是否大于999999。
C语言流程图:
N
Y
N
Y
3.设计一个出租车计费系统:
起步价为5元(2km以内),2km后,0.8元/0.5km;要求每500m刷新计费一次,在8为数码管中,前3为显示数码管显示里程数,后3位数码管显示价钱(角,元,十元)
原理:
计数器每计数100个外部脉冲就产生中断,里程加1百米,大于两千米百位就和5和0比较,如果相等就调用价格计算子程序,价格加0.8元。
然后返回中断,调用里程和价格显示。
这个用C语言和上面两个差不多,也就多个价格显示,但是用汇编复杂点,改动价格起来麻烦点,很多运算必须经过中间缓冲单元才行。
汇编流程图
N
Y
N
Y
N
Y
三、PROTEUS硬件电路图
1.255计数器
C语言流程图:
2.999999
3.出租车计费器(汇编)
(1).(小于2KM与大于2KM),第一个按键是复位功能,右边的开关是暂停/继续功能
(2).这个是进入第二个按键(设定价格)的功能,然后按第三或四个按键可以加减价格,从而设定价格起步价(时间有限,程序未全部完全),这个按键是我自己额外加的,想让它功能更完善,更人性化。
以下这个是插入四个扫描独立键盘按键的程序小模块
MAIN:
LCALLDISPM;调用价格子程序
LCALLDISPL;调用里程子程序
;LJMPMAIN
MOVA,#0FFH
MOVP1,A
B1:
MOVA,P1
CJNEA,#0FFH,B3
SJMPB1
B3:
LCALLDELAY10MS
MOVA,P1
CJNEA,#0FFH,B2
SJMPB1
B2:
JNBACC.0,TAB0
JNBACC.1,TAB1
;JNBACC.2,TAB2
;JNBACC.3,TAB3
SJMPB1
TAB0:
LJMPOPR0
TAB1:
LJMPOPR1
;TAB2:
LJMPOPR2
;TAB3:
LJMPOPR3
OPR0:
LJMPSTART
;MOVP2,#0FH
;MOVSHIQIAN,#00H
;MOVQIANMI,#00H
;MOVBAIMI,#00H
;MOVSHIYUAN,#00H
;MOVYUAN,#03H;低于2KM,价格显示3元
;MOVJIAO,#00H
;LCALLDELAY10MS
;MOVP0,#3FH
;MOVP2,#00H
LJMPMAIN
OPR1:
MOVYUAN,#00H
MOVP2,#0EH
;LJMPMAIN
…………………….
(3)以下.这个是我在上面6位数码管中扩展的,在8位数码管中,前4位显示数码管显示里程数,后4位数码管显示价钱(这个其实也很简单,也就加多两个位选,判断下进位等就OK了)
四.源程序
1.255(C语言)
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
uchartemp,bai,shi,ge;//uchar是无符号字符型,范围为0到255
ucharcodetable[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};//共阴极段码表
voiddelay(uintz);
voidmain()
{
temp=0;
TMOD=0x06;//00000110T0计数模式,工作方式2(8位,自动重装初值)
TH0=255;
TL0=255;//赋初值
//EA=1;用的是查询方式计数,不用开总中断
//ET0=1;
TR0=1;//开定时计数器T0
P0=0x00;
temp=0;//数码管初值
while
(1)
{
if(TF0==1)
{
temp=temp+1;//加计数
if(temp>255)
temp=0;
TF0=0;
}
bai=temp/100;
shi=temp%100/10;
ge=temp%10;
P2=0xf3;
P0=table[bai];
delay
(1);
P0=0x00;
P2=0xf4;
P0=table[shi];
delay
(1);
P0=0x00;
P2=0xf5;
P0=table[ge];
delay
(1);
P0=0x00;
}
}
voiddelay(uintz)//延时zMS
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
1.255(汇编)
ORG0000H
AJMPSTART
ORG000BH
AJMPTINT0
ORG0030H
START:
MOVTMOD,#06H;计数模式,工作方式2(自动重新赋值)
MOVTH0,#00H;初值0
MOVTL0,#00H
SETBTR0
SETBET0
SETBEA
LOOP:
LCALLDISP
SJMPLOOP
TINT0:
RETI
DISP:
MOVA,TL1
MOVB,#64H;64H=100
DIVAB;A为百位,商存放在A,余数存放在B
MOVDPTR,#SEGTAB
MOVCA,@A+DPTR
MOVP2,#03H;位选4(Y4),百位数码管打开
MOVP0,A;送百位数据
ACALLDELAY
MOVA,B
MOVB,#0AH;0AH=10
DIVAB;A为十位,B为个位
MOVCA,@A+DPTR
MOVP2,#04H;位选5(Y5),十位数码管打开
MOVP0,A;送十位数据
ACALLDELAY
MOVA,B
MOVCA,@A+DPTR
MOVP2,#05H;位选6(Y6),个位数码管打开
MOVP0,A;送个位数据
ACALLDELAY
RET
DELAY:
MOVR5,#01H;延时1ms,晶振6MHz
LOOP1:
MOVR6,#248
DJNZR6,$
DJNZR5,LOOP1
RET
SEGTAB:
DB3FH,06H,5BH,4FH,66H;0,1,2,3,4;共阴极LED数码管的段码表
DB6DH,7DH,07H,7FH,6FH;5,6,7,8,9
END
2.999999(C语言),用共阴极数码管
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
ucharbai,shi,ge,shiwan,qian,wan;
ucharcodetable[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};//段码表
voiddelay(uintz);
unsignedlongtemp;//定义要显示的数为无符号长整形(范围:
0到2的32次方减1)
voidmain()
{
TMOD=0x06;//00000110T0计数模式,工作方式2(8位,自动重装初值)
TH0=255;
TL0=255;//赋初值255,来一个脉冲直接溢出
TR0=1;//开定时计数器T1(用的是查询方式,总中断不用开)
P0=0x00;
temp=0;//数码管初值
while
(1)//一直在while里面循环
{
if(TF0==1)
{
temp=temp+1;//加计数
if(temp>999999)
temp=0;
TF0=0;//溢出标志位TF0清0
}
shiwan=temp/100000;
wan=temp%100000/10000;
qian=temp%10000%10000/1000;
bai=temp%10000%10000%1000/100;
shi=temp%10000%10000%1000%100/10;
ge=temp%10;
P2=0xf0;//位选(十万位)
P0=table[shiwan];//段选
delay
(1);//延时1MS
P0=0x00;//段选全关,消影,防止乱码
P2=0xf1;
P0=table[wan];
delay
(1);
P0=0x00;
P2=0xf2;
P0=table[qian];
delay
(1);
P0=0x00;
P2=0xf3;
P0=table[bai];
delay
(1);
P0=0x00;
P2=0xf4;
P0=table[shi];
delay
(1);
P0=0x00;
P2=0xf5;
P0=table[ge];
delay
(1);
P0=0x00;
}
}
voiddelay(uintz)//延时zMS
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
2.999999(汇编)
ORG0000H
LJMPMAIN
ORG000BH
LJMPL1
ORG0030H
MAIN:
MOV70H,#0;给段码显示缓冲区清0
MOV71H,#0
MOV72H,#0
MOV73H,#0
MOV74H,#0
MOV75H,#0
MOVTMOD,#06H;计数模式,工作方式2(自动重装初值)
MOVTH0,#255;赋初值255,每来一个脉冲就会溢出,即TF1=1,数码管显示(计数)加1
MOVTL0,#255;TF1清0后,又自动赋初值255
SETBTR0;开T1定时/计数器
L1:
;采用查询方式中断,TF1软件清0,总中断不能开
JNBTF1,L3;判断计数溢出标志位TF1,若TF1=0(无溢出),则转到L3
CLRTF1;若TF1=1(溢出),则清0
LCALLCOUNT;调用COUNT
L3:
LCALLDISPLAY
SJMPL1
COUNT:
;计数加1程序
MOVR1,#70H;R1<--70H
L2:
INC@R1;(R1)中的内容加1
CJNE@R1,#10,BTOM;判断,若((R1))不等于10,转到BOTM
MOV@R1,#0;若((R1))=10,即产生进位,则清0
INCR1;进位保存在下一个单元中
CJNER1,#76H,L2;判断是否计满999999,最高位(十万位)75H是否产生进位,若(R1)不等于76H,转回L2
MOVR1,#70H;若最高位(十万位)75H是否产生进位,即(R1)=76H,则重新R1<--70H
BTOM:
RET
DISPLAY:
MOVR0,#70H;显示缓冲区首地址送R0
MOVR3,#0;位选码首地址清0
MOVDPTR,#SEG;DPTR指向字型码表的首地址
L4:
MOVA,@R0;取出要显示的数
MOVCA,@A+DPTR;取出显示码
MOVP2,R3;位选输出到P2
MOVP0,A;显示码(段选)输出到P0
INCR0;动态显示
INCR3
LCALLD6MS;延时
MOVP0,#0FFH;共阳极数码管,段选高电平全灭,消影
CJNER3,#6,L4;若位选没循环显示够6次,则返回L4
RET
SEG:
;DB3FH,06H,5BH,4FH,66H;0,1,2,3,4
;DB6DH,7DH,07H,7FH,6FH;5,6,7,8,9
DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H;共阳极数码管的段码表
DB80H,90H
D6MS:
;延迟6MS
MOVR7,#3
DL:
MOVR6,#10
DJNZR6,$
DJNZR7,DL
RET
END
3.出租车计费器(C语言)
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
ucharbaimi,qianmi,shiqian,jiao,yuan,shiyuan;
ucharcodetable[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};//段码表
voiddelay(uintz);
voidjiage1();
voidlucheng1();
uintjiage,lucheng;
voidmain()
{
TMOD=0x06;//00000110T0计数模式,工作方式2(8位,自动重装初值)
TH0=156;
TL0=156;
EA=1;
ET0=1;
TR0=1;
P0=0x00;
lucheng=0;//路程初值
jiage=50;//价格初值
while
(1)//一直在while里面循环
{
jiage1();
lucheng1();
}
}
voidjiage1()
{
shiyuan=jiage/100;
yuan=jiage%100/10;
jiao=jiage%10;
P2=0xf3;
P0=table[shiyuan];
delay
(1);
P0=0x00;
P2=0xf4;
P0=table[yuan];
delay
(1);
P0=0x00;
P2=0xf5;
P0=table[jiao];
delay
(1);
P0=0x00;
}
voidlucheng1()
{
shiqian=lucheng/100;
qianmi=lucheng%100/10;
baimi=lucheng%10;
P2=0xf0;
P0=table[shiqian];
delay
(1);
P0=0x00;
P2=0xf1;
P0=table[qianmi];
delay
(1);
P0=0x00;
P2=0xf2;
P0=table[baimi];
delay
(1);
P0=0x00;
}
voidtimer0()interrupt2
{
lucheng++;
if(lucheng>20)//大于2KM
{
baimi=lucheng%10;
if(baimi==5|baimi==0)
jiage=jiage+8;//单价
}}
voiddelay(uintz)//延时zMS
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
3.出租车计费器(汇编)
ORG0000H
AJMPSTART
ORG000BH
SJMPTINT0
ORG0030H
SHIQIANEQU20H
QIANMIEQU21H
BAIMIEQU22H
SHIYUANEQU24H
YUANEQU25H
JIAOEQU26H
START:
CLRP2.3
MOVSHIQIAN,#00H
MOVQIANMI,#00H
MOVBAIMI,#00H
MOVSHIYUAN,#00H
MOVYUAN,#03H;低于2KM,价格显示3元
MOVJIAO,#00H
MOVTMOD,#06H;定时模式,工作方式2(自动重赋初值)
MOVTH0,#9CH;赋初值9CH=156,(计数100溢出)
MOVTL0,#9CH
SETBTR0
SETBET0
SETBEA
MAIN:
LCALLDISPM;调用价格子程序
LCALLDISPL;调用里程子程序
SJMPMAIN
TINT0:
;中断处理程序
LCALLLONG;每100个脉冲溢出中断时,调用里程加100米计算子程序
MOVA,SHIQIAN
CJNEA,#00H,T1
MOVA,QIANMI;千米位
CLRC
SUBBA,#02H;判断千米位减掉2KM是否大于0
JNCT1;大于两千米转到T1,即借位(Cy)=0
RETI
T1:
MOVA,BAIMI
CJNEA,#05H,NEXT;和5相等,就更新价格,否则判断是否和0相等
LCALLMONEY;(A)=5,调用价格计算子程序
RETI
NEXT:
CJNEA,#00H,T2;和0相等,更新价格,否则返回
LCALLMONEY
T2:
RETI
DISPL:
;显示里程子程序
MOVR0,#20H;十千米20H
MOVA,@R0
MOVDPTR,#SEGTAB
MOVCA,@A+DPTR
MOVP2,#09H;位选,P2.3连接74HC138的使能端E1(高电平有效),138输入端为001,则输出Y1为0,数码管位2选通
MOVP0,A;段选
LCALLDELAY
INCR0;千米21H
MOVA,@R0
MOVCA,@A+DPTR
ADDA,#80H;显示小数点
MOVP2,#0AH;位选,1010,Y2为0,数码管位3选通
MOVP0,A;段选