中断时部分子程序不执行是为什么?

2020-01-17 19:11发布

程序的问题是当漫反射接收到信号,向单片机P3^2脚发出低电平时,86步进电机没有按照程序转动,有大神能告诉我是为什么?
源程序奉上
#include <reg52.h>
#include <intrins.h>   

#define uch unsigned char
#define uint unsigned int

sbit get = P3^2;//转盘得物信号
sbit ULR = P0^1;//脉冲脚
sbit DIR = P0^2;//方向脚
sbit OE = P0^3;//74LS573 锁存器芯片输出使能

int volue = 0;//转动标志位
char t; //86电机循环用变量

uch idata buf[8];  //接收字符串用的数组

//**********************正向旋转相序表*****************************
unsigned char code FFW[9]=
{0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09,0X00};  
//28 BYJ-48 小电机正转相序表
// 上履带电机
unsigned char code FFW1[9]=
{0x80,0xc0,0x40,0x60,0x20,0x30,0x10,0x90,0X00};
//下履带电机
//**********************履带步进电机正转******************************

void receive (uch idata * d) //串口接收数据子程序
{
        int i; // 循环用的局部变量
        while(RI == 0);
        //用while语句确定已经接收完一组数据
        for(i=0; i<10; i++)
        {
                d[i] = SBUF; //把数据缓冲器的值写到定义的数组里
        }
        if(d[0] == 1)
        {
                volue = 1;         //转盘用的86电机,转动角度标志//45°
        }
        if(d[0] == 2)
        {
                volue = 2;         //同上 //0°
        }
        RI = 0;        //软件复位,为下次串口接收做准备
}

void delay(void)   //软件生成误差 0us          //控制上履带电机频率
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=2;b>0;b--)
            for(a=197;a>0;a--);
}

void mdelay(void)                //86电机的脉冲频率 //软件计算误差0us;
{
        unsigned char a,b;
          for(b=185;b>0;b--)
      for(a=12;a>0;a--);
}

void motor_ffw(unsigned int n)         //上履带电机正向转动程序
{
   uch i;          //循环用局部变量
   uint j;          //循环用局部变量
   for (j=0; j<8*64*n; j++)          //电机减速比1/64,消除转速比,8脉冲一圈,n为圈数
    {
      for (i=0; i<8; i++)
        {
                P1 = FFW[i];                //P1口高8位控制上履带电机正转
                 delay();
        }
    }
}

void  motor_ffw1(unsigned int n)  //上履带电机正向转动程序
{
   uch i;
   uint j;
   for (j=0; j<8*64*n; j++)
    {
      for (i=0; i<8; i++)
        {
                  P1 = FFW1[i];                  //P1口高8位控制下履带电机正转
                 delay();
        }
    }
}

void go()
{
        motor_ffw(20);                //上履带20圈
}

void go1()        //由于期间会被中断打断并重新触发所以基本可以无视圈数
{
        motor_ffw1(20);                //下履带20圈
}

void init()          //初始化
{         
        OE = 1; //高阻态       
        ULR = 1; //86电机脉冲初始化
        EX0=1;//允许外部中断0       
        IT0=1; //有信号时保持中断,信号撤除中断停止
        SCON = 0X50;  //  0工作方式2,允许接收
        TMOD = 0X20; //          定时器模式,T0,工作方式2       
        PCON = 0X80;  //  波特率翻倍
        TH1 = 0XF3;         //          定时器赋初值
        TH0 = 0XF3;        //          定时器赋初值
        ES = 1;         //          串口中断开启
        EA = 1;         //         总中断开启
        TR1 = 1; //         开启定时器中断
}

void move()        //86电机转动45度程序
{
        for(t=0; t<25; t++)
        {
                ULR = 1;
                mdelay();
                ULR = 0;
                mdelay();
        }
}

//*************************主程序*********************************
void main()
{  
        init();
        go();
}

void wvolue() interrupt 4 // 串口中断  即扫描枪扫描并确定角度程序
{
        receive(buf);
}

