最近学STM8的输入捕获功能,遇上了点难题。
STM8用定时器1测量方波信号的周期。
配置捕获输入信号的上升沿。
也就是有上升沿输入时timer1计数器里的值会写入TIM1_CCR1中,并且捕获标志位CC1F会被置位。
如果开启捕获中断时则会产生捕获中断。
本来也是挺简单的事,但是测试并不顺利。
我使用单片机的时钟输出功能输出时钟作为方波来源。
测量时钟输出稳定,8M CPU时钟64分频成125K时钟。
按照正常的逻辑推测得出的周期应该是64个时钟,因为输入波形刚好是计数时钟的64分频嘛。
但是实验结果却不是理想的稳定的64。
而是大部分时间显示的是128。
也就是测量出的周期大了一倍。
我想是不是在处理中断的时候又发生了捕获,导致读取的值是两次方波周期。
查看CC1OF,果然是出现了重复捕获。
是不是64个时钟周期对于中断处理来说太短了,处理不过来??
最后加了个判断,如果出现重复捕获则周期减半,但是还是容易误动作,变成32.。。。
贴上程序
- /*周期测量*/
- #include<iostm8s105k4.h>
- unsigned int T,T1,T2;
- unsigned int result;
- #pragma vector=TIM1_CAPCOM_CC1IF_vector
- __interrupt void timer1()
- {
- T1=T2;
- T2=TIM1_CCR1H<<8;
- T2|=TIM1_CCR1L;
- if(T2>T1) T=T2-T1;
- if(TIM1_SR2&0x02)
- {
- TIM1_SR2=0;
- T/=2;
- }
- }
- void init()
- {
-
- CLK_SWCR|=0x02; //时钟切换
- CLK_SWR=0xB4; //外部8M晶体
- CLK_CKDIVR=0x00; //不分频
- CLK_CCOR=0x15; //Fcpu/64输出 125K
-
- PD_DDR_DDR0=1; //PD0配置 时钟输出
- PD_CR1_C10=1;
- PD_CR2_C20=1;
-
- PC_DDR_DDR1=0; //PC1配置 捕获
- PC_CR1_C11=1;
- PC_CR2_C21=0;
-
- TIM1_ARRH=0xff; //初始化重装载寄存器
- TIM1_ARRL=0xff;
- TIM1_CCR1H=0; //初始化捕获寄存器
- TIM1_CCR1L=0;
- TIM1_CCMR1=0x01; //配置捕获通道
- TIM1_IER=0x02;
- TIM1_CR1=0x01; //开计数器
- TIM1_CCER1=0x01; //开捕获
-
-
- }
- int main( void )
- {
- init();
- asm("rim");
- while(1)
- {
- /* while(!(TIM1_SR1&0x02)); //等待捕获标志 首次捕获
-
- T1=TIM1_CCR1H<<8;
- T1|=TIM1_CCR1L;
-
- while(!(TIM1_SR1&0x02)); //等待捕获标志 二次捕获
-
- T2=TIM1_CCR1H<<8;
- T2|=TIM1_CCR1L;
-
- if(T2>T1) T=8000/(T2-T1); //计算频率 单位K 判断T1、T2大小,避免计数器溢出影响
- */
- }
- }
是不是输入频率较高时使用分频会好些。
使用查询方式就比较稳定,是不是进入中断比较费时间呢?
THE END!