单片机课程设计.docx

上传人:b****5 文档编号:4600525 上传时间:2022-12-07 格式:DOCX 页数:31 大小:276.45KB
下载 相关 举报
单片机课程设计.docx_第1页
第1页 / 共31页
单片机课程设计.docx_第2页
第2页 / 共31页
单片机课程设计.docx_第3页
第3页 / 共31页
单片机课程设计.docx_第4页
第4页 / 共31页
单片机课程设计.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

单片机课程设计.docx

《单片机课程设计.docx》由会员分享,可在线阅读,更多相关《单片机课程设计.docx(31页珍藏版)》请在冰豆网上搜索。

单片机课程设计.docx

单片机课程设计

目录

1设计任务……………………………………………………………2

2任务分析……………………………………………………………2

2.1设计一个255计数器………………………………………...2

2.2设计一个999999计数器…………………………………….2

2.3设计一个出租车计费系统…………………………………...3

3硬件设计……………………………………………………………3

4软件设计……………………………………………………………4

4.1255计数器……………………………………………………4

4.1.1流程图…………………………………………………4

4.1.2源程序…………………………………………………6

4.1.3仿真截图………………………………………………13

4.2999999计数器………………………………………………..13

4.2.1流程图…………………………………………………13

4.2.2源程序…………………………………………………14

4.2.3仿真截图………………………………………………20

4.3出租车计费系统……………………………………………...20

4.3.1流程图…………………………………………………20

4.3.2源程序…………………………………………………22

4.3.3仿真截图………………………………………………28

5设计总结……………………………………………………………29

 

1设计任务

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

1.1.1设计一个255计数器:

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

1.1.2设计一个99999计数器:

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

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

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

2任务分析

2.1设计一个255计数器

该设计计数范围为255,在51单片机里刚好一个字节足以,所以比较简单,脉冲计数方法可用单片机内部定时器的计数功能来实现,同样也可用外部中断的边沿触发方式实现。

但采用外部中断更耗费CPU资源,且计数最高频率比用定时器低,所以在这里我们采用定时器1的计数功能来实现。

单片机内部定时器为16位的,而这里只有用到8位,如果只按照任务要求功能来实现的话非常的简单,可以采用定时器1的工作方式1的计数方式来实现,因为当TL1中数据计到255时再来一个脉冲TL1则向TH1进位同时TL1清零,现在我们只看TL1中的变化就是从0-255不断的循环计数,这我们只需将TL1中数据译码后送入数码管显示就可了。

由于两个任务都是计满自动清零,在这里我们决定将第一个任务做成计数到255后停止计数,且数码管闪烁显示,再设置一个清零启动按键以方便控制。

在这里我们还是采用定时器1的工作方式1来实现,在主程序中可以设置一判断语句,当TL1中数据达到255时则停止计数,但是这样的话当外部脉冲频率过高时,可能会导致当TL1中数据超过255还没有来得及停止,因此我们在这里再加一层保障,启用中断来实现,需要说明的是采用中断计数也是要计到256才会产生中断的,就此会多计一个脉冲,在这里我们决定处理一下,即使是计到256我们也将它还原成255显示。

2.2设计一个99999计数器

该设计与第一个设计基本上一样,只是999999已经超出了16位,因此只有加上相应的处理才能满足要求了,但还是有很多种方法实现的,由于我采用的编程语言为C51,因此常见的方法有这两种,一是采用一个长整型变量来进行脉冲计数,二是采用六个字节计数,逢十进一的方法。

如果采用第一种方法编程稍容易,但其编译后的代码量和执行速度没第二种方法好,因此在这里我们采用第二种方法。

采用定时器1的工作方式2进行计数,设置成每来一个脉冲产生一个中断,在中断服务程序里面进行加计数。

在这里为方便控制我们还是设置一个按键,用来控制启动、停止、清零计数,当启动的

时候按下按键停止计数,当停止计数的时候按下按键启动计数,当按下按键超过1S时清零计数。

2.3设计一个出租车计费系统

该设计其实和前面两个任务差不多,只是有几个要考滤的地方,一就是车轮转一圈会产生几个脉冲,车轮的周长又为多少。

