2019-07-21 05:27发布
lizelin 发表于 2019-1-22 14:43 我也是在做复制空调遥控器的波形 然后再发射出去 我是记录接收到的波形高低电平持续时间,然后再通过PWM ...
最多设置5个标签!
看来你和我曾经遇到得问题一样,好的,我仔细的给你解释一下,希望对你有所帮助,嘻嘻!
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;
}
花近一个小时写这么多,该死的颈椎病又犯了,说了这么多希望对你有用。
一周热门 更多>