最近学习到timer1输入捕获功能,挺强大的定时计数器,结构也比较复杂。
首先还是先讲讲timer1的结构框图吧。
概括图
主要有时钟/触发控制单元,基本定时计数模块
输入输出模块
输入捕获输出比较模块。
接下来是输入捕获和输出比较模块框图
这个框图很好的表达了输入捕获需要满足的前提条件
下面是输入部分结构
四个输入通道,带有独立的滤波和边沿检测器
以通道1为例的结构图
信号经过滤波、边沿检测,再到预分频才能进入输入捕获单元
结构大体就是这样
那如何测量一个方波信号的周期呢?
其实也简单,就是在出现测定边沿的时候记录下timer1里的数值,再次出现相同边沿时再记录一次。
两次数据之差就是输入信号的周期。
进行周期测量时,timer1的计数器使用内部时钟计数,当出现捕获时计数器内的数值存入捕获寄存器
两次捕获就能测出信号周期。
看着挺简单的,实际上也应当是很简单的。但是我在使用捕获中断来测量时总是得不到正确的结果。
使用while循环检测捕获标志位就能得到正确结果。
原因还没找到,这里就先用while循环检测吧。
CPU时钟分频作为输入频率源
8M 64分频 得到125KHZ时钟
在线仿真
计算的频率正确无误
最后贴上测试代码
- /*周期测量*/
- #include<iostm8s105k4.h>
- unsigned int T,T1,T2;
- unsigned int result;
- 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_CR1=0x01; //开计数器
- TIM1_CCER1=0x01; //开捕获
-
-
- }
- int main( void )
- {
- init();
- 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!