找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3121|回复: 7
收起左侧

恳求前辈们帮我看看,超声波避障小车跑太快,不会PWM调速,请指教,这是我代码

[复制链接]
ID:130125 发表于 2016-8-3 10:14 | 显示全部楼层 |阅读模式
#include<reg52.h>         用的是LM298N驱动

#include <intrins.h>
sbit RX=P2^1;    echo接口
sbit TX=P2^0;    trig接口

sbit K1=P1^0;
sbit K2=P1^1;
sbit K3=P1^2;
sbit K4=P1^3;

unsigned int  time=0;
unsigned int  timer=0;
unsigned char posit=0;
unsigned long S=0;
bit      flag =0;
//--定义使用的IO--//
#define GPIO_DIG P0

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

//--定义全局变量--//
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char disbuff[4]       ={ 0,0,0,0,};
/*******************************************************************************
* 函 数 名         : DigDisplay
* 函数功能           : 使用数码管显示
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void DigDisplay()
{
    unsigned char i;
    unsigned int j;
    for(i=0;i<8;i++)
    {
        switch(i)     //位选,选择点亮的数码管,
        {
            case(0):
                LSA=0;LSB=0;LSC=0; break;//显示第0位
            case(1):
                LSA=1;LSB=0;LSC=0; break;//显示第1位
            case(2):
                LSA=0;LSB=1;LSC=0; break;//显示第2位
            case(3):
                LSA=1;LSB=1;LSC=0; break;//显示第3位
            case(4):
                LSA=0;LSB=0;LSC=1; break;//显示第4位
            case(5):
                LSA=1;LSB=0;LSC=1; break;//显示第5位
            case(6):
                LSA=0;LSB=1;LSC=1; break;//显示第6位
            case(7):
                LSA=1;LSB=1;LSC=1; break;//显示第7位   
        }
        GPIO_DIG=disbuff;//发送段码
        j=10;                         //扫描间隔时间设定
        while(j--);   
        GPIO_DIG=0x00;//消隐
    }
}
/********************************************************/
    void Conut(void)
    {
     time=TH0*256+TL0;
     TH0=0;
     TL0=0;
   
     S= (long)(time*0.17);     //算出来是CM
     if((S>=4000)||flag==1) //超出测量范围显示“ERR0”
     {     
      flag=0;
      disbuff[0]=0x3f;       //“-”
      disbuff[1]=0x50;       //“-”
      disbuff[2]=0x50;       //“-”
      disbuff[3]=0x79;       //“-”
     }
     else
     {
      disbuff[3]=DIG_CODE[S%10000/1000];
      disbuff[2]=DIG_CODE[S%1000/100];
      disbuff[1]=DIG_CODE[S%100/10];
      disbuff[0]=DIG_CODE[S%10/1];
     }
    }

    void qudong()    小车驱动程序
    {
   
     
      K1=0;
      K2=1;

      K3=1;
      K4=0;
     
    }

    void stop()   电机停止
    {
     K1=0;
     K2=0;K3=0;
     K4=0;
    }

    void left()  左转
    {
     K1=0;
     K2=0;

     K3=1;
     K4=0;
    }

void Delay(unsigned int a)//0~65535
{
    unsigned char b;
    for(;a>0;a--)
    {
        for(b=110;b>0;b--);
    }
}
/********************************************************/
     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;
     }
  }
/*********************************************************/

    void  main(  void  )

  {  
    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;               //开启总中断

    while(1)
    {
     while(!RX);        //当RX为零时等待
     TR0=1;                //开启计数
     while(RX);            //当RX为1计数并等待
     TR0=0;   
      qudong();            //关闭计数
     Conut();
     
     qudong();
     if(S>400)
      {left();
      }
      if(S<650)
      {stop();}            //计算
    }

  }

回复

使用道具 举报

ID:135860 发表于 2016-8-3 11:23 | 显示全部楼层
PWM不行可以用延时来试试看
回复

使用道具 举报

ID:130125 发表于 2016-8-3 17:15 | 显示全部楼层
鹅鹅鹅111 发表于 2016-8-3 11:23
PWM不行可以用延时来试试看

请问在那块加延时啊?
回复

使用道具 举报

ID:130196 发表于 2016-8-4 14:17 来自手机 | 显示全部楼层
用T2定时器做PWM
回复

使用道具 举报

ID:136154 发表于 2016-8-6 16:21 | 显示全部楼层
PWM调速无非就是控制它的占空比
回复

使用道具 举报

ID:136154 发表于 2016-8-6 16:22 | 显示全部楼层
不要用死循环延时 你只要在定时器中断里面判断就可以了
回复

使用道具 举报

ID:113415 发表于 2016-8-6 16:55 | 显示全部楼层
应当选用带有PWM模块的单片机,会省劲一点。用普通的IO端,再以软件模拟PWM也可以,但你要对PWM非常熟悉才行。
回复

使用道具 举报

ID:136168 发表于 2016-8-6 19:22 | 显示全部楼层
做一下延时吧
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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