为什么运行舵机就会导致单片机复位?

2019-07-15 13:22发布

我在做基于舵机调整方向的超声波避障的蓝牙遥控智能小车,用的是stc12c5a60s2单片机,超声波用外部中断和定时器1来测距,舵机用定时器0调整方向,小车的轮子转动是用单片机的内置两路PWM输出的,单独运行超声波时不会影响到PWM的输出,而运行舵机的时候就会导致单片机复位,求大神帮我看看原因啊!
#include<at89x51.h>
#include<STC12C5A60S2_PWM.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int


/***自定义一些数据*/
#define leftdata  0x11
#define rightdata 0x22
#define forwarddata 0x33
#define backdata  0x44
#define stopdata  0x55

/*****接线定义******/
sbit IN1=P1^5;
sbit IN2=P1^6;
sbit IN3=P1^1;
sbit IN4=P1^2;
sbit EN1=P1^3;
sbit EN2=P1^4;

/*****独立波特率发生器专用寄存器*******/
sfr AUXR=0x8e;//AUXR的SFR地址在0x8e
sfr BRT=0x9c;//BRT的SFR地址在0x9C
//*********************************************************************************************************
sbit trig   = P3^2;
sbit echo   = P3^3;
bit flagg; //中断进入标志
#define         ControlPort      P1_0

unsigned char push_val_left = 11;
    unsigned char timeOutCounter=0;   
   float dis=0;

         unsigned char posit=0;
                         unsigned long S=0;
                         unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff};
                         unsigned char const positon[3]={  0xbf,0xdf,0xef};
                         unsigned char disbuff[4]           ={ 0,0,0,0,};

    void Display(void)                                 //扫描数码管
        {
         if(posit==0)
         {P0=(discode[disbuff[posit]])&0x7f;}
         else
         {P0=discode[disbuff[posit]];}
          P2=positon[posit];
          if(++posit>=3)
          posit=0;
        }
void delay_20us()
{  
uchar bt ;
for(bt = 0;bt<10;bt++);       
}
//*************************************************************************************************
void Forward(unsigned char Speed_Right,unsigned char Speed_Left); //申明一个“前进函数”
void Stop(void);//申明一个“停止”函数


unsigned char SBUF_DATA,flag;

//void SendString(unsigned char *pt);
void Send_Char(unsigned char DATA);

//L 左
//R 右

void Forward(unsigned char Speed_Right,unsigned char Speed_Left)//Speed_Right,Speed_Left为左右电机对应的速度参数0-255之间,255最快,0最慢。
{
                 IN1=0;
        IN2=1;
        IN3=0;
        IN4=1;
       
     PWM_Set(255-Speed_Right,255-Speed_Left);
}
void Back(unsigned char Speed_Right,unsigned char Speed_Left)//Speed_Right,Speed_Left为左右电机对应的速度参数0-255之间,255最快,0最慢。
{
          IN1=1;
         IN2=0;
         IN3=1;
         IN4=0;

     PWM_Set(255-Speed_Right,255-Speed_Left);
}
void Turn_Left(unsigned char Speed_Right,unsigned char Speed_Left)
{
    IN1=1;
        IN2=0;
        IN3=0;
        IN4=1;
        PWM_Set(255-Speed_Right,255-Speed_Left);

}
void Turn_Right(unsigned char Speed_Right,unsigned char Speed_Left)
{
    IN1=0;
        IN2=1;
        IN3=1;
        IN4=0;
        PWM_Set(255-Speed_Right,255-Speed_Left);
}
void Stop(void)        //刹车
{

     IN1=0;
         IN2=0;
         IN3=0;
         IN4=0;
         PWM_Set(0,0);
}
void delayuus(unsigned char dela)
{
   while(dela--);
}
void delayms(unsigned char nn)
{
   while(nn--)
   {
   delayuus(245);
   delayuus(245);
   }
}

void test(void)         
{
TH1  = 0x00;
TL1  = 0x00;
trig = 1;

delay_20us();
trig = 0;

while(!echo);
TR1 = 1;
EX1 = 1;
delayms(30);

if(flagg==1)
{                         flagg=0;
                    dis  = (TH1 * 256 + TL1);
                      S=(dis*1.7)/100;     //算出来是CM
         if(S>=700) //超出测量范围显示“-”
         {         
         
          disbuff[0]=10;           //“-”
          disbuff[1]=10;           //“-”
          disbuff[2]=10;           //“-”
         }
         else
         {
          disbuff[0]=S%1000/100;
          disbuff[1]=S%1000%100/10;                                                                                   
          disbuff[2]=S%1000%10 %10;       
          }
}
TH1=0;
TL1=0;
TR1=0;
EX1=0;

}
void ISR_INT1(void) interrupt 2
{
    TR1=0;
    EX1=0;
    flagg=1;
}



