找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9196|回复: 3
打印 上一主题 下一主题
收起左侧

基于51单片机的出租车计价器源程序与Proteus仿真设计

  [复制链接]
跳转到指定楼层
楼主
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


本设计是针对城市出租车运营的一个计价器。设计基于STC15F2K60S2单片机为主控制芯片,通过霍尔传感器来给单片机产生脉冲,从而累计车轮旋转的圈数,利用算法来计算出行驶的路程,并根据相应的收费标准计算出应当收取的费用,通过LCD1602液晶显示屏来显示路程,单价,消费金额,路程中等待的时间等信息。本设计还可以根据自身的需要对收费的标准进行调整。系统硬件包括CPU控制模块、按键模块、显示模块、电源模块等四部分。软件设计包括系统总流程图与每个模块的流程图,最后将软件与硬件联调,达到所需功能要求。

(1)不同情况具有不同的收费标准。
白天,晚上,途中等待(>=10min 开始收费)
(2)能进行手动修改单价
(3)具有数据的复位功能
(4)具有启动计时开关、白天/晚上收费标准的转换开关、数据的清零开关、单价的调整(最好使用+和-按键)
(5) 数据输出:单价输出 2 位(要能输入小数),路程输出 2 位,总金额输出 3 位(有 1 位小数)。

一个基于单片机STC15F2K60S2的出租车自动计价器,附带有键盘电路,显示模块等。在上电时LCD1602显示最初的起步价,里程单价,等待时间收费三种收费,通过按键可以调整起步价、里程单价和等待时间收费。通过电机来模拟出租车轮胎的转动和停止。在LCD1602液晶上可以显示运行的路程,运行时暂停的时间,通过软件计算可以得出乘客所需要支付的费用。在这里主要是以STC15F2K60S2单片机为核心控制器,P0口接1602液晶显示模块,P1口接按键原理电路,霍尔传感器连接在外部中断0口向单片机输入脉冲,一个脉冲代表车轮转动一周,从而计算出运行的路程和费用。
设计方案

通过单片机作为主控器,利用1602字符液晶作为显示电路,采用内部时钟脉冲,通过按键可以方便调节,而且控制简单,成本低廉,设计电路简单,易操作,以下是系统流程图。如图1.1所示。
当我们乘坐出租车时,出租车司机通过电源启动计价器后,只要汽车一启动,随着行驶里程的增加,当小于某一个值的时候<如3km>时,就会看到出租车里面的计价器里程数字显示的读数为起步价,而当行驶到某一值<如3km)计费数字显示开始从起步价<如7.7元)增加。当出租车到达某地需要在那里等候时,司机只要按一下“等待”键,每等候一定的时间<如10分钟),计费显示就增加一个该收的等候费用<如每10 分钟收取3.3元)。出租车继续行驶时,停止计算等候费用,继续增加里程计费。到达目的地,便可按显示的数字收费。然后关闭计费器,对计数器清零,等待下次计费开始。
由stc15f2k60s2作为主控制芯片,并连接按键系统和lcd1602显示系统,用电机来模拟车轮的转动,通过霍尔传感器对单片机输入一个脉冲,一个脉冲待变车轮转动一周,假设转动一周的距离为0.01km,由此来判断出租车行驶的距离,从而计算出乘客应付的价钱。
在司机等待时按下等待按键,则计时器开始工作,等待10分钟则开始加价,停止等待时,页面会自动返回到初始计价页面,等待价钱和时间不清零,结束计价时则把等待价钱和显示价钱一起算。
本次设计利用单片机技术来实现一台出租车计价器,具有性能可靠、电路简单、成本低等特点。本次设计所设计的出租车计价器的主要功能有:数据的复位、白天/晚上转换、数据输出、计时计价、单价输出及调整、路程输出、等功能。输出采用LCD1602液晶。本电路设计的计价器不但能实现基本的计价,而且还能根据白天、黑夜、中途等待来调节单价,

第二章 硬件电路设计

2.1按键电路
采用独立式键盘,每个按键占用一个I/O口,每个按键相对独立,I/O口通过按键与地相连,无键按下时,引脚端为高电平,有键按下时,引脚端为低电平。所以可以通过判断每个引脚端是否为低电平,就可以知道是否有键按下。图2.1为按键电路。

图2.1  按键电路

