打印
[程序源码]

红外遥控解码,求指导

[复制链接]
1901|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fengrenjie|  楼主 | 2017-4-4 21:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用的PIC16F877A,程序不知道哪里出错了,找茬了一天了。求指导;
CCP1输入捕获方式,用D端口的指示灯指示接收到的数据。指示灯用电阻上拉的。
程序如下:请指导下。
#include<pic.h>
//__CONFIG(0xFF32);

void ccp1_init()  //capture mode
{
        T1CON = 0x00;                //no postscale and no prescale
        CCP1CON = 0x04;         //capture mode and falling edge
        TMR1L = 0x00; //timer1 count from TMR1 to 0xffff
        TMR1H = 0x00;
        GIE = 1;
        PEIE = 1;
        CCP1IE = 1;
        CCP1IF = 0;
}

volatile unsigned int countl = 0;   //捕获的时间
volatile unsigned char leadcode_ok = 0; //引导码OK
volatile unsigned char time_start = 0;  //解码开始
volatile unsigned char i = 0;
volatile unsigned char ir_code[4] = {0,0,0,0}; // 红外接收到的4个数据

void main()                 
{
        TRISD = 0x00;                          //portd 输出  LED端口
        PORTD = 0xff;
        TRISC = 0xff;                        // CCP1 输入,对应红外输入
        ccp1_init();                               
        while (1)        
        {
                ;
        }       
}

void interrupt ccp1(void)
{
        if(CCP1IF && CCP1IE )
        {
                CCP1IE = 0;
                if(time_start == 0)
                {
                        TMR1H = 0;
                        TMR1L = 0 ;
                        TMR1ON = 1;
                        time_start = 1;
                }       
                else
                {
                        TMR1ON = 0;
                        countl = TMR1H*256+TMR1L;
                        TMR1H = 0;
                        TMR1L = 0;
                        TMR1ON = 1;
                        if((countl >12500)&&(countl <14500)&&(leadcode_ok == 0))
                        {
                                leadcode_ok = 1;       
                                i = 0;
                        }
                        else
                        {
                                if((countl >2000)&&(countl <2500)&&(leadcode_ok==1)) //bit 1
                                {
                                        ir_code[i/8] = ir_code[i/8]<<1+1;
                                        i++;
                                }
                                else                               
                                if((countl >1000)&&(countl <1300)&&(leadcode_ok==1))   //bit 0
                                {
                                        ir_code[i/8] = ir_code[i/8] <<1 ;
                                        i++;
                                }
                                else
                                {
                                        time_start = 0;
                                        leadcode_ok = 0;
                                        i = 0;                                       
                                }                       
                        }
                        if(i==32)
                                {
                                        i = 0;
                                        time_start = 0;
                                        leadcode_ok = 0;
                                        PORTD = ~ir_code[3]; //用指示灯输出 红外数据
                                }
                }
                TMR1IF = 0;
                CCP1IF = 0;
                CCP1IE = 1;
        }       
}       

相关帖子

沙发
airwill| | 2017-4-5 07:25 | 只看该作者
呵呵, 连问题都不说, 让人家网友在没有工作板的条件下, 既要看程序, 又要猜问题吗?

使用特权

评论回复
板凳
whay| | 2017-4-5 10:38 | 只看该作者
有电路图吗?

使用特权

评论回复
地板
lxyppc| | 2017-4-5 13:23 | 只看该作者
只要把代码的第67行那个if的判定条件改一下就好了

使用特权

评论回复
5
pang7| | 2017-4-5 14:52 | 只看该作者
接收还是发射啊? 做遥控器推荐中颖sh77p1654 效果非常非常好。

使用特权

评论回复
6
shang21ic| | 2017-12-7 09:42 | 只看该作者
以前我也自己写代码折腾了很久,后来用YiRTX02,轻松搞定。

使用特权

评论回复
7
一路向北lm| | 2017-12-7 11:57 | 只看该作者
我这里有一个,你试试能不能用。

程序.rar

30.31 KB

使用特权

评论回复
8
零点飞越| | 2017-12-7 21:22 | 只看该作者

//测试成功,2017.12.3日,修改
//----------------------------------------------------------------------------------------------------------------------------------
// 程序名:HW6-2.c
// 程序功能:红外线遥控LED
// --------------------------------------------------------------------------------------------------------------------------------

#include<reg51.h>                                                   //头文件
sbit IRIN=P3^2;                                                       //定义红外IR信号输入位
sbit SPK=P3^7;                                     //定义蜂鸣器接口
sbit RELAY=P2^7;                                   //定义继电器接口
unsigned char IRDATA[7];                                   //定义数组,存储红外接收到的数据

//-------------------------------------- 主函数 --------------------------------------
void main()
{
        EA=1;                                          // 允许总中断
    EX0=1;                                         // 允许外部中断INT0中断
        IT0=1;                                         // 外部中断INT0采用脉冲触发方式
        P1=0x00;                                       // 设置P1初始值
        SPK=1;                                         // 设置SPK初始值
        IRIN=1;                                        // IR 输入位设置为高电平
        while(1);                                      // 无限循环
}

//--------------------------------------- 延时函数  ------------------------------------

void delay(unsigned char x)                               //延时约x*0.1ms  
{                                                                                         
        unsigned char i;                                                                
        while(x--)                                                           
        {for(i=0;i<10;i++){}}                                
}

//-------------------------------------  发声函数  -------------------------------------

void fs_d ( )                                                  
{                                                                                                                   
        unsigned char i;                                               
        for(i=0;i<100;i++)
         {
           delay(4);                                                     
           SPK=~SPK;
         }                                                                        
        SPK=1;
}

//-------------------------------------  中断解码函数   -----------------------------------


void IR_IN() interrupt 0 using 0                           //外部中断INT0函数
{
        unsigned char j,k,n=0;                                               //先定义变量,且n=0
    EX0=0;                                                                               //暂时先关中断
        delay(20);                                                           //延时0.10ms*20=2ms
        if(IRIN==1)                                                   //如果IRIN出现高电平,是干扰信号
         {                                                                    
           EX0=1;
           return;                                      //返回                 
         }
        while(!IRIN){delay(1);}                                    //避开9ms前导低电平信

   for(j=0;j<4;j++)                                                        //一共有4组数据
     {       
          for(k=0;k<8;k++)                                                //每组数据有8位
         {
   while(IRIN){delay(1);}                                // 避开4.5ms高电平
   while(!IRIN){delay(1);}                                 
// 开始接收数据         
    while(IRIN)                                                 
        {
           delay(1);                                                //延时0.1ms
       n++;                                                                //每过0.1ms时n就加1
           if(n>=30)                                            //如果超过30,放弃
           {                                                              
                  EX0=1;
                  return;
           }                                  //返回
        }
                  
              IRDATA[j]=IRDATA[j]>>1;                   //右移1位
          if(n>=8){IRDATA[j]=IRDATA[j]|0x80;}                                                                   
              n=0;                                            //n清0
            }
     }
//检查接收的数据和数据反码是否相反          
    if(IRDATA[2]!=~IRDATA[3])                            //判断数据码和数据反码是不是相反
        {                                                                            //否则就放弃
             EX0=1;
             return;
        }       
        else {}
           fs_d ( );                                   //调用发声函数
           P1=IRDATA[2];                                   // P1端口输出  
           EX0=1;                                                               //开中断
}       

//--------------------------------------------------------------------------------------------------




使用特权

评论回复
9
一路向北lm| | 2017-12-8 12:50 | 只看该作者
不错,继续努力

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

331

帖子

3

粉丝