相比于一通道,原子的例程里因为清了计数时间,所以要对程序进行修改。

记录上升沿后的计数,然后记录下降沿的计数。相减后计算高电平时间,对于定时器中断间隔的边界要分开处理。

这里因为我的接收机时间是1ms~2ms,而中断时间设置为20ms。所以根本不需要考虑时间延迟超过计时器时间。

下面是我的代码

//arr:自动重装值 psc:时钟预分频数
//定时器溢出时间计算:Tout=((arr+1)*(psc+1))/Ft us
//Ft = 定时器工作频率,单位Mhz
//TIM2在APB1上,为HCLK/2 36Mhz
void TIM2_CAP_Init(u16 arr, u16 psc)
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_ICInitTypeDef TIM_ICInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//开启TIM2和GPIO时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//PA0初始化
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD; //下拉输入
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct); //TIM2定时器初始化
TIM_TimeBaseInitStruct.TIM_Period = arr;
TIM_TimeBaseInitStruct.TIM_Prescaler = psc;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); //TIM2_CH1输入捕获初始化
TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
TIM_ICInitStruct.TIM_ICFilter = 0x00; //不滤波
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; //输入器不分频
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到IC1
TIM_ICInit(TIM2, &TIM_ICInitStruct); TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;
TIM_ICInitStruct.TIM_ICFilter = 0x00; //不滤波
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; //输入器不分频
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到IC2
TIM_ICInit(TIM2, &TIM_ICInitStruct); TIM_ICInitStruct.TIM_Channel = TIM_Channel_3;
TIM_ICInitStruct.TIM_ICFilter = 0x00; //不滤波
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; //输入器不分频
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到IC3
TIM_ICInit(TIM2, &TIM_ICInitStruct); TIM_ICInitStruct.TIM_Channel = TIM_Channel_4;
TIM_ICInitStruct.TIM_ICFilter = 0x00; //不滤波
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; //输入器不分频
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到IC4
TIM_ICInit(TIM2, &TIM_ICInitStruct); //中断分组初始化
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = ;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = ;
NVIC_Init(&NVIC_InitStruct); TIM_ITConfig(TIM2, TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3|TIM_IT_CC4, ENABLE); //更新中断和CC1IE捕获中断 TIM_Cmd(TIM2, ENABLE);
printf("Init TIM2 CAP success\n");
}

然后是中断处理函数