S1:接P1.0口,开始计费和结束计费按键,按单次为开始计费,按双次为结束计费。
S2:接P1.1口,是暂停按键,按下后,开启定时器0,LCD1602会开始显示等待时间并且在等待开始十分钟后开始增加等待价钱,在按下结束键之前,等待时间和金钱不会清零。
S3:接P1.2口,是设置按键,在结束计价的时候,按一次,对起步价可以进行调整;按两次,对等待10分钟的等待价钱可以进行调整;按三次,对晚上可以单价进行调整;按四次,可以对白天单价进行调整;按第五次时,回到初始界面,然后循环。
S4:接P1.3口,是用来调整单价增加的键。
S5:接P1.4口,是用来调整单价减少的键。
S6:接P1.5口,复位键,按下之后所有的数据恢复到刚开始的状态。

2.2直流电机电路

该直流电机主要是通过驱动芯片L298来驱动,这款芯片可以同时驱动2个直流电机,可以用直流电或PWM脉冲波驱动第5,7脚为控制电机的正反转,一个接负电压,一个接正电压,第6脚ENA控制电机的转速,通过PWM可以控制转速,.这里我们给它-一个高电平就可以了。直流电机电路如图2.2所示。

图2.2 直流电机电路

2.3显示电路

2.3.1 LCD1602的基本参数及引脚功能

引脚功能说明:
1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表1所示。

2.4脉冲输入电路

