打印

哪位高手用MCU软件模拟红外遥控芯片HT6221?

[复制链接]
3935|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hopewise|  楼主 | 2013-4-18 11:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
airwill| | 2013-4-18 12:07 | 只看该作者
单片机模拟红外遥控芯片的控制, 并不是个难事儿, 只是里面有些细节, 象弄清按键键码等问题, 比较繁琐.
有个叫 "万能遥控器" 的产品就干好了这个事情了

使用特权

评论回复
板凳
huangqi412| | 2013-4-18 12:18 | 只看该作者
波形通过音频接口送电脑对比。。。示波器都免了。

使用特权

评论回复
地板
refee| | 2013-4-18 13:43 | 只看该作者
之前曾经做过一个直接用IO接原遥控接收头输出端的 如果用IO驱动红外二极管的话 那得搞定38K载波先

#define IRCODE_GPIO 4 //Pin8 GPIO4

extern const BYTE ir_mapcode[];

static BYTE get_ircode(BYTE IrFunc)
{
    BYTE i;

    for (i = 0; i < 96; i++)
    {
        if (ir_mapcode[i] == IrFunc)
            break;
    }

    return i;
}

static void delay_necir_clk(BYTE Clk560uS)
{
    UINT16 delay10us = Clk560uS * 56 + 1;
    while (delay10us --)
    {
        delay_1us(10);
    }
}

static void send_necir_byte(BYTE data)
{
    int i ;
    for (i = 0; i < 8; i ++)
    {
        GPIO_O_SET(IRCODE_GPIO, 0);
        delay_necir_clk(1);
        GPIO_O_SET(IRCODE_GPIO, 1);
        if (data & 0x01)
            delay_necir_clk(3);
        else
            delay_necir_clk(1);
        data >>= 1;
    }
}

void send_necir_flame_data(BYTE IrFunc)
{
    BYTE IRcode = 0;

    GPIO_F_SET(IRCODE_GPIO, 1);
    GPIO_M_SET(IRCODE_GPIO, 1);
    GPIO_E_SET(IRCODE_GPIO, 1);

    //Lead code
    GPIO_O_SET(IRCODE_GPIO, 0);
    delay_necir_clk(16);
    GPIO_O_SET(IRCODE_GPIO, 1);
    delay_necir_clk(8);

    //Custom code
    send_necir_byte(0x00);
    send_necir_byte(0xFF);

    //Data code
    IRcode = get_ircode(IrFunc);
    send_necir_byte(IRcode);
    IRcode = 0xFF - IRcode;
    send_necir_byte(IRcode);

    GPIO_O_SET(IRCODE_GPIO, 0);
    delay_necir_clk(9);
    GPIO_O_SET(IRCODE_GPIO, 1);
}

使用特权

评论回复
5
coody| | 2013-4-18 15:43 | 只看该作者
这个很容易的,你按照DS里的波形,38K是用1/3占空比输出的

使用特权