void serial() interrupt 4 //中断法
{
        flag=1;        //如果产生了中断,说明单片机串口接收到数据,串口中断标志置1
        SBUF_DATA=SBUF;//将接收到的数据存放到a中
        RI=0;//中断标志
}
void time1()interrupt 1           //舵机PWM输出
  {
          TH0=(65536-125)/256;
        TL0=(65536-125)%256;
        TimeOutCounter ++;
          
        switch(push_val_left)         
        {         
                case 6 :          
                {
                        if( TimeOutCounter <= 7)                //右:7
                        {
                                ControlPort = 1;
                        }
                        else
                        {
                                ControlPort = 0;
                        }
                        break;
                }
                        case 7 :          //
                {
                        if( TimeOutCounter <= 16)                        //左                                                       
                        {
                                ControlPort = 1;
                        }
                        else
                        {
                                ControlPort = 0;
                        }
                        break;
                }
                        case 8 :          //
                {
                        if( TimeOutCounter <= 12)                        //中                                                                 12:中
                        {
                                ControlPort = 1;
                        }
                        else
                        {
                                ControlPort = 0;
                        }
                        break;
                }
       
                default : break;
        }
       
        if( TimeOutCounter == 160 )         //周期20ms(理论值)
        {
                TimeOutCounter = 0;
        }
  }                               



void main(void)
{
unsigned char sudu=130;
    PWM_ini();
        //*****************************************************************************************************
         TMOD=0x11;
        TH1=0x00; //
        TL1=0x00;
        TH0=(65536-125)/256;
        TL0=(65536-125)%256;
                         //TR0=1;
                                ET0=1;
        //*********************************************************************************************************
        SCON=0x50;// 0   1   0   1   0   0  0  0
                  //SM0 SM1 SM2 REN TB8 RB8 TI RI
                          //从上面化成二进制之后可以看到SCON的各位设置
                          //①SMO SM0=01 ,说明串口工作在方式1
                          //②REN=1,允许串口接收数据
        BRT=0xfd;//9600波特率的初值
        AUXR=0x11;//12T,BRTR=1启动独立波特率发生器
              //S1BRS=1,串口1选着独立波特率发生器作为波特率发生器
                    
   PS=1;                                          //中断太多,置串口为高优先级中断

        ES=1;//允许串行中断
        EA=1;//开总中断
        IT1=1;         //IT1=1表示边沿触发
                                TR0=1;
                                push_val_left=8;
                                delayms(240);
                                delayms(240);
                                TR0=0;
                while(1)
                {

                        if(SBUF_DATA==0x15)
                        {
                        TR0=0;
                           test();          //超声波测距
                        Display();                   //数码管显示
                        if(S<=10)
                        {
                                TR0=1;
                                push_val_left=6;
                                delayms(240);
                                delayms(240);
                                        delayms(240);
                                        delayms(240);
       
                                push_val_left=7;
                                delayms(240);
                                delayms(240);
                                delayms(240);
                                delayms(240);
                                delayms(240);
                                delayms(240);
                                TR0=0;
               
                        }
                        else
                        {
                                TR0=0;
                           test();
                        Display();
                        }
                        }
                   if(flag==1)//如果产生过中断,证明串口接收到了数据
                   {                EX1=1;
                     flag=0;
                          
                           switch(SBUF_DATA)          //小车行驶方向控制 pwm
                           {
                                         case leftdata: Turn_Left(sudu,sudu); break;
                                         case rightdata: Turn_Right(sudu,sudu); break;
                                         case forwarddata: Forward(sudu,sudu); break;
                                         case backdata: Back(sudu,sudu); break;
                                         case stopdata: Stop();         break;
                               
                                                 default: break;                                  
                                       
                            }
                  
                   }


                  
                }

}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
陆富进
1楼-- · 2019-07-15 15:15
 精彩回答 2  元偷偷看……
本人新手
2楼-- · 2019-07-15 18:32
舵机和单片机要单独供电
小鸭kity
3楼-- · 2019-07-16 00:03
太复杂
看不懂
小鸭kity
4楼-- · 2019-07-16 03:32
单片机实现不了,但是PLC我能实现了
LYGOK
5楼-- · 2019-07-16 08:41
电源电压波动,干扰单片机

一周热门 更多>