找回密码
 立即注册

QQ登录

只需一步,快速开始

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

求教用51单片机做的超声波测距小车,数码管扫描和pwm的中断地址重叠了

[复制链接]
跳转到指定楼层
楼主
ID:765385 发表于 2020-6-3 00:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如题,用的是stc89c52单片机,本人新手,想做一个超声波测距小车,已实现测距,但连接小车时,小车不动,数码管闪烁。
希望实现功能:小车可以边运动边测距,距离墙50mm时可以左转,当左转四次后停止。
标红出为中断地址重叠出,希望各位大佬可以给出解决代码,谢谢大家
代码如下
  • #include"reg52.h"
  • #include <intrins.h>
  • sbit IN1=P1^0;
  • sbit IN2=P1^1;
  • sbit IN3=P1^2;
  • sbit IN4=P1^3;
  • sbit L_PWM=P1^4;
  • sbit R_PWM=P1^5;
  • sbit RX=P1^7;
  • sbit TX=P1^6;
  • unsigned int  time=0;
    unsigned int  timer=0;
    unsigned char posit=0;
    unsigned long S=0;
    bit      flag =0;
    //--定义使用的IO--//
    #define GPIO_DIG P0
    #define L_go      IN1=0;IN2=1
    #define L_back    IN1=1;IN2=0
    #define L_stop    IN1=0;IN2=0
    #define R_go     IN3=0;IN4=1
    #define R_back   IN3=1;IN4=0
    #define R_stop   IN3=0;IN4=0
  • #define car_go    L_go;R_go;
    #define car_back   L_back;R_back
    #define car_left   R_go;L_stop
    #define car_right   L_go;R_stop
    #define car_stop   L_stop;R_stop
    #define car_left_360 R_go;L_back
    #define car_right_360 L_go;R_back
  • //定义数码管位选控制信号
    sbit LSA=P2^0;
    sbit LSB=P2^1;
    sbit LSC=P2^2;
    sbit LSD=P2^3;
  • //--定义全局变量--//
    unsigned char code DIG_CODE[17]={
    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
    //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
    unsigned char disbuff[4]    ={ 0,0,0,0,};
    //数据定义
    unsigned char l_tt=0; //定时器计数用
  • unsigned char l_Lpwm=0; //左轮PWM占空比值,我们设计10个格,0-9,0为停止,9为全速
    unsigned char l_Rpwm=0; //右轮PWM占空比值,我们设计10个格,0-9,0为停止,9为全速

  • /*******************************************************************************
    * 函 数 名         : DigDisplay
    * 函数功能     : 使用数码管显示
    * 输    入         : 无
    * 输    出         : 无
    *******************************************************************************/
    void DigDisplay()
    {
    unsigned char i;
    unsigned int j;
    for(i=0;i<4;i++)
    {
      switch(i)  //位选,选择点亮的数码管
      {
       case(0):
        LSA=0;LSB=1;LSC=1;LSD=1; break;//显示第1位
       case(1):
        LSA=1;LSB=0;LSC=1;LSD=1; break;//显示第2位
       case(2):
        LSA=1;LSB=1;LSC=0;LSD=1; break;//显示第3位
       case(3):
        LSA=1;LSB=1;LSC=1;LSD=0; break;//显示第4位
      }
      GPIO_DIG=disbuff[ i];//发送段码
      j=10;       //扫描间隔时间设定
      while(j--);
      GPIO_DIG=0xFF;//消隐
    }
    }
    /********************************************************/
        void Conut(void)
    {
      time=TH0*256+TL0;
      TH0=0;
      TL0=0;

      S= (long)(time*0.17);     //算出来是MM
      if((S>=4000)||flag==1) //超出测量范围显示“ERR0”
      {  
       flag=0;
       disbuff[3]=0xc0;    //“-”
       disbuff[2]=~0x50;    //“-”
       disbuff[1]=~0x50;    //“-”
       disbuff[0]=0x86;    //“-”
      }
      else
      {
       disbuff[0]=DIG_CODE[S%10000/1000];
       disbuff[1]=DIG_CODE[S%1000/100];
       disbuff[2]=DIG_CODE[S%100/10];
       disbuff[3]=DIG_CODE[S%10/1];
      }
    }
    /********************************************************/
         void zd0() interrupt 1    //T0中断用来计数器溢出,超过测距范围
      {
        flag=1;        //中断溢出标志
      }
    /********************************************************/
       void  zd3()  interrupt 3    //T1中断用来扫描数码管和计800MS启动模块
      {
      TH1=0xf8;
      TL1=0x30;
      DigDisplay();
      timer++;
      if(timer>=100)
      {
       timer=0;
       TX=1;                   //800MS  启动一次模块
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       _nop_();
       TX=0;
      }
      }
    /*********************************************************/
    //TIMER0中断服务子函数产生PWM信号
    void timer0()interrupt 1   using 2
    {
    TH0=0XFC;   //定时1毫秒,10格调速,为100HZ频率,此频率下效果比较好,过大有噪声,过小振动大
    TL0=0X17;
    l_tt++;
    if(l_tt>9)l_tt=0; //比较用,10格调速

    if(l_tt<=l_Lpwm){//左调速,占空比数值越大,输出高电平时间越宽,电机转速越高,我们设计10个格,0-9,0为停止,9为全速
       L_PWM=1;
    }
    else{
      L_PWM=0;
    }
    if(l_tt<=l_Rpwm){//右调速,同上
      R_PWM=1;
    }
    else{
      R_PWM=0;
    }
    }
  • [ i]/*********************************************************/
  • [ i] void  main(  void  )
  • [ i]  {  int i=0;
        TMOD=0x11;     //设T0为方式1,GATE=1;
    TH0=0;
    TL0=0;         
    TH1=0xf8;     //2MS定时
    TL1=0x30;
    ET0=1;             //允许T0中断
    ET1=1;      //允许T1中断
    TR1=1;      //开启定时器
    EA=1;      //开启总中断

        car_go;   //前进  
    while(1)
    {
      while(!RX);  //当RX为零时等待
      TR0=1;       //开启计数
      while(RX);   //当RX为1计数并等待
      TR0=0;    //关闭计数
         Conut();   //计算
      if(S<=500)
      {L_go;
      i++;}
      else
      {car_go;}
      if(i==3)
       break;       //左转四次后跳出循环
    }
    car_stop;
      }
  • [ i]谢谢大家

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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