评论回复
6
hopewise|  楼主 | 2013-4-19 08:35 | 只看该作者
多谢各位高手的回答.我只是想用主MCU软件模拟HT6221的发送时序图,不用3搞8K载波---因为从机MCU就判断IO电平就行了.现在问题是:用遥控器按下某键,从机MCU完全正常接收到信号,但用我写的主MCU软件模拟HT6221的发送时序的程序就没反应了(采用定时器中断方法,从机MCU也是的).
//*************定时器1中断****************
//****************************************
void t1_isr(void) interrupt 3                                                    //每隔280us中断一次
{
      TL1=(0xffff-280)%0x100;
      TH1=(0xffff-280)/0x100;
      if(SendIE)                                                          //有数据要发送出去
      {
           SendTCnt++;                                                    //脉宽计数器加一
           send( );                                                          //发送数据
      }
      else
      {                                                                          //否则要是没有数据发送的话,则
           SendTCnt=0;                                                          //脉宽计数器清零
           Dio=1;                                                          //通信引脚拉高,释放总线
     }                                                                                                         
}
//**********************************
//**********************************
void  send( )
{
      if(rfgobit==0)                                                          //产生头码和结果码
      {
             if(SendTCnt<=32)
             {
                  Dio=0;                                                  //头码时间到(9ms/280us=32次)
                     
             }
             else  if(SendTCnt<48)
             {
                  Dio=1;                                                   
                     
             }
             else if(SendTCnt==48)                                           //结果码时间到(4.5ms/280us=16次,故32+16=48次)
             {
                  Dio=0;                                                   //通信引脚,为下次发32位数据作准备
                  rfgobit=1;                                               //32位数据允许发送标志位置1
                  SendTCnt=0;                                                     //脉宽计数器清零                    
             }
      
      }
      if(rfgobit==1)                                                           //发送32位数据
      {
            zbit=dispcount[word_count]&0x01;                                   //高位先发送
            if(zbit==0)                                                           //"0"状态
            {
                 if(SendTCnt==1)  
                 {

                        Dio=0;
                }
                else         if(SendTCnt==2)
                {

                        Dio=1;                                                  //0.56ms低电平时间到
                }
                else         if(SendTCnt==3)
                {

                        Dio=1;
                }
                else         if(SendTCnt==4)                                          //0.56ms高电平时间到
                {
                        SendTCnt=0;
                        bit_count++;                                          //位数加一
                        Dio=0;
                        if(bit_count==8)                                  //发完了8位
                        {
                              bit_count=0;
                              word_count++;                                  //则字节数加一
                              if(word_count==4)                                  //32位数据发完毕
                              {
                                    word_count=0;
                                    rfgobit=0;
                                    Dio=1;
                                    SendIE=0;                                  //禁止发送
                             }
                            return;
                       }
                       dispcount[word_count]=dispcount[word_count]>>1;          //发送下一位(数据右移1位)
                }

          }
          else   if(zbit==1)                                                   //"1"状态
          {
                if(SendTCnt==1)  
                {

                        Dio=0;
                }
                else         if(SendTCnt==2)
                {

                        Dio=1;                                                  //0.56ms低电平时间到
                }
                else         if(SendTCnt==3)
                {

                         Dio=1;
                }
                else         if(SendTCnt==4)
                {

                        Dio=1;
                }
                else if(SendTCnt==5)
                {

                        Dio=1;
                }
                else if(SendTCnt==6)
                {

                        Dio=1;
                }
                else if(SendTCnt==7)
                {

                        Dio=1;
                }
                else  if(SendTCnt==8)                                          //1.68ms高电平时间到
                {
                       SendTCnt=0;
                       bit_count++;                                          //位数加一
                       Dio=0;
                       if(bit_count==8)
                       {
                             bit_count=0;
                             word_count++;
                             if(word_count==4)
                             {
                                  word_count=0;
                                  rfgobit=0;
                                  Dio=1;
                                  SendIE=0;
                            }
                            return;
                       }
                       dispcount[word_count]=dispcount[word_count]>>1;
               }
          }
    }
}

使用特权

评论回复
7
wangyy608| | 2013-4-19 08:53 | 只看该作者
不用3搞8K载波。。。。
这个真的要

使用特权

评论回复
8
hopewise|  楼主 | 2013-4-19 09:15 | 只看该作者
wangyy608 你有没有更好的建议啊?Thanks

使用特权

评论回复
9
hopewise|  楼主 | 2013-4-19 09:18 | 只看该作者
wangyy608 一定要产生38k载波吗?主机MCU和从机MCU是通过一条线连接的(当然也有+5V和GND,包含通信脚,总共3条线)

使用特权

评论回复
10
hopewise|  楼主 | 2013-4-19 09:21 | 只看该作者
应该是所谓的一线通信.只是我想采用红外遥控时序图格式来进行双MCU通信

使用特权

评论回复
11
rgh111| | 2013-4-19 13:27 | 只看该作者
不搞38KHz载波的话,貌似更容易些啦.  那你就看遥控器按下的时候,接收IO口的波形是什么样的, 就些接收头可能正好与资料的电平相反.;P

使用特权

评论回复
12
hopewise|  楼主 | 2013-4-19 14:26 | 只看该作者
rgh111,是9ms头码(低电平)+4.5ms结果码(高电平)+32位数据

使用特权

评论回复
13
skygz| | 2015-12-7 20:05 | 只看该作者
refee 发表于 2013-4-18 13:43
之前曾经做过一个直接用IO接原遥控接收头输出端的 如果用IO驱动红外二极管的话 那得搞定38K载波先

#define ...

你好.....

求你这段代码的完整代码......我正在弄 直接往接收头的IO, 写编码,  总不工作.........

例如你这段代码里 的 GPIO_O_SET, GPIO_F_SET, GPIO_M_SET,GPIO_E_SET     等不清楚是什么啊............

使用特权

评论回复
14
coody| | 2015-12-8 14:22 | 只看该作者
Very easy! 任何MCU都可以,只要你按时序写就可以了。

使用特权

评论回复
15
micleader| | 2015-12-8 17:02 | 只看该作者
路过

使用特权

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

本版积分规则

46

主题

468

帖子

3

粉丝