利用霍尔传感器来对单片机输入一个脉冲,从而计算出租车行驶的路程,将霍尔传感器接到单片机外部中断0上,触发中断,计算公里数。
由于A44E属于开关型的霍尔器件,其工作电压范围比较宽<4.5~18V),其输出的信号符合TTL电平标准,可以直接接到单片机的I0端口上,而且其最高检测频率可达到1MHz。
A44E集成霍耳开关由稳压器A、霍耳电势发生器(即硅霍耳片>B、差分放大器C、施密特触发器D和0CI门输出E五个基本部分组成。
如图2.4所示为霍尔传感器连接电路。

图2.4  霍尔传感器连接电路

2.5 STC15F2K60S2的引脚连接和说明

2.5.1 STC15F2K60S2的引脚连接

P2口连接LCD1602D0-D7口;
P0.0连接LCD1602RS口,P0.1连接LCD1602的R/W口,P0.2连接LCD1602的EN口;
P1.0-P1.5为按键连接口;
P3.2为外部中断0连接口,连接霍尔传感器输入端,向单片机输入脉冲来计算行车途中的行驶里程;
P3.0和P3.1口连接驱动芯片L298N的输入端IN1和IN2,用来控制电机转动和停止,用来模仿出租车的行驶和停止。
如图2.5为STC15F2K60S2的引脚连接图:

图2.5 STC15F2K60S2的引脚连接图

第三章 软件设计

3.1 单片机资源利用

在本次设计中电路键盘用到了P1口,其中P1.0口到P1.5口作为键盘的输入,显示电路用到了P0口和P2口,P2口为液晶的数据口,P3.2口作为脉冲的输入端。
3.2单片机软件模块设计
如图3.1所示为总体软件设计流程图。
如图3.2所示为外部中断0计算路程流程图。
如图3.3所示为按键子函数流程图。
如图3.4 定时器T0计时收费流程图。



图3.3 按键子函数流程图


在软件设计中,用T0来计时,当汽车停下来等待时,出租车司机则按下等待键,开启定时器T0,定时器每次定50ms,定20次就是1s,此时miao就加一,当miao=59时,执行miao=0,fen++;当fen=59时,执行fen=0,shi++;接下来判断fen是否>=10?若>=10,计价器就按收费标准开始计算价钱。如图3.3为定时器T0计时收费流程图。

图3.4 定时器T0计时收费流程图

第四章 总结

本款出租车计价器有不少功能,其中包括单价输出、单价调整、路程输出、显示途中等待时间和相应的价钱、显示总价等功能。另外,这个出租车计价器还具有性能可靠、电路简单、成本低、实用性强等特点。

单片机源程序如下:
  1. #include<reg51.h>
  2. #include<LCD1602.h>

  3. #define uchar unsigned char
  4. #define uint  unsigned int


  5. sbit key_start =P1^0;         //开始/结束计价
  6. sbit key_wait  =P1^1;         //等待
  7. sbit key_set   =P1^2;         //设置
  8. sbit key_jia   =P1^3;         //加值
  9. sbit key_jian  =P1^4;         //减值
  10. sbit key_dn    =P1^5;   //控制白天晚上
  11. sbit key_fuwei =P1^6;  //复位
  12. sbit mod=P1^7;          //电机控制


  13. /************************——变量定义***********************/
  14. uint start_price=77;                //起步价
  15. uint white_price=66;         //白天的单价   超过3公里每公里6元
  16. uint black_price=88;        //夜晚的单价   超过3公里每公里8元
  17. uint Wait_price=100;                //等待价钱
  18. bit dnc=0;                   //白天晚上的转换标志
  19. bit qiting;                 //起 停标志位   
  20. uint price1,price2;                           //总价钱、等待价钱
  21. uint   mil;                //里程数

  22. uint mil2;               

  23. uchar shi,fen,miao;
  24. uchar  moshi,moshi2,ms,set_f;                                //模式mos=0初始界面,=1改价页面,=2等待页面           
  25.                                 //set_f设置标志=1设置初始价格,=2设置等待价格,=3设置晚上单价,=4设置白天单价

  26. void delay(uchar ms)        //延时函数
  27. {
  28.    uchar j;
  29.          while(ms--)
  30.          {
  31.           for(j=0;j<130;j++);
  32.          }
  33. }

  34. void key()        //按键函数
  35. {  
  36.                         if(key_dn==0)
  37.                                  {
  38.            delay(5);   //延时去抖
  39.                                          if(key_dn==0)
  40.                                           {
  41.              while(!key_dn);
  42.                                                  dnc=~dnc;                                                
  43.             }
  44.          }
  45.         if(key_start==0)
  46.                                  {
  47.            delay(5);
  48.                                          if(key_start==0)
  49.                                           {
  50.              while(!key_start);   //检测按键是否松开
  51.                                                  qiting=~qiting;      //起 停 转换
  52.                                                  if(qiting==0)         
  53.                                                    {
  54.                 moshi=0;
  55.                }
  56.               mod=~qiting;         //电机打开/关闭
  57.                                                         TR0=qiting;          //定时器0打开/关闭
  58.               set_f=0;                                                         
  59.             }
  60.          }
  61.                                  if(key_fuwei==0)          //复位
  62.                                  {
  63.            delay(5);
  64.                                          if(key_fuwei==0)
  65.                                           {
  66.              while(!key_fuwei);
  67.                                                  miao=0;fen=0;shi=0;
  68.                                                  price1=0;price2=0;        mil=0;moshi=0;
  69.             }
  70.          }
  71.                                 if(key_wait==0)
  72.                                 {
  73.                                  delay(5);
  74.                                  if(key_wait==0)
  75.                                  {
  76.                                   while(!key_wait);
  77.                                         miao=0;fen=0;shi=0;
  78.                                         moshi=2;
  79.                                  }
  80.                                 }        
  81.                                          
  82.                                 if(qiting==0)         //结束计价后才能设置
  83.                                 {                                       
  84.                                 if(key_set==0)
  85.                                  {
  86.            delay(5);
  87.                                          if(key_set==0)
  88.                                           {
  89.              while(!key_set);
  90.                                                  set_f++;
  91.                                                  moshi=1;
  92.              if(set_f==5){moshi=0;set_f=0;}                                                        
  93.             }
  94.          }
  95.         if(set_f!=0)
  96.                                  {
  97.          if(key_jia==0)
  98.                                  {
  99.            delay(5);
  100.                                          if(key_jia==0)
  101.                                           {
  102.              while(!key_jia);
  103.                                      if(set_f==1){if(start_price<999)start_price++;}
  104.                                                  if(set_f==2){if(Wait_price<999)Wait_price++;}
  105.                                                  if(set_f==3){if(black_price<999)black_price++;}
  106.                                                  if(set_f==4){if(white_price<999)white_price++;}
  107.             }
  108.          }
  109.                                  if(key_jian==0)
  110.                                  {
  111.            delay(5);
  112.                                          if(key_jian==0)
  113.                                           {
  114.              while(!key_jian);
  115.                                      if(set_f==1){if(start_price>0)start_price--;}
  116.                                                  if(set_f==2){if(Wait_price>0)Wait_price--;}
  117.                                                  if(set_f==3){if(black_price>0)black_price--;}
  118.                                                  if(set_f==4){if(white_price>0)white_price--;}
  119.             }
  120.          }
  121.          }
  122.                          }
  123.       }

  124. void xianshi()
  125.      {
  126.                          if(moshi!=moshi2)   
  127.                           {
  128.           lcd_wcmd(0x01);       //清显示屏        
  129.                                         moshi2=moshi;
  130.         }                                 
  131.                          if(moshi==0)
  132.                          {        
  133.          lcd_wcmd(0x80);
  134.                          lcd_data('N');
  135.        lcd_data('J');        
  136.                          lcd_data(':');
  137.                          lcd_data(ASCII[black_price%1000/100]);
  138.                          lcd_data(ASCII[black_price%100/10]);
  139.                          lcd_data('.');
  140.                          lcd_data(ASCII[black_price%10]);

  141.                                  
  142. //       lcd_wcmd(0x80);
  143. //                         lcd_data('D');
  144. //       lcd_data('J');        
  145. //                         lcd_data(':');
  146. //                         lcd_data(ASCII[white_price%1000/100]);
  147. //                         lcd_data(ASCII[white_price%100/10]);
  148. //                         lcd_data('.');
  149. //                         lcd_data(ASCII[white_price%10]);
  150. //                         lcd_data('Y');
  151.                          lcd_data('G');
  152.                          lcd_data(':');  
  153.                          lcd_data(ASCII[mil%1000/100]);
  154.                          lcd_data(ASCII[mil%100/10]);
  155.                          lcd_data('.');
  156.                          lcd_data(ASCII[mil%10]);
  157.                          lcd_data('K');
  158.                          lcd_data('M');         
  159.                          lcd_wcmd(0x80+0x40);
  160.                          lcd_data('D');
  161.        lcd_data('J');        
  162.                          lcd_data(':');
  163.                          lcd_data(ASCII[white_price%1000/100]);
  164.                          lcd_data(ASCII[white_price%100/10]);
  165.                          lcd_data('.');
  166.                          lcd_data(ASCII[white_price%10]);
  167.                          lcd_data('Y');
  168.                          lcd_data('Y');
  169.        lcd_data('Q');        
  170.                          lcd_data(':');
  171.                          lcd_data(ASCII[price1%1000/100]);
  172.                          lcd_data(ASCII[price1%100/10]);
  173.                          lcd_data('.');
  174.                          lcd_data(ASCII[price1%10]);
  175.                          lcd_data('O');
  176.                          lcd_data('Y');
  177.                          }
  178.                         if(moshi==1)       //改价页面
  179.                          {                                 
  180.        lcd_wcmd(0x80);
  181.                          lcd_data('S');
  182.        lcd_data('J');        
  183.                          lcd_data(ASCII[start_price%1000/100]);
  184.                          lcd_data(ASCII[start_price%100/10]);
  185.                          lcd_data('.');
  186.                          lcd_data(ASCII[start_price%10]);
  187.                          lcd_data('Y');
  188.                          lcd_data(' ');  
  189.                          lcd_data('P');
  190.                          lcd_data('T');

  191.                          lcd_data(ASCII[Wait_price%1000/100]);
  192.                          lcd_data(ASCII[Wait_price%100/10]);
  193.                          lcd_data('.');
  194.                          lcd_data(ASCII[Wait_price%10]);
  195.                          lcd_data('Y');
  196.                           
  197.                          lcd_wcmd(0x80+0x40);
  198.                          lcd_data('N');
  199.        lcd_data('J');        
  200.                          lcd_data(ASCII[black_price%1000/100]);
  201.                          lcd_data(ASCII[black_price%100/10]);
  202.                          lcd_data('.');
  203.                          lcd_data(ASCII[black_price%10]);
  204.                          lcd_data('Y');
  205.        lcd_data(' ');        
  206.              lcd_data('D');
  207.        lcd_data('J');        
  208.                          lcd_data(ASCII[white_price%1000/100]);
  209.                          lcd_data(ASCII[white_price%100/10]);
  210.                          lcd_data('.');
  211.                          lcd_data(ASCII[white_price%10]);
  212.                          lcd_data('Y');
  213.                          }
  214.                          if(moshi==2)       //等待页面
  215.                           {
  216.                                 
  217.         lcd_wcmd(0x80);
  218.                          lcd_data('W');
  219.        lcd_data('a');        
  220.                          lcd_data('i');
  221.                          lcd_data('t');        
  222.                          lcd_data(':');
  223.                          lcd_data(' ');
  224.                          lcd_data(' ');
  225.         
  226.                          lcd_data(ASCII[shi%100/10]);
  227.                          lcd_data(ASCII[shi%10]);
  228.                          lcd_data(':');
  229.                          lcd_data(ASCII[fen%100/10]);
  230.                          lcd_data(ASCII[fen%10]);
  231.                          lcd_data(':');
  232.                          lcd_data(ASCII[miao%100/10]);
  233.                          lcd_data(ASCII[miao%10]);
  234.                
  235.          
  236.                          lcd_wcmd(0x80+0x40);
  237.                          lcd_data('D');
  238.        lcd_data('D');        
  239.                          lcd_data('M');
  240.                          lcd_data(':');
  241. //                         lcd_data(ASCII[(white_price/2)%1000/100]);
  242. //                         lcd_data(ASCII[(white_price/2)%100/10]);
  243.                          lcd_data(ASCII[price2%1000/100]);
  244.                          lcd_data(ASCII[price2%100/10]);
  245.                          lcd_data('.');
  246.                          lcd_data(ASCII[price2%10]);
  247.                          //lcd_data(ASCII[(white_price/2)%10]);
  248.                          lcd_data(' ');
  249.                          lcd_data('Y');
  250.         }  
  251.      }
  252.                  
  253. void jiaqianjisuan()         //计算价钱
  254.       {
  255.                                 if(dnc==0)   //白天价钱
  256.                                 {        
  257.                                 if(mil>30)
  258.                                  {        
  259.           price1=(white_price*((mil-30)/10));
  260.                                   price1=price1+start_price+price2;        
  261.                                  }
  262.                                 else
  263.                                  price1=start_price+price2;        
  264.                          }        
  265.        else         //晚上价钱
  266.                          {
  267.          if(mil>30)
  268.                                  {        
  269.           price1=(black_price*((mil-30)/10));
  270.                                   price1=price1+start_price+price2;        
  271.                                  }
  272.                                 else
  273.                                  price1=start_price+price2;        
  274.        }        
  275.                         
  276.              }                 

  277. void T0_init()                   //定时器0初始化
  278.                   {
  279.                 EA=1;                  //开总中断
  280.                 ET0=1;                 //定时器T0中断允许         
  281.                 TMOD=0x01;             //使用定时器T0的模式1
  282.                                         TH0=(65536-50000)/256; //定时器T0的高8位赋初值
  283.                                         TL0=(65536-50000)%256; //定时器T0的低8位赋初值
  284.                                         TR0=0;                                         //关闭定时器0
  285.                                   EX0=1;                 //外部中断0允许位
  286.                                   IT0=1;                 //下降沿触发外部中断
  287.       }
  288.                  
  289. void main()
  290. {
  291.         lcd_init();           //LCD1602初始化

  292.         T0_init();           //定时器0初始化
  293. while(1)                                                         //死循环
  294.         {
  295.         
  296.                   jiaqianjisuan();
  297.                    key();                        //按键检测处理
  298.             xianshi();
  299.                  
  300.   }
  301. }

  302. void timer0() interrupt 1                  //定时器0中断函数
  303.    {
  304.      TH0=(65536-50000)/256;
  305.      TL0=(65536-50000)%256;                //定50ms
  306.      ms++;
  307.      if(ms>=20)
  308.            {
  309.             ms=0;
  310.             miao++;
  311.                   if(moshi==0)
  312. ……………………

  313. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载(仿真+代码):
最终程序.7z (1.45 MB, 下载次数: 292)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏8 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:922223 发表于 2021-5-18 10:55 | 只看该作者
程序用Keil5才能打开
回复

使用道具 举报

板凳
ID:1013449 发表于 2022-4-3 20:15 | 只看该作者
用Proteus8.8版本才能打开仿真
回复

使用道具 举报

地板
ID:992347 发表于 2022-6-29 15:58 | 只看该作者
Bug有点多,等待那块,还有白天夜晚那块,有些问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表