找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机出租车计价器程序

[复制链接]
跳转到指定楼层
楼主

1. 用前4位数码管实时显示里程数(Z),单位为公里,最后一位为小数位;用后4位数码管时时显示金额数(J),单位为元,最后一位为小数位。
2. 规定出租车单程价格为2元/公里,往返则价格为1.5元/公里;单程/往返分别由“单程” 按键和“往返” 按键设定。
3. 车速<5公里/小时的时间累积为总等待时间T(分钟),每5分钟等待时间相当于里程数增加1公里。
4. 起步公里数为3公里,价格为8元;若实际运行大于3公里, 按“设计任务2”计算价格。
5. 必须充分利用比赛指定的硬件平台上的资源进行设计。
6. 用单片机控制电机转动,并用光电传感器检测转盘转动模拟车速,车速与转盘转速成正比。转盘转速为5转/秒对应车速为5公里/小时,转盘转速为50转/秒对应车速为50公里/小时,依此类推。
7. 要求公里数检测误差不超过±10%。
8. 到达目的地后,按“暂停” 键,计价器可暂停计价。
9. 按“清除” 键,计价器能将记录数据(里程、等待时间与价格等)自动清0。
10.按“查询”键,能自动显示总等待时间T,再按下该键回到显示里程数、金额状态。
1.2系统工作原理及其组成
出租车计价是根据车所行驶的路程以及乘客乘车的方式综合决定的。出租车行驶总路程可以通过车轮的周长乘车轮旋转圈数得到。即可计算得到车轮旋转几周出租车能行驶一公里的路程。因此,使用槽型光耦的目的就是方便地计量车轮旋转的圈数。可在车轮转轴涂上白色条纹,其余部分涂成黑色,发光管照射转轴。当转轴转动时,反光与不反光交替出现,所以槽型光耦间断地接收光的反射信号,输出电脉冲。再经过整形电路,输出标准TTL信号。输出的脉冲信号被接入到STC89C52单片机系统中,通过计算接收到的脉冲个数,计算出当前所行驶的路程。同时,根据不同的收费标准,选择相应的起步价、单价等收费标准进行计算。HD 7279管理键盘和数码显示,通过键盘能够实现启动、暂停、停止计价器、切换显示当前的行驶里程和需支付的车费。
出租车计价器用于记录里程、等待时间、是否往返、起步公里数与价格的关系,它能有效地避免司机与乘客间的矛盾,保障双方的利益。
模拟出租车计价器能根据总里程数、总等待时间长短、是否往返、起步公里数的情况作出相应报价等。当然实际的出租车计价器还具有能打印出车票等功能
1 单片机最小系统单元主控机系统采用了Atmel 公司生产的 STC89C52单片机,它含有256 字节数据存储器,内置8K 的电可擦除FLASH ROM,可重复编程,大小满足主控机软件系统设计,所以不必再扩展程序存储器。复位电路和晶振电路是STC89C52 工作所需的最简外围电路。单片机最小系统电路图如图2.1所示。
主控机系统采用了Atmel 公司生产的 STC89C52单片机,它含有256 字节数据存储器,内置8K 的电可擦除FLASH ROM,可重复编程,大小满足主控机软件系统设计,所以不必再扩展程序存储器。复位电路和晶振电路是STC89C52 工作所需的最简外围电路。单片机最小系统电路图如图2.1所示。
file:///C:/Users/WF/AppData/Local/Temp/msohtmlclip1/01/clip_image002.gif
图2.1 单片机最小系统图
STC89C52的复位端是一个史密特触发输入,高电平有效。RST端若由低电平上升到高电平并持续2个周期,系统将实现一次复位操作。在复位电路中,按一下复位开关就使在RST端出现一段时间的高电平,外接11.0592M 晶振和两个30pF 电容组成系统的内部时钟电路
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
/*7279指令*/
#define com_read  0x15      //读键盘数据指令
/*变量及I/O口定义 */                                               
sbit cs= P1^0;               //cs  连接于 P1.0,低电平有效
sbit clk=P1^1;               //clk 连接于 P1.1
sbit key=P1^3;               //dat 连接于 P1.2
sbit dat=P1^2;               //key 连接于 P1.3,低电平有效   
/*函数原型声明 */
voidwrite7279(uchar,uchar);   //写入到HD7279
uchar read7279(uchar);         //从HD7279读出
void send_byte(uchar);        //发送一个字节
ucharreceive_byte(void);     //接收一个字节
void short_delay(void);       //延时约8us
void long_delay(void);        //延时约50us
void delay_10ms(uchartimes);  //延时约times*10ms
void delay_1ms(uchar times);  //延时约times*1ms
void Init_date();
ucharqianwei,baiwei,shiwei,gewei;
uint tt,aa,aaa,wait,dengdai,gongli,jiage,jg;
bit flag0,flag1,flag2,flag3;
uchar led[]={0x1c,0x1d,0x1e,0x1f,0x14,0x15,0x16,0x17,
                0x0c,0x0d,0x0e,0x0f,0x04,0x05,0x06,0x07};    //键值编码s0-s15
