STM32红外发送和接收

1、PWM发射脉冲设置**(38KHz,占空比50%,PWM发射端需用定时器的复用端口来实现,TIM_Period = 38KHz/84MHz/2=2262=1131*2,通过仪器进行微调靠近38Hz)**
void PWM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);//系统时钟84MHz
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); 	//使能PORTF时钟	

GPIO_PinAFConfig(GPIOD,GPIO_PinSource13,GPIO_AF_TIM4); //GPIOD13复用为定时器14
GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_TIM4); //GPIOD14复用为定时器14

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;  //GPIOD13
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
GPIO_Init(GPIOD,&GPIO_InitStructure);              //初始化PF9

TIM_TimeBaseStructure.TIM_Period = 1105*2; //38KHz波形
TIM_TimeBaseStructure.TIM_Prescaler = 0; //
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //

/* Output Compare Active Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //
TIM_OCInitStructure.TIM_Pulse = 557*2;                   //占空比:50%
TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High ; //TIM_OCPolarity_High
TIM_OC2Init(TIM4, &TIM_OCInitStructure);  //
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);  //TIM_OC2PreloadConfig与发射通道匹配

/* Output Compare Active Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //
TIM_OCInitStructure.TIM_Pulse = 557*2;                   //占空比:50%
TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High ; //TIM_OCPolarity_High
TIM_OC3Init(TIM4, &TIM_OCInitStructure);  //
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);  //

TIM_ARRPreloadConfig(TIM4, ENABLE);

TIM_Cmd(TIM4,DISABLE); //默认定时器处于关闭状态

}
2、PWM发射引脚的控制**(引脚打开要注意模式设置为复用模式,引脚的关闭不能直接关闭,直接使能关闭后发现引脚还是在发射状态,所以将引脚的模式性质进行修改为输入模式后可以直接关闭)**
void PWM_ON(void) //发射引脚打开
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); 	//使能PORTF时钟	
GPIO_PinAFConfig(GPIOD,GPIO_PinSource13,GPIO_AF_TIM4); //GPIOF9复用为定时器14
GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_TIM4); //GPIOF9复用为定时器14

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;           //GPIOF9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
GPIO_Init(GPIOD,&GPIO_InitStructure);              //初始化PF9

TIM_Cmd(TIM4,ENABLE);

}
void PWM_OFF(void)//发射引脚关闭
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

TIM_Cmd(TIM4,DISABLE);
TIM4->CR1 |= TIM_CR1_CEN;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOD, &GPIO_InitStructure);

}
3、PWM发射过程中**(要随时控制发射引脚的打开和关闭,否则出现一次关闭后,不执行打开操作将不能再发射脉宽)**
while(bufnum < readData) //2019-4-11 15:30:33
{
times_us = IRred.globe_IRBuf[bufnum];
bufnum ++;
delay_us(times_us);
if(IRflag.globe_pluse38k_flag)
{
IRflag.globe_pluse38k_flag = 0;
PWM_OFF(); //引脚关闭
GPIO_ResetBits(GPIOD,IR_Send_Pin13);
}
else
{
IRflag.globe_pluse38k_flag = 1;
GPIO_SetBits(GPIOD,IR_Send_Pin13);
PWM_ON(); //引脚打开
}
}
4、红外接收**(红外接收口使用定时器复用的捕获功能,且注意就收数据的起始位置从1开始)**
void Remote_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM1_ICInitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//TIM1时钟使能
//GPIOA8 复用功能,上拉
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化

GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_TIM1); //GPIOA8复用为TIM1

TIM_TimeBaseStructure.TIM_Prescaler=167;  预分频器,1M的计数频率,1us加1.	
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=50000;   //设定计数器自动重装值 最大50ms溢出  
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure); 
  
//初始化TIM2输入捕获参数
TIM1_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 	选择输入端 IC1映射到TI1上

TIM1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge; //上升沿捕获
TIM1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM1_ICInitStructure.TIM_ICFilter = 0x03;//IC1F=0003 8个定时器时钟周期滤波
TIM_ICInit(TIM1, &TIM1_ICInitStructure);//初始化定时器2输入捕获通道

TIM_ITConfig(TIM1,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断	

TIM_Cmd(TIM1,DISABLE ); //使能定时器1

NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
}
void TIM1_CC_IRQHandler(void)
{
if(TIM_GetITStatus(TIM1,TIM_IT_CC1)SET) //处理捕获(CC1IE)中断
{
if((IRflag.globe_IRSave_OPEN_flag
1)|| (IRflag.globe_IRSave_CLOSE_flag==1))
{
if(RDATA)//上升沿捕获
{
Dval=TIM_GetCapture1(TIM1);//读取CCR1也可以清CC1IF标志位
TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获
TIM_SetCounter(TIM1,0); //清空定时器值
IRred.globe_IRBuf[IRred.globe_datalength] = Dval;
IRred.globe_datalength ++;

            if(IRred.globe_datalength>=MAX_IR_BUF)
            {
                IRred.globe_datalength=MAX_IR_BUF;   
            }
        }else //下降沿捕获
        {
            Dval=TIM_GetCapture1(TIM1);//读取CCR1也可以清CC1IF标志位
            TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Rising); //CC1P=0	设置为上升沿捕获
            TIM_SetCounter(TIM1,0);	   	//清空定时器值
            
            IRred.globe_IRBuf[IRred.globe_datalength] = Dval;
            IRred.globe_datalength ++;

            if (0 == IRflag.globe_Timer7_flag)
            {
                IRflag.globe_Timer7_flag = 1;
                
                TIM_Cmd(TIM7, ENABLE);
                TIM_SetCounter(TIM7,0);
            }
            if(IRred.globe_datalength>=MAX_IR_BUF)
            {
                IRred.globe_datalength=MAX_IR_BUF;   
            }
        }   
    }
   IRred.time10us_cnt = IRred.globe_datalength;
}
TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);  //清除中断标志位 

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值