• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

求救:红外控制28BYJ-48

片片见真情 2014-09-03 浏览量:775

如标题,我想用红外遥控器实现控制28BYJ-48电机 正转 反转 停止 三个功能。 但实际效果是遥控器按下去以后电机只工作了一会,之后就停下来了,再按其他键也没有反应。 反复琢磨自己的程序,都觉得没有问题。 故想请大家帮我看看到底是哪里出错了。

#include

sbit A1=P3^0;   
sbit B1=P3^1;
sbit C1=P3^2;
sbit D1=P3^3;      //A1-D1 分别是电机的四个接口,我是通过ULN2003来实现对单片机I/0口输出电压的放大,之后再接给电机。




unsigned char time;
bit n;
bit m;
unsigned char a[33];
unsigned char b[4];
unsigned char i=0;
unsigned char code display[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

bit startflag;
unsigned char time;    //用于定时器中断的时间记录
bit n;                           //外部中断 判别标志 1表示中断发生
bit m;
unsigned char a[33];   //红外接收的33个中断信号
unsigned char b[4];    //解码后的 分别对应引导码 客户码 操作码 操作反码
unsigned char i=0; 
void DelayUs2x(unsigned char t)     //延时函数
{   
 while(--t);
}
void DelayMs(unsigned char t)    //延时函数
{
     
 while(t--)
 {
     //大致延时1mS
     DelayUs2x(245);
DelayUs2x(245);
 }


void timer_inital()     //定时器初始化
{
ET0=1;
TMOD=0x02;
EA=1;
TH0=0;
TL0=0;
TR0=1;
}
void EX0_inital()   //外部中断初始化
{
EA=1;
EX0=1;
IT0=1;
}


void EXO(void)interrupt 0    //外部中断函数 1、把每次中断所用的时间记录到了a[33]里面,以便之后的解码  2、把n置为1来标志中断
{
if(startflag)                         
   {
    if(time<63&&time>=33)    //引导码 遥控器的头码,9ms+4.5ms
                        i=0;
    a[i]=time;                         //存储每个电平的持续时间,用于以后判断是0还是1
    time=0;
    i++;
    if(i==33)
      {
  n=1 ;
i=0;
startflag=0;
m=1;
      }
   }
  else
{
time=0;
startflag=1;
}
}
void timer(void)interrupt 1         //计时器中断函数 记录时间用
{
time++;
}

void codetransmit()                  //解码函数 解码以后的8为二进制存入b[4]中
{
unsigned char j,k,l,y;
l=1;
for(j=0;j<4;j++)
  { 
    for(k=0; k<8;k++)
 {
  y>>=1;
if(a[l]>7)
  y=y|0x80;
l++;
 }
 
b[j]=y;
     y=0;
  }
}

void step1()                           //电机工作函数
{
A1=1;B1=0;C1=0;D1=0;
}
void step2()                       //电机工作函数
{
A1=0;B1=1;C1=0;D1=0;
}
void step3()                      //电机工作函数
{
A1=0;B1=0;C1=1;D1=0;
}
void step4()                     //电机工作函数
{
A1=0;B1=0;C1=0;D1=1;
}

void machine1()             //电机工作函数 正转
{
step1();DelayMs(5);
step2();DelayMs(5);
step3();DelayMs(5);
step4();DelayMs(5);
}
void machine2()             //电机工作函数 倒转
{
step4();DelayMs(5);
step3();DelayMs(5);
step2();DelayMs(5);
step1();DelayMs(5);
}
void machinestop()       //电机工作函数 停止
{
A1=0;B1=0;C1=0;D1=0;DelayMs(5);
}

void work(unsigned char value)    //电机工作
{
switch(value)
   {
case 0x44:             //转码后如果是0x44,则正转
             m=0;
             machine1();
             if(m==1)         //我检查过,发现这里m的值在刚开始的时候为0,当电机停止的时候就置1了,所以电机不会工作了。但是我

                                       怎么都想不通这里m怎么会置1的,又没有发生中断,只有中断发生的时候m才被置1啊。 
                n=1;
             else 
                n=0;
             break;
case 0x40:                   //转码后如果是0x40,则倒转
            m=0;
            machine2();
            if(m==1)
              n=1;
            else 
              n=0;
            break;
case 0x43:                   //转码后如果是0x43,则停止
            m=0;
            machinestop();
            if(m==1)
               n=1;
           else 
              n=0;
           break;
default:break;
   }
}

void main()
{
unsigned char value;
timer_inital();
EX0_inital();

while(1)
  {
   if(n==1)
       {
        codetransmit();
        value=b[2];
        }
   work(value);
   DelayMs(5);
  }
}

0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
所有亮答 数量:3
  • 呵呵 我是做硬件的,用硬件给你分析一下,电机供电和主板是一个电源吗?先用LED替换电机,防止电机干扰造成主板工作不正常,如果LED工作正常,可以排除程序问题。

  • 这个电机模块我有一个,用ULN2003驱动能力太弱了,转速很慢,现在已经送人了,你的问题可能不是程序上,好好看看硬件

    在接ULN2003之前,最好用个缓冲器或者74芯片再放大一下信号

  • 我的问题已经解决了,是硬件的问题,我的程序完全没问题,该程序也可以给其他像我一样的初学者参考

相关问题

问题达人换一批

求救:红外控制28BYJ-48