void turn() interrupt 0          //转盘转动并送物中断程序
{
        switch(volue)
        {
                case 1:
                {
                  OE = 0;//锁存器输出使能       
              DIR = 1;
                  move();
                  go1();
                  DIR = 0;
                  move();
                  volue = 0;
                  break;
                }
                case 2:
                {
                        OE = 0;//锁存器输出使能       
                        go1();
                        volue = 0;               
                        break;
                }
                default:
                {
                        OE = 0;//锁存器输出使能       
                        DIR = 0;
                        move();
                        go1();
                        DIR = 1;
                        move();
                        volue = 0;       
                        break;
                }
        }
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
25条回答
kebaojun305
1楼-- · 2020-01-20 14:16
 精彩回答 2  元偷偷看……
柯铭凯
2楼-- · 2020-01-20 14:43
kebaojun305 发表于 2016-4-14 14:13
前辈不敢当,那个数字越小,优化程度越低。  0是不优化。

前辈,试了,不顶用,还是不转
kebaojun305
3楼-- · 2020-01-20 19:28
柯铭凯 发表于 2016-4-14 14:57
前辈,试了,不顶用,还是不转

那估计有可能是你写的程序有问题。
柯铭凯
4楼-- · 2020-01-20 22:25
86电机子程序move()不调用的问题我已经解决了,附上源码。
柯铭凯
5楼-- · 2020-01-21 00:39
#include <reg52.h>
#include <intrins.h>   

#define uch unsigned char
#define uint unsigned int

sbit ULR = P0^0;//脉冲脚
sbit DIR = P0^1;//方向脚
sbit OE = P0^2;//74LS573 锁存器芯片输出使能
sbit GET = P3^3;

int volue = 0;//转动标志位

uch idata buf[8];  //接收字符串用的数组

//**********************正向旋转相序表*****************************
unsigned char code FFW[9]=
{0x08,0x0c,0x04,0x06,0x02,0x03,0x01,0x09,0X00};  
//28 BYJ-48 小电机正转相序表
// 上履带电机
unsigned char code FFW1[9]=
{0x80,0xc0,0x40,0x60,0x20,0x30,0x10,0x90,0X00};                  
//下履带电机
//**********************履带步进电机正转******************************
void delay20ms(void)   //误差 0us  //86电机的脉冲频率
{
    unsigned char a,b;                 
    for(b=215;b>0;b--)
        for(a=45;a>0;a--);
}

void move()        //86电机转动45度程序
{
        char t = 0; //86电机循环用变量
        OE = 0;
        for(t=0; t<25; t++)
        {
                ULR = 1;
                delay20ms();
                ULR = 0;
                delay20ms();
        }
}

void receive (uch idata * d) //串口接收数据子程序
{
        if(RI == 0);
        //用while语句确定已经接收完一组数据
        d[0] = SBUF; //把数据缓冲器的值写到定义的数组里
        if(d[0] == '1')
        {
                volue = 1;         //转盘用的86电机,转动角度标志//45°
        }
        if(d[0] == '2')
        {
                volue = 2;         //同上 //0°
        }
        else
        {
                volue = 0;
        }
        RI = 0;        //软件复位,为下次串口接收做准备
}

void delay(void)   //误差 0us   1ms
{
    unsigned char a,b;
    for(b=199;b>0;b--)
        for(a=1;a>0;a--);
}

void motor_ffw(unsigned int n)         //上履带电机正向转动程序
{
   uch i;          //循环用局部变量
   uint j;          //循环用局部变量
   for (j=0; j<8*64*n; j++)          //电机减速比1/64,消除转速比,8脉冲一圈,n为圈数
    {
      for (i=0; i<8; i++)
        {
                P1 = FFW[i];                //P1口高8位控制上履带电机正转
                 delay();
        }
    }
}

void  motor_ffw1(unsigned int n)  //上履带电机正向转动程序
{
   uch i;
   uint j;
   for (j=0; j<8*64*n; j++)
    {
      for (i=0; i<8; i++)
        {
                  P1 = FFW1[i];                  //P1口高8位控制下履带电机正转
                 delay();
        }
    }
}

void go()
{
        motor_ffw(1);                //上履带20圈
}

void go1()        //由于期间会被中断打断并重新触发所以基本可以无视圈数
{
        motor_ffw1(1);                //下履带20圈
}

void init()          //初始化
{         
        OE = 1; //高阻态       
        DIR = 0;
        EX1=1;//允许外部中断0       
        IT1=1; //有信号时保持中断,信号撤除中断停止
        EX0 = 1;
        IT0 = 1;
        SCON = 0X50;  //  0工作方式2,允许接收
        TMOD = 0X20; //          定时器模式,T1,工作方式2       
        PCON = 0X80;  //  波特率翻倍
        TH1 = 0XF3;         //          定时器赋初值
        TL1 = 0XF3;        //          定时器赋初值
        ES = 1;         //          串口中断开启
        EA = 1;         //         总中断开启
        TR1 = 1; //         开启定时器中断
}



//*************************主程序*********************************
void main()
{  
        ULR = 1; //86电机脉冲初始化
        while(1)
        {
                init();
                go();
        }
}

void wvolue() interrupt 4 // 串口中断  即扫描枪扫描并确定角度程序
{
        receive(buf);
}

void turn() interrupt 2          //转盘转动并送物中断程序
{
        switch(volue)
        {
                case 1:
                {
              DIR = 1;
                  move();
                  while(GET == 0)
                  {
                          go1();
                  }
                  DIR = 0;
                  move();
                  volue = 0;
                  break;
                }
                case 2:
                {
                    while(GET == 0)
                        {
                           go1();
                        }
                        volue = 0;               
                        break;
                }
                default:
                {
                        OE = 0;       
                        DIR = 0;
                        move();
                        while(GET == 0)
                    {
                      go1();
                    }
                        DIR = 1;
                        move();
                        volue = 0;
                        break;               
                }
        }

}


void try() interrupt 0          //转盘转动并送物中断程序
{
        move();
}
柯铭凯
6楼-- · 2020-01-21 03:01
 精彩回答 2  元偷偷看……

一周热门 更多>