新手入门 
 
	- 积分
 - 3
 
        - 金钱
 - 3 
 
       - 注册时间
 - 2019-3-27
 
      - 在线时间
 - 0 小时
 
 
 
 | 
 
1金钱 
/*NEC协议红外通信 
单片机解码后通过串口以9600的比特率发送出去 
*/ 
 
#include <reg52.h> 
 
/*==================================== 
 自定义类型名 
====================================*/ 
typedef unsigned char INT8U; 
typedef unsigned char uchar; 
 
typedef unsigned int INT16U; 
typedef unsigned int uint; 
 
/*==================================== 
 硬件接口位声明 
====================================*/ 
sbit IR  = P3^2;     //定义红外脉冲数据接口        外部中断O输入口 
sbit a=P0^0; 
sbit b=P0^1; 
uchar IRtime;                 //检测红外高电平持续时间(脉宽) 
uchar IRcord[4];    //此数组用于储存分离出来的4个字节的数据(用户码2个字节+键值码2个字节) 
uchar IRdata[33];   //此数组用于储存红外的33位数据(第一位为引导码用户码16+键值码16) 
bit IRpro_ok, IRok;  //第一个用于红外接收4个字节完毕。IRok用为检测脉宽完毕 
 
void init()           //初始化定时器0 和外部中断0 
{ 
        TMOD = 0x22; //定时器0和定时器1工作方式2,8位自动重装 
        TH0 = 0x00;  //高8位装入0那么定时器溢出一次的时间是256个机器周期 
        TL0 = 0x00; 
        EA = 1;      //总中断 
        ET0 = 1;           //定时器0中断 
        TR0 = 1;     //启动定时器0 
 
        IT0 = 1;           //设置外部中断0为跳沿触发方式,来一个下降沿触发一次 
        EX0 = 1;           //启动外部中断0 
 
        TH1 = 0xfd;  //此溢出率为波特率9600 
        TL1 = 0xfd; 
        TR1 = 1;     //启动定时器1 
        SM1 = 1;     //设置串口工作方式1,10位异步收发器 
} 
 
void time0() interrupt 1   //定义定时器0 
{ 
        IRtime++;                            //检测脉宽,1次为278us 
} 
 
void int0() interrupt 0                          //定义外部中断0 
{ 
        static uchar i;                                 //        声明静态变量(在跳出函数后在回来执行的时候不会丢失数值)i用于把33次高电平的持续时间存入IRdata 
        static bit startflag;                //开始储存脉宽标志位 
        if(startflag)                                 //开始接收脉宽检测 
        { 
                if( (IRtime < 53) && (IRtime >= 32) ) /*判断是否是引导码,底电平9000us+高4500us         
                这个自己可以算我以11.0592来算了NEC协议的引导码低8000-10000+高4000-5000  
                如果已经接收了引导码那么i不会被置0就会开始依次存入脉宽*/ 
                        i = 0;                                 //如果是引导码那么执行i=0把他存到IRdata的第一个位 
                IRdata[i] = IRtime;                   //以T0的溢出次数来计算脉宽,把这个时间存到数组里面到后面判断 
                IRtime = 0;                                 //计数清零,下一个下降沿的时候在存入脉宽 
                i++;                                          //计数脉宽存入的次数 
                if(i == 33)                                  //如果存入34次 数组的下标是从0开始i等于33表示执行了34次 
                { 
                         IRok = 1;                                 //那么表示脉宽检测完毕 
                        i = 0;                                  //把脉宽计数清零准备下次存入 
                } 
        } 
        else                   
        { 
                IRtime = 0;                                  //引导码开始进入把脉宽计数清零开始计数 
                startflag = 1;                         //开始处理标志位置1 
        } 
} 
 
void IRcordpro()                                    //提取它的33次脉宽进行数据解码 
{ 
        uchar i, j, k, cord, value;        /*i用于处理4个字节,j用于处理一个字节中每一位,k用于33次脉宽中的哪一位 
        cord用于取出脉宽的时间判断是否符合1的脉宽时间*/ 
        k = 1;                                                 //从第一位脉宽开始取,丢弃引导码脉宽 
        for(i = 0; i < 4; i++) 
        { 
                for(j = 0; j < 8; j++) 
                { 
                        cord = IRdata[k];            //把脉宽存入cord 
                        if(cord > 5)                         //如果脉宽大于我11.0592的t0溢出率为约278us*5=1390那么判断为1 
                        value = value | 0x80;        /*接收的时候是先接收最低位, 
                        把最低位先放到value的最高位在和0x08按位或一下 
                        这样不会改变valua的其他位的数值只会让他最高位为1*/ 
                        if(j < 7) 
                        { 
                                value = value >> 1;        //value位左移依次接收8位数据。 
                        } 
                        k++;                                //每执行一次脉宽位加1 
                } 
                IRcord[i] = value;           //每处理完一个字节把它放入IRcord数组中。 
                value = 0;                            //清零value方便下次在存入数据 
        } 
        IRpro_ok = 1;                                   //接收完4个字节后IRpro ok置1表示红外解码完成         
} 
 
 void delay(uint z) 
{ 
        uint x,y; 
        for(x = z; x > 0; x--) 
                for(y = 114; y > 0 ; y--); 
} 
void main() 
{ 
    uchar k; 
        uchar i; 
        init();         
        while(1)         
        { 
                if(IRok)                         
                {    
                        IRcordpro(); 
                        IRok = 0;         
                        if(IRpro_ok)    
                        { 
                                k=0; 
                            for(i=0;i<4;i++) 
                                { 
                                   k=k+IRcord[i]; 
                                } 
                                if(k=0x1fe) 
                                        { 
                                           a=1; 
                                           b=0; 
                                        } 
                                IRpro_ok = 0; 
                        } 
                }         
        } 
} 
求助大神,用51单片机红外遥控控制电机正反转。用IRcord这个数组解码红外遥控的键值码,假如ch-的键值码是00ff45ba,然后让一个变量if语句判断是否为ch-的键值码,是的话让电机正转。 
for(i=0;i<4;i++) 
                                { 
                                   k=k+IRcord[i]; 
                                } 
                                if(k=0x1fe) 
                                        { 
                                           a=1; 
                                           b=0; 
                                        } 
就是这段程序,其中a和b控制电机,给出1,0控制电机正反转。 
 
 |   
 
 
 
 
 
 |