SIEMENS山西省阳泉市 西门子代理商——西门子华北一级总代理
| 更新时间 2024-11-16 07:00:00 价格 请来电询价 西门子总代理 PLC 西门子一级代 驱动 西门子代理商 伺服电机 联系电话 15903418770 联系手机 15915421161 联系人 张经理 立即询价 |
详细介绍
4.1.4 定时器中断初始化
/*** @brief 定时器5中断服务程序*/void TIM5_IRQHandler(void){ if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获(1000 0000){ /*定时器溢出中断*/ if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) { if(TIM5CH1_CAPTURE_STA&0X40)/* 之前标记了开始信号(0100 0000) */ { if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F) /* 高电平太长了,计数溢出了 (0011 1111) */ { TIM5CH1_CAPTURE_STA|=0X80; /* (强制)标记成功捕获了一次 (1000 0000) */ TIM5CH1_CAPTURE_VAL=0XFFFFFFFF; /* 因为溢出次数N不能再加了,就将当前的捕获值设置为32位的Zui大值,等效Nmax+1*/ } else /* 正常情况是不会溢出,Zui终得出正确的高电平时间 */ { TIM5CH1_CAPTURE_STA++; /* 累计定时器溢出次数N */ } } else { /* 还没有捕获到信号时,定时器溢出后什么也不做,自己清零继续计数即可 */ } } /*捕获1发生捕获事件*/ if(TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET) { /*捕获到一个下降沿(结束信号)*/ if(TIM5CH1_CAPTURE_STA&0X40) /* 之前标记了开始信号(0100 0000) */ { TIM5CH1_CAPTURE_STA|=0X80; /* 标记成功捕获到一次高电平脉宽 (1000 0000) */ TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5); /* 获取当前的捕获值 */ TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); /* CC1P=0 重新设置为上升沿捕获,用于下次捕捉信号 */ } /*还未开始,第一次捕获 上升沿(起始信号) */ else { TIM5CH1_CAPTURE_STA=0; /* 清空 捕获状态寄存器 */ TIM5CH1_CAPTURE_VAL=0; /* 清空 捕获值 */ TIM5CH1_CAPTURE_STA|=0X40; /* 标记捕获到了上升沿 (0100 0000) */ TIM_Cmd(TIM5,DISABLE ); /* 关闭定时器5 */ TIM_SetCounter(TIM5,0); /* 清空CNT,重新从0开始计数 */ TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); /* CC1P=1 设置为下降沿捕获 */ TIM_Cmd(TIM5,ENABLE ); /* 使能定时器5 */ } } } TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位}
定时器中断的使能设置已在上面的定时器配置中设置,这里只是进行常规的配置定时器中断的优先级:
此处用到了两个全局变量,用于辅助实现高电平捕获。其中:
TIM5CH1_CAPTURE_VAL用来记录捕获到下降沿的时候 TIM5_CNT的值。
TIM5CH1_CAPTURE_STA用来记录捕获状态,我们把它当成一个寄存器那样来使用 。其各位描述下:
/*** @brief 定时器5中断服务程序*/void TIM5_IRQHandler(void){ if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获(1000 0000){ /*定时器溢出中断*/ if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) { if(TIM5CH1_CAPTURE_STA&0X40)/* 之前标记了开始信号(0100 0000) */ { if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F) /* 高电平太长了,计数溢出了 (0011 1111) */ { TIM5CH1_CAPTURE_STA|=0X80; /* (强制)标记成功捕获了一次 (1000 0000) */ TIM5CH1_CAPTURE_VAL=0XFFFFFFFF; /* 因为溢出次数N不能再加了,就将当前的捕获值设置为32位的Zui大值,等效Nmax+1*/ } else /* 正常情况是不会溢出,Zui终得出正确的高电平时间 */ { TIM5CH1_CAPTURE_STA++; /* 累计定时器溢出次数N */ } } else { /* 还没有捕获到信号时,定时器溢出后什么也不做,自己清零继续计数即可 */ } } /*捕获1发生捕获事件*/ if(TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET) { /*捕获到一个下降沿(结束信号)*/ if(TIM5CH1_CAPTURE_STA&0X40) /* 之前标记了开始信号(0100 0000) */ { TIM5CH1_CAPTURE_STA|=0X80; /* 标记成功捕获到一次高电平脉宽 (1000 0000) */ TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5); /* 获取当前的捕获值 */ TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); /* CC1P=0 重新设置为上升沿捕获,用于下次捕捉信号 */ } /*还未开始,第一次捕获 上升沿(起始信号) */ else { TIM5CH1_CAPTURE_STA=0; /* 清空 捕获状态寄存器 */ TIM5CH1_CAPTURE_VAL=0; /* 清空 捕获值 */ TIM5CH1_CAPTURE_STA|=0X40; /* 标记捕获到了上升沿 (0100 0000) */ TIM_Cmd(TIM5,DISABLE ); /* 关闭定时器5 */ TIM_SetCounter(TIM5,0); /* 清空CNT,重新从0开始计数 */ TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); /* CC1P=1 设置为下降沿捕获 */ TIM_Cmd(TIM5,ENABLE ); /* 使能定时器5 */ } } } TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位}
再来对比一下这张图:
初始化时设置为上升沿触发,触发后(起始信号),清空CNT,重新从0开始计数,并设置为下降沿捕获
在之后的过程中可能会有多次定时器计数溢出,即TIM5CH1_CAPTURE_STA++(使用低6位),也即N的值
Zui后捕捉到下降沿(结束信号),TIM5CH1_CAPTURE_VAL获取当前CNT的值,也即CCRx2的值
再看主函数中:
相关产品