在任务中要求显示里程数和费用,根据要求我们又能找里程数和费用的关系为一个分段函数,在这里我们采用定时器1的工作方式2来对脉冲进行计数,设置定时器的初始值使之每行走一米产生一个中断,里程数在这里我们的分辨率设成0.1Km,因此要每产生一百次中断里程数加1,在数据里面加1而显示中实则为0.1Km,这是为了避免出现小数而这样计算的。

当每载完一个顾客后要对里程数进行清零或关闭系统,在这里我们设置一个按键,当按下该按键时会清零并重新计费,当按下按键超过1S关闭系统。

3硬件设计

由于三个任务在硬件功能上大体相同,因此完全可以采用同一个硬件来实现,且硬件比较简单,在这里就不单独对各个模块进行分析了。

下面就列出整体的原理图。

4软件设计

4.1255计数器

4.1.1流程图

⑴主程序流程图

 

⑵按键扫描函数流程图

 

⑶数据转换函数流程图

 

⑷显示函数流程图

 

⑸定时器0中断函数流程图

 

⑹定时器1中断函数流程图

 

4.1.2源程序

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

******文件名:

0-255外部脉冲计数

******功能:

对外部脉冲信号进行计数并显示脉冲范围0-255

******编写人:

电信083刘广

******版本:

******说明:

本程序以AT89S51为处理器,晶振为12MHZ编写。

采用proteus仿真

******实现,电路采用共阳极数码管,采用573和138分别做段码和位码的驱动。

******脉冲信号在实际中可能采用555构成多谐振荡器产生,在这里我们采用

******proteus自带的脉冲产生器来产生,仿真时注意脉冲信号频率不能高于

******0.5MHz,在这里为方便操作,采用一个控制按键进行控制,用来进行启动

******清零控制,当按下按键时会进行计数清零并重新开始计数,当计数达到

******255时停止计数,同时数码管闪烁显示。

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

#include

//#include

//#include

#defineucharunsignedchar

#defineuintunsignedint

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

**************************硬件声明区*********************************

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

#defineDispBitP2

#defineDispSegP0

#defineDispNum3

sbitKeyControl=P1^0;

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

**************************全局变量区*********************************

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