/*发送字节函数 发送的字节为out_byte*/
void send_byte(ucharout_byte)
  {
      uchar i;
      cs=0;
      long_delay();
      for(i=0;i<8;i++)
         {
          if(out_byte&0x80)
              dat=1;
           else
              dat=0;
           clk=1;
           short_delay();
           clk=0;
           short_delay();
           out_byte=out_byte*2;   //左移一位
         }
      dat=0;
  }
/*接收字节函数 接收的字节in_byte*/
uchar receive_byte(void)
  {
    uchar i,in_byte;
    dat=1;                        
    long_delay();
    for(i=0;i<8;i++)
       {
         clk=1;
         short_delay();
         in_byte=in_byte*2;
         if(dat)
           in_byte=in_byte|0x01;
         clk=0;
         short_delay();
       }
    dat=0;   
    return(in_byte);
  }
/*发送带数据指令函数*/
void write7279(ucharcommond,uchar date)
  {
    send_byte(commond);
    send_byte(date);
  }
/*读指令函数*/
uchar read7279(ucharcommond)
  {
     send_byte(commond);
     return(receive_byte());
   }
/*短延时函数1*/
void short_delay(void)            //延时约8us
  {
    uchar i;
    for(i=0;i<2;i++);
  }
/*短延时函数2*/
void long_delay(void)             //延时约50us
  {
     uchar i;
     for(i=0;i<12;i++);
   }
void zting()                  //停止子程序
   {
       flag1=!flag1;
       if(flag1)  
       {
           EX0=0;       //关闭中断  定时器
           TR0=0;
       }
       else
       {
           EX0=1;
           TR0=1;
       }
   }
uchar   read_key_code(void)  //读键值
{
    uchar i_code;
    if(!key)
    {
       i_code=read7279(0x15);
       while(!key);       //消除键盘抖动
       return i_code;        //读键盘值  
    }
    else
       return 0xff;         //无键盘按下
}
uchar read_key_number(void)   //读键盘号
{
    uchar l_o;
    uchar i;
    l_o=read_key_code();
    if(l_o!=0xff)          //判断是否有键盘按下
    {
    for(i=0;i!=l_o;i++);
    return i;
    }
    else return 0xff;
}
void keyscan()
{
    uchar k_p;
    k_p=read_key_number();            //读键值号 选择相应的操作
    switch(k_p)
    {
       case 12: flag0=!flag0;break; //显示金额 公里 等待时间T 脉冲数   
       case 13: Init_date();break; //数据初始化函数
       case 14: zting();break;     //暂停
       case 15: flag2=1;break;       //单程
       case 11: flag2=0;break;       //往返
       default :break;
    }
}
void jisuan()     //计算数据处理
{
    if(0<=aaa<=180)           
    {
       gongli=aaa/6+dengdai/3000;
       jiage=60;       //60角
    }
    if(!flag2) jg=20;  //单程价格
    jg=15;          //往返价格
    if(aaa>180)
    {      
       gongli=aaa/6+dengdai/3000;
       jiage=jg*(gongli-30)/10+60;
    }
   
    wait=dengdai/100;
}
void fenli(uint temp,uchardd,uchar ee,uchar ff,uchar gg)    //数据的分离处理
{
    if(temp>=9999) temp=9999;
    qianwei=temp/1000;
    baiwei=temp/100%10;
    shiwei=temp%100/10|0x80;
    gewei=temp%10;
    write7279(dd,qianwei);
    write7279(ee,baiwei);
    write7279(ff,shiwei);
    write7279(gg,gewei);
}
void display()      //7279显示程序
{
    if(flag0)
    {
       write7279(0x98,0xff);
       fenli(wait,0x87,0x86,0x85,0x84);
       fenli(aaa,0x83,0x82,0x81,0x80);    //显示脉冲数
    }
    else
    {
           write7279(0x98,0xff);
           fenli(gongli,0x87,0x86,0x85,0x84);
           fenli(jiage,0x83,0x82,0x81,0x80);
           
    }}
void Init_date()              //数据初始化
{               
           
           aaa=0;
           tt=0;
           wait=0;
           dengdai=0;
           gongli=0;
           jiage=0;
           flag0=0;
           flag1=0;
           flag2=0;
           flag3=0;
}
void init()                           //定时器初始化  
{
    TMOD=0x01;
    TH0=(65536-10000)/256;
    TL0=(65536-10000)%256;
    IE=0x83;
    IT0=1;   //外部边沿触发方式
    TR0=1;
}
void main()                 //主程序
{
    Init_date();       //调用数据初始数据
    init();               //定时器初始化
    send_byte(0xa4);  //初始化7279
    while(1)
    {
       keyscan();     //键盘扫描
       jisuan();      //数据处理
       display();      //显示
    }
}
/**********中断***********/
void zd() interrupt 0        //中断0
{
    aa++;
    if(flag3)     aaa++;      //进入中途等待计价
}
/*********定时器********/
void time0() interrupt 1   //定时0
{
    TH0=(65536-10000)/256;      //10ms
    TL0=(65536-10000)%256;
    tt++;
    if(tt>=100)          //1s采样
    {
       tt=0;
       aa=aa/5;     //速度(n*圈/s)
       if(aa<=5)    flag3=0;
       else            flag3=1;
       aa=0;
    }
    if(!flag3)
    {   dengdai++;
    }
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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