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_flag1)|| (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); //清除中断标志位
}