ucharcodeTAB[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

ucharDisplayBuff[DispNum],TimeCount;

bitHelpBit;

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

***************************函数声明区********************************

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

voidMCUInit();

voidDelayMs(uintDat);

voidDataConvert();

voidDisplayScan();

voidKeyScan();

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

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

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

voidmain()

{

MCUInit();

while

(1)

{

KeyScan();

DataConvert();

DisplayScan();

}

}

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

*****函数名:

MCUInit()

*****输入参数:

*****输出参数:

*****功能:

对单片机内部资源进行初始化

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

voidMCUInit()

{

HelpBit=1;

TL1=0;

TH1=0xff;

TH0=(65536-50000)/256;//定时

TL0=(65536-50000)%256;

TimeCount=0;

TMOD=0x51;

IE=0x8a;

}

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

*****函数名:

DelayMs(uintDat)

*****输入参数:

Dat

*****输出参数:

*****功能:

延时函数,延时时间Dat*ms。

用在按键防抖和显示扫描部分。

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

voidDelayMs(uintDat)

{

uintx,y;

for(x=Dat;x>0;x--)

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

}

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

*****函数名:

DataConvert()

*****输入参数:

TL1

*****输出参数:

DisplayBuff[]

*****功能:

将TL1中的二进制数译成共阳极七段码给DisplayBuff数组。

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

voidDataConvert()

{

if(TL1==255)//如果计数满255则停止计数,同时置标志位

{

TR1=0;

TR0=1;

}

DisplayBuff[0]=TAB[TL1%10];//分离个位并译成七段码

DisplayBuff[1]=TAB[((TL1%100)/10)];//分离十位

DisplayBuff[2]=TAB[(TL1/100)];//分离百位

}

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

*****函数名:

DisplayScan()

*****输入参数:

DisplayBuff

*****输出参数:

*****功能:

将DisplayBuff中的数码放入数码管进行显示,动态扫描显示。

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

voidDisplayScan()

{

uchari;

if((TR0==0)||((TR0==1)&&(HelpBit==1)))//如果计数不满255正常显示

{//否则闪烁显示

for(i=0;i

{

DispSeg=0xff;

DispBit=i;

DispSeg=DisplayBuff[i];

DelayMs

(1);

}

}

P0=0xff;

P2=0xff;

}

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

*****函数名:

KeyScan()

*****输入参数:

*****输出参数:

*****功能:

进行脉冲计数清零和重新启动

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

voidKeyScan()

{

if(KeyControl==0)

{

DelayMs(10);//按键防抖

if(KeyControl==0)

{

TR0=0;

TR1=1;

HelpBit=1;

TimeCount=0;

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

TL1=0;

TH1=0xff;

while(KeyControl==0)//等待按键释放,如果按键放下则停止计数,并显示当前值

{

DataConvert();

DisplayScan();

}

}

}

}

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

*****函数名:

Time0()

*****输入参数:

*****输出参数:

*****功能:

定时器0中断函数,用数控制数码管闪烁。

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

voidTime0()interrupt1

{

TH0=(65536-50000)/256;//定时

TL0=(65536-50000)%256;

TimeCount++;

if(TimeCount==10)

{

HelpBit=~HelpBit;

TimeCount=0;

}

}

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

*****函数名:

Time1()

*****输入参数:

*****输出参数:

*****功能:

定时器1中断函数,当脉冲频率过快时,由于动态扫描占用了程序

*****单次执行时间的绝大部分,且时间相对较长,有可能出现脉冲计数到255

*****无法及时停止计数,这里设立中断用当出现这种情况时进行计数器的停止

*****定时器工作方式采用方式1.

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

voidTime1()interrupt3

{

TR1=0;

TR0=1;

TL1=0xff;

TH1=0xff;

HelpBit=1;

}

4.1.3仿真截图

4.2999999计数器

4.2.1流程图

由于该设计与上一个设计大体相同,所以其流程图也大体相同,在这里只列出不同的部分。

⑴按键扫描函数流程图

 

 

⑵定时器0中断服务函数流程图

 

4.2.2源程序

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

******文件名:

0-99999999外部脉冲计数

******功能:

对外部脉冲信号进行计数并显示脉冲范围0-99999999

******编写人:

电信083刘广

******版本:

******说明:

本程序以AT89S51为处理器,晶振为12MHZ编写。

采用proteus仿真

******实现,电路采用共阳极数码管,采用573和138分别做段码和位码的驱动。

******脉冲信号在实际中可能采用555构成多谐振荡器产生,在这里我们采用

******proteus自带的脉冲产生器来产生,仿真时注意脉冲信号频率不能高于

******3K。

在这里为方便操作,采用一个控制按键进行控制,用来进行启动

******停止控制,当停止时按下按键启动,当启动时按下按键停止,当计数达到

******99999999自动清零。

重新计数.当按键按下超过1S清零并停止计数。

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

#include

//#include

//#include

#defineucharunsignedchar

#defineuintunsignedint

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

**************************硬件声明区*********************************

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

#defineDispBitP2

#defineDispSegP0

#defineDispNum8

sbitKeyControl=P1^0;

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

**************************全局变量区*********************************

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

ucharcodeTAB[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

ucharDisplayBuff[DispNum],TimeCount,CountBuff[DispNum];

//bitHelpBit;

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

***************************函数声明区********************************

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

voidMCUInit();

voidDelayMs(uintDat);

voidDataConvert();

voidDisplayScan();

voidKeyScan();

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

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

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

voidmain()

{

MCUInit();

while

(1)

{

KeyScan();

DataConvert();

DisplayScan();

}

}

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

*****函数名:

MCUInit()

*****输入参数:

*****输出参数:

*****功能:

对单片机内部资源进行初始化

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

voidMCUInit()

{

//HelpBit=1;

TL1=0xff;

TH1=0xff;

TH0=(65536-50000)/256;//定时50ms

TL0=(65536-50000)%256;

TimeCount=0;

TMOD=0x61;//设定T1为计数方式2工作,设定T0为定时方式1工作

IE=0x8a;//开定时器1和定时器2的中断

}

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

*****函数名:

DelayMs(uintDat)

*****输入参数:

Dat

*****输出参数:

*****功能:

延时函数,延时时间Dat*ms。

用在按键防抖和显示扫描部分。

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

voidDelayMs(ui

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

当前位置:首页 > 高中教育 > 高中教育

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

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