1、单片机课程设计目录1 设计任务 22 任务分析 2 2.1 设计一个255计数器. 2 2.2 设计一个999999计数器. 2 2.3 设计一个出租车计费系统. 33 硬件设计 34 软件设计 4 4.1 255计数器 4 4.1.1 流程图 4 4.1.2 源程序 6 4.1.3 仿真截图13 4.2 999999计数器.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 仿真截图285 设计总结291 设计任务1.1 外部脉冲自动计数,自动显示。1.1.1设计一个255计
2、数器:0255计数,计满后自动清0,重新计数(在数码管中显示)。1.1.2设计一个99999计数器:0999999计数,计满后自动清0,重新计数(在数码管中显示)。1.2 设计一个出租车计费系统: 起步价为5元(2km以内),2km后,0.8元/0.5km;要求每500m刷新计费一次,在8位数码管中,前三位显示数码管显示里程数,后三位数码管显示价钱(角,元,十元)2 任务分析2.1设计一个255计数器该设计计数范围为255,在51单片机里刚好一个字节足以,所以比较简单,脉冲计数方法可用单片机内部定时器的计数功能来实现,同样也可用外部中断的边沿触发方式实现。但采用外部中断更耗费CPU资源,且计数
3、最高频率比用定时器低,所以在这里我们采用定时器1的计数功能来实现。单片机内部定时器为16位的,而这里只有用到8位,如果只按照任务要求功能来实现的话非常的简单,可以采用定时器1的工作方式1的计数方式来实现,因为当TL1中数据计到255时再来一个脉冲TL1则向TH1进位同时TL1清零,现在我们只看TL1中的变化就是从0-255不断的循环计数,这我们只需将TL1中数据译码后送入数码管显示就可了。由于两个任务都是计满自动清零,在这里我们决定将第一个任务做成计数到255后停止计数,且数码管闪烁显示,再设置一个清零启动按键以方便控制。在这里我们还是采用定时器1的工作方式1来实现,在主程序中可以设置一判断语
4、句,当TL1中数据达到255时则停止计数,但是这样的话当外部脉冲频率过高时,可能会导致当TL1中数据超过255还没有来得及停止,因此我们在这里再加一层保障,启用中断来实现,需要说明的是采用中断计数也是要计到256才会产生中断的,就此会多计一个脉冲,在这里我们决定处理一下,即使是计到256我们也将它还原成255显示。 2.2设计一个99999计数器 该设计与第一个设计基本上一样,只是999999已经超出了16位,因此只有加上相应的处理才能满足要求了,但还是有很多种方法实现的,由于我采用的编程语言为C51,因此常见的方法有这两种,一是采用一个长整型变量来进行脉冲计数,二是采用六个字节计数,逢十进一
5、的方法。如果采用第一种方法编程稍容易,但其编译后的代码量和执行速度没第二种方法好,因此在这里我们采用第二种方法。采用定时器1的工作方式2进行计数,设置成每来一个脉冲产生一个中断,在中断服务程序里面进行加计数。在这里为方便控制我们还是设置一个按键,用来控制启动、停止、清零计数,当启动的时候按下按键停止计数,当停止计数的时候按下按键启动计数,当按下按键超过1S时清零计数。 2.3设计一个出租车计费系统 该设计其实和前面两个任务差不多,只是有几个要考滤的地方,一就是车轮转一圈会产生几个脉冲,车轮的周长又为多少。在任务中要求显示里程数和费用,根据要求我们又能找里程数和费用的关系为一个分段函数,在这里我
6、们采用定时器1的工作方式2来对脉冲进行计数,设置定时器的初始值使之每行走一米产生一个中断,里程数在这里我们的分辨率设成0.1Km,因此要每产生一百次中断里程数加1,在数据里面加1而显示中实则为0.1Km,这是为了避免出现小数而这样计算的。当每载完一个顾客后要对里程数进行清零或关闭系统,在这里我们设置一个按键,当按下该按键时会清零并重新计费,当按下按键超过1S关闭系统。3 硬件设计由于三个任务在硬件功能上大体相同,因此完全可以采用同一个硬件来实现,且硬件比较简单,在这里就不单独对各个模块进行分析了。下面就列出整体的原理图。4 软件设计4.1 255计数器4.1.1 流程图主程序流程图 按键扫描函
7、数流程图 数据转换函数流程图显示函数流程图定时器0中断函数流程图定时器1中断函数流程图4.1.2 源程序/*文件名:0-255外部脉冲计数*功能:对外部脉冲信号进行计数并显示 脉冲范围0-255*编写人:电信083 刘广*版本:*说明:本程序以AT89S51为处理器,晶振为12MHZ编写。采用proteus仿真*实现,电路采用共阳极数码管,采用573和138分别做段码和位码的驱动。*脉冲信号在实际中可能采用555构成多谐振荡器产生,在这里我们采用*proteus自带的脉冲产生器来产生,仿真时注意脉冲信号频率不能高于*0.5MHz,在这里为方便操作,采用一个控制按键进行控制,用来进行启动*清零控
8、制,当按下按键时会进行计数清零并重新开始计数,当计数达到*255时停止计数,同时数码管闪烁显示。*/#include/#include/#include#define uchar unsigned char#define uint unsigned int/*硬件声明区*/#define DispBit P2#define DispSeg P0#define DispNum 3sbit KeyControl=P10;/*全局变量区*/uchar code TAB=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;uchar DisplayBuf
9、fDispNum,TimeCount;bit HelpBit;/*函数声明区*/void MCUInit();void DelayMs(uint Dat);void DataConvert();void DisplayScan();void KeyScan();/*主 程 序*/void main() MCUInit(); while(1) KeyScan(); DataConvert(); DisplayScan(); /*函数名:MCUInit()*输入参数:无*输出参数:无*功能:对单片机内部资源进行初始化*/void MCUInit() HelpBit=1; TL1=0; TH1=0x
10、ff; TH0=(65536-50000)/256; /定时 TL0=(65536-50000)%256; TimeCount=0; TMOD=0x51; IE=0x8a;/*函数名:DelayMs(uint Dat)*输入参数:Dat*输出参数:无*功能:延时函数,延时时间Dat*ms。用在按键防抖和显示扫描部分。*/void DelayMs(uint Dat) uint x,y; for(x=Dat;x0;x-) for(y=111;y0;y-);/*函数名:DataConvert()*输入参数:TL1*输出参数:DisplayBuff*功能:将TL1中的二进制数译成共阳极七段码给Disp
11、layBuff数组。*/void DataConvert() if(TL1=255) /如果计数满255则停止计数,同时置标志位 TR1=0; TR0=1; DisplayBuff0=TABTL1%10; /分离个位并译成七段码 DisplayBuff1=TAB(TL1%100)/10); /分离十位 DisplayBuff2=TAB(TL1/100); /分离百位/*函数名:DisplayScan()*输入参数:DisplayBuff*输出参数:无*功能:将DisplayBuff中的数码放入数码管进行显示,动态扫描显示。*/void DisplayScan() uchar i; if(TR0
12、=0)|(TR0=1)&(HelpBit=1)/如果计数不满255正常显示 /否则闪烁显示 for(i=0;iDispNum;i+) DispSeg=0xff; DispBit=i; DispSeg=DisplayBuffi; DelayMs(1); P0=0xff; P2=0xff;/*函数名:KeyScan()*输入参数:无*输出参数:无*功能:进行脉冲计数清零和重新启动*/void KeyScan() if(KeyControl=0) DelayMs(10); /按键防抖 if(KeyControl=0) TR0=0; TR1=1; HelpBit=1; TimeCount=0; TH0
13、=(65536-50000)/256; TL0=(65536-50000)%256; TL1=0; TH1=0xff; while(KeyControl=0) /等待按键释放,如果按键放下则停止计数,并显示当前值 DataConvert(); DisplayScan(); /*函数名:Time0()*输入参数:无*输出参数:无*功能:定时器0中断函数,用数控制数码管闪烁。*/void Time0() interrupt 1 TH0=(65536-50000)/256; /定时 TL0=(65536-50000)%256; TimeCount+; if(TimeCount=10) HelpBit
14、=HelpBit; TimeCount=0; /*函数名:Time1()*输入参数:无*输出参数:无*功能:定时器1中断函数,当脉冲频率过快时,由于动态扫描占用了程序*单次执行时间的绝大部分,且时间相对较长,有可能出现脉冲计数到255*无法及时停止计数,这里设立中断用当出现这种情况时进行计数器的停止*定时器工作方式采用方式1.*/void Time1() interrupt 3 TR1=0; TR0=1; TL1=0xff; TH1=0xff; HelpBit=1;4.1.3 仿真截图4.2 999999计数器4.2.1 流程图由于该设计与上一个设计大体相同,所以其流程图也大体相同,在这里只列
15、出不同的部分。按键扫描函数流程图定时器0中断服务函数流程图 4.2.2 源程序/*文件名:0-99999999外部脉冲计数*功能:对外部脉冲信号进行计数并显示 脉冲范围0-99999999*编写人:电信083 刘广*版本:*说明:本程序以AT89S51为处理器,晶振为12MHZ编写。采用proteus仿真*实现,电路采用共阳极数码管,采用573和138分别做段码和位码的驱动。*脉冲信号在实际中可能采用555构成多谐振荡器产生,在这里我们采用*proteus自带的脉冲产生器来产生,仿真时注意脉冲信号频率不能高于*3K。在这里为方便操作,采用一个控制按键进行控制,用来进行启动*停止控制,当停止时按
16、下按键启动,当启动时按下按键停止,当计数达到*99999999自动清零。重新计数.当按键按下超过1S清零并停止计数。*/#include/#include/#include#define uchar unsigned char#define uint unsigned int/*硬件声明区*/#define DispBit P2#define DispSeg P0#define DispNum 8sbit KeyControl=P10;/*全局变量区*/uchar code TAB=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;uchar
17、DisplayBuffDispNum,TimeCount,CountBuffDispNum;/bit HelpBit;/*函数声明区*/void MCUInit();void DelayMs(uint Dat);void DataConvert();void DisplayScan();void KeyScan();/*主 程 序*/void main() MCUInit(); while(1) KeyScan(); DataConvert(); DisplayScan(); /*函数名:MCUInit()*输入参数:无*输出参数:无*功能:对单片机内部资源进行初始化*/void MCUInit()/ 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(uint Dat)*输入参数:Dat*输出参数:无*功能:延时函数,延时时间Dat*ms。用在按键防抖和显示扫描部分。*/void DelayMs(ui
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1