//捕获状态
//[7]:0,没有成功捕获;1,成功捕获到一次
//[6]:0,还没捕获到低电平;1,已经捕获到低电平了.
//[5:0]:捕获低电平后溢出第次数
u8 CAPTURE_STA_TIM2CH[] = {};
u16 CAPTURE_VAL_TIM2CH[];
u16 CAPTURE_UP_TIM2CH[], CAPTURE_DOWN_TIM2CH[];
void TIM2_IRQHandler(void)
{
// if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
// if((CAPTURE_STA_TIM2CH[1]&0x80) == 0) { //还未捕获成功
// if(CAPTURE_STA_TIM2CH[1]&0x40) { //已经捕获到高电平了
// if((CAPTURE_STA_TIM2CH[1]&0x3F)==0x3F) { //高电平太长了
// CAPTURE_STA_TIM2CH[1] |= 0x80; //标记成功捕获了一次
// CAPTURE_VAL_TIM2CH[1] = 0xFFFF;
// } else
// CAPTURE_VAL_TIM2CH[1]++;
// }
// }
// TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// } if((CAPTURE_STA_TIM2CH[]&0x80) == ) { //还未捕获成功
if(TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) { //捕获1发生捕获事件
if(CAPTURE_STA_TIM2CH[]&0x40) { //捕获到一个下降沿
CAPTURE_STA_TIM2CH[] |= 0x80; //标记成功捕获到一次高电平脉宽
CAPTURE_DOWN_TIM2CH[] = TIM_GetCapture1(TIM2);
if(CAPTURE_DOWN_TIM2CH[] >= CAPTURE_UP_TIM2CH[])
CAPTURE_VAL_TIM2CH[] = CAPTURE_DOWN_TIM2CH[] - CAPTURE_UP_TIM2CH[];
else
CAPTURE_VAL_TIM2CH[] = 0xffff + CAPTURE_DOWN_TIM2CH[] - CAPTURE_UP_TIM2CH[];
TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
} else { //还未开始,第一次捕获上升沿
CAPTURE_STA_TIM2CH[] = ; //清空
CAPTURE_VAL_TIM2CH[] = ;
CAPTURE_UP_TIM2CH[] = TIM_GetCapture1(TIM2);
CAPTURE_STA_TIM2CH[] |= 0x40; //标记捕获到了上升沿
TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获
}
TIM_ClearFlag(TIM2, TIM_FLAG_CC1); //清除状态标志
}
} if((CAPTURE_STA_TIM2CH[]&0x80) == ) { //还未捕获成功
if(TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) { //捕获2发生捕获事件
if(CAPTURE_STA_TIM2CH[]&0x40) { //捕获到一个下降沿
CAPTURE_STA_TIM2CH[] |= 0x80; //标记成功捕获到一次高电平脉宽
CAPTURE_DOWN_TIM2CH[] = TIM_GetCapture2(TIM2); //获取捕获2计数
if(CAPTURE_DOWN_TIM2CH[] >= CAPTURE_UP_TIM2CH[])
CAPTURE_VAL_TIM2CH[] = CAPTURE_DOWN_TIM2CH[] - CAPTURE_UP_TIM2CH[];
else
CAPTURE_VAL_TIM2CH[] = 0xffff + CAPTURE_DOWN_TIM2CH[] - CAPTURE_UP_TIM2CH[];
TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
} else { //还未开始,第一次捕获上升沿
CAPTURE_STA_TIM2CH[] = ; //清空
CAPTURE_VAL_TIM2CH[] = ;
CAPTURE_UP_TIM2CH[] = TIM_GetCapture2(TIM2);
CAPTURE_STA_TIM2CH[] |= 0x40; //标记捕获到了上升沿
TIM_OC2PolarityConfig(TIM2, TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获
}
TIM_ClearFlag(TIM2, TIM_FLAG_CC2); //清除状态标志
}
} if((CAPTURE_STA_TIM2CH[]&0x80) == ) { //还未捕获成功
if(TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET) { //捕获2发生捕获事件
if(CAPTURE_STA_TIM2CH[]&0x40) { //捕获到一个下降沿
CAPTURE_STA_TIM2CH[] |= 0x80; //标记成功捕获到一次高电平脉宽
CAPTURE_DOWN_TIM2CH[] = TIM_GetCapture3(TIM2); //获取捕获2计数
if(CAPTURE_DOWN_TIM2CH[] >= CAPTURE_UP_TIM2CH[])
CAPTURE_VAL_TIM2CH[] = CAPTURE_DOWN_TIM2CH[] - CAPTURE_UP_TIM2CH[];
else
CAPTURE_VAL_TIM2CH[] = 0xffff + CAPTURE_DOWN_TIM2CH[] - CAPTURE_UP_TIM2CH[];
TIM_OC3PolarityConfig(TIM2, TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
} else { //还未开始,第一次捕获上升沿
CAPTURE_STA_TIM2CH[] = ; //清空
CAPTURE_VAL_TIM2CH[] = ;
CAPTURE_UP_TIM2CH[] = TIM_GetCapture3(TIM2);
CAPTURE_STA_TIM2CH[] |= 0x40; //标记捕获到了上升沿
TIM_OC3PolarityConfig(TIM2, TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获
}
TIM_ClearFlag(TIM2, TIM_FLAG_CC3); //清除状态标志
}
}
if((CAPTURE_STA_TIM2CH[]&0x80) == ) { //还未捕获成功
if(TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET) { //捕获2发生捕获事件
if(CAPTURE_STA_TIM2CH[]&0x40) { //捕获到一个下降沿
CAPTURE_STA_TIM2CH[] |= 0x80; //标记成功捕获到一次高电平脉宽
CAPTURE_DOWN_TIM2CH[] = TIM_GetCapture4(TIM2); //获取捕获2计数
if(CAPTURE_DOWN_TIM2CH[] >= CAPTURE_UP_TIM2CH[])
CAPTURE_VAL_TIM2CH[] = CAPTURE_DOWN_TIM2CH[] - CAPTURE_UP_TIM2CH[];
else
CAPTURE_VAL_TIM2CH[] = 0xffff + CAPTURE_DOWN_TIM2CH[] - CAPTURE_UP_TIM2CH[];
TIM_OC4PolarityConfig(TIM2, TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
} else { //还未开始,第一次捕获上升沿
CAPTURE_STA_TIM2CH[] = ; //清空
CAPTURE_VAL_TIM2CH[] = ;
CAPTURE_UP_TIM2CH[] = TIM_GetCapture4(TIM2);
CAPTURE_STA_TIM2CH[] |= 0x40; //标记捕获到了上升沿
TIM_OC4PolarityConfig(TIM2, TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获
}
TIM_ClearFlag(TIM2, TIM_FLAG_CC4); //清除状态标志
}
} //处理帧数据
if(CAPTURE_STA_TIM2CH[]&0x80) { //成功捕获到了一次上升沿 //溢出时间总和
myControl.remoteControl[] = CAPTURE_VAL_TIM2CH[]; //得到总的高电平时间
// printf("TIM2 CH1:%d\t", temp[0]);
CAPTURE_STA_TIM2CH[] = ;
}
if(CAPTURE_STA_TIM2CH[]&0x80) { //成功捕获到了一次上升沿 //溢出时间总和
myControl.remoteControl[] = CAPTURE_VAL_TIM2CH[]; //得到总的高电平时间
// printf("TIM2 CH2:%d\t", temp[1]);
CAPTURE_STA_TIM2CH[] = ;
}
if(CAPTURE_STA_TIM2CH[]&0x80) { //成功捕获到了一次上升沿 //溢出时间总和
myControl.remoteControl[] = CAPTURE_VAL_TIM2CH[]; //得到总的高电平时间
// printf("TIM2 CH3:%d\t", temp[2]);
CAPTURE_STA_TIM2CH[] = ;
}
if(CAPTURE_STA_TIM2CH[]&0x80) { //成功捕获到了一次上升沿 //溢出时间总和
myControl.remoteControl[] = CAPTURE_VAL_TIM2CH[]; //得到总的高电平时间
// printf("TIM2 CH4:%d\t", temp[3]);
CAPTURE_STA_TIM2CH[] = ;
}
}

这些printf函数会极大的占用MCU资源,所以不在中断中处理。

最新文章

  1. Form Builder的三种查询方法构建
  2. 那些强悍的PHP一句话后门
  3. Tomcat6环境JBPM4.4报错:java.lang.ClassNotFoundException: de.odysseus.el.util.SimpleResolver
  4. spring 小结
  5. [Windows驱动]流媒体驱动开发
  6. IOS 日志输出控制
  7. Linux Shell产生16进制随机数
  8. IOS动态修改按钮响应时间
  9. Unity 中关于 BuildSetting 中 “Optimize Mesh Data” 选项的“坑”
  10. Javascript中bind()方法的使用与实现
  11. (git fetch git push git pull)远程本地分支互相推送更新
  12. Qt带来的是更加低廉的开发成本和学习成本,对于很多小公司而言,这种优势足以让他们获得更大的利润空间 good
  13. Java学习之开篇—个人随想
  14. ios7禁止默认划动返回
  15. iOS11、iPhone X、Xcode9 适配
  16. Laravel5中使用阿里大于(鱼)发送短信验证码
  17. logback常用配置详解及logback简介
  18. ios定义数组和字典快捷方式
  19. 使用 STHTTPRequest 框架解析 Soap1.2 教程
  20. cdoj203-Islands 【并查集】

热门文章

  1. P2158仪仗队
  2. java 为啥可打印date
  3. C++ lower_bound 与 upper_bound 函数
  4. mysql_备份_mysqldump
  5. centos6.5下apollo1.7.1的搭建
  6. C语言的未初始化的数组的值为什么是随机的
  7. vue全局自定义指令-元素拖拽
  8. HTML 解析类库HtmlAgilityPack
  9. JS DOM元素的操作(创建,添加,删除,和修改属性)
  10. Linux——文件打包与压缩