怎么生成红外波形

2019-07-21 05:27发布

大一刚学习,想利用F103发送红外线控制空调,要怎么利用PWM调制出一个波形
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
13条回答
YongIOT
2019-07-21 09:57
lizelin 发表于 2019-1-22 14:43
我也是在做复制空调遥控器的波形 然后再发射出去  我是记录接收到的波形高低电平持续时间,然后再通过PWM ...

看来你和我曾经遇到得问题一样,好的,我仔细的给你解释一下,希望对你有所帮助,嘻嘻!
1.目的:复制遥控器红外波形然后发射出去控制红外家电设备。
2.怎么复制:A.我是通过STM32的定时器捕获来获取遥控器发射给红外接收头解调后的电平,说的详细点,就是红外遥控器发射的是一组经过调制的红外信号,后面我们模拟的时候也是需要调制的,调制需要载波:38k左右都可以,红外接收头接收到遥控器的红外信号后内部会自动解调,如图1.0是接收到的信号和红外解调后的信号。
B.然后是红外接收头接32的定时器捕获引脚(这个要看32的引脚分配,不能随便分配),我所捕获的就是解调后的高低电平时间,这个不需要遵守遥控器的编码协议,因为我们是复制,那些完全不用管,如图1.1。
C.将我们记录的高低电平时间分开(采用定时器的上升沿捕获和下降沿捕获),将每组记录的时间都放在数组里,肯可能有点多,一般的遥控器60到70组数据(高低电平总和),像美的空调,格力空调的话大概有150多组,经测试,数组大小为200的话,复制市面上大多数遥控器都可以。采集到的数据存在32的flash里,这样实现资源的合理利用,也可以外接存储器,看你自己的选择,这样复制就完成啦!
3.怎么发射:
A.产生载波:我们产生38K的载波,具体怎么产生以及原理我就不再这里啰嗦啦,我改的那部分代码里有,唉~我再次帖到这里,
void SendPort(void){                  //发送端口,此端口为PWM导通端口
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
       
        GPIO_InitStructure.GPIO_Pin        = GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB, GPIO_Pin_7 );
}


void TIM4_PWM_Init(u16 arr,u16 psc)//TIM4 CH3   PB8
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef        TIM_TimeBaseInitStructure;
        TIM_OCInitTypeDef         TIM_OCInitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);          //使能定时器4时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);   //使能GPIO外设时钟
       
        /* GPIOB.9初始化 */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;                            // TIM4 CH4
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         // PB8复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_SetBits(GPIOB,GPIO_Pin_8);
        /* TIM4初始化*/
        TIM_TimeBaseInitStructure.TIM_Period = arr;            //下一个更新事件装入活动的自动重装载寄存器周期的值
        TIM_TimeBaseInitStructure.TIM_Prescaler = psc;        //作为TIMx时钟频率除数的预分频值
        TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;  //时钟分割:TDTS = Tck_tim
        TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;        //TIM向上计数模式
        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);
        /* 定时器TIM4 Ch4 PWM模式初始化 */
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //选择定时器模式:TIM PWM1
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;        //比较输出使能
        //TIM_OCInitStructure.TIM_Pulse = (arr+1)/2;          //占空比 50%
        TIM_OCInitStructure.TIM_Pulse = (arr+1)/3;          //占空比1:3
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;        //输出极性:TIM输出比较极性高
        TIM_OC3Init(TIM4, &TIM_OCInitStructure);

        /* 使能TIM4在CCR1上的预装载寄存器 */
        TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
       
        /* 使能定时器 */
//        TIM_Cmd(TIM4,ENABLE);
        SendPort();  //这里下面说,这是红外信号控制发射端口,

}
上面就实现了38K的载波啦!要是不能理解的话,简易去看下STM32的PWM怎么产生的相关资料,加油!其实你按我这样配置完全没得问题。
B.怎么发送:先说下我的发射电路吧,如图1.2 ,发送端口随便定,有了电路后就好办啦,单片机一上电一直产生38K载波,也就是说下面那个三级管一直在开与闭合之间变化,发射端口的作用就是读取刚才存储在数组里的的那些数据,至于怎么读取发送,我也把代码帖在下面把,大家都是为了学习,我也是学生,为了学习就应该互相帮助,就像这个论坛一样开源,支持开源

源码太多了,我只给出核心部分,注意***为重点
             if(T1==0X00){                //串口接收,
                STMFLASH_Read(ADDR1,Pulse1,200);   //***这里读取数据
                delay_ms(500);
//                                  TIM_Cmd(TIM1,DISABLE ); //***
//                      TIM_ITConfig( TIM1,TIM_IT_Update|TIM_IT_CC1,DISABLE);//***
          T1=0x10;
                                }
                   else if(T1==0x10){
                            GPIOB->BRR |= 0x0020;//0 红 {MOD}
          GPIOB->BSRR |= 0x0040; //1//绿 {MOD}LED  //不用管,我弄的指示灯
                for(i1=1; i1<200; i1++)         //***从1开始的原因是,数组里第0位为无效数据
                {
                if(Pulse1[i1]==0x00) {      /***以防数据没有200组实际只有150组,后面的都W为0,这样会导致死机,所以数据为0后就结束发送
                                         GPIOB->BSRR |= 0x0020; //1  RED
           GPIOB->BSRR |= 0x0020;  //1   GREEN
                                         GPIOB->BSRR |= 0x0081;//***发送管脚,通过寄存器操作更快点
                                   continue;   
                                   }
                else{
                        if(i1%2 == 0)              //***偶数位发送。奇偶数位发送
                        {
                                                //GPIO_SetBits(GPIOB,GPIO_Pin_7);
                                                GPIOB->BSRR |= 0x0081;//****
                                                delay_us(Pulse1[i1]);//***延时一定要精确,原因,模拟采集的时间控制发送端口的高低电平,实现和载波的调制
                                          }
                                   else
                                   {
                                        //GPIO_ResetBits(GPIOB,GPIO_Pin_7);
                                          GPIOB->BRR |= 0x0081;//***
                                                delay_us(Pulse1[i1]);/***
                                  }
                           }
             }
                                GPIOB->BSRR |= 0x0020; //1
        GPIOB->BSRR |= 0x0040; //1
                                GPIOB->BSRR |= 0x0081;
                          USART3_RX_BUF[1]=0x00;
              }       

花近一个小时写这么多,该死的颈椎病又犯了,说了这么多希望对你有用。






               









一周热门 更多>