MC9S12XET256之ECT模块(5)

    

实验5:初识输入捕捉功能

所谓输入捕捉,简单的说就是感应输入引脚PTx上的电平的变化,如果发现电平变化,则:

TCNT计数器的值被保存到到输入捕捉寄存器TCx中,状态标志位被置 1

l 如果中断允许,则向CPU发出中断请求

ECT 模块可以捕捉到的电平变化包括上升沿、下降沿或任意沿。简单的说就是可以捕捉任意一种变化,功能还是很强悍的。

TCx 寄存器(Timer Input Capture/Output Compare 0-7

在介绍输出比较功能时已经提到过。在这里,用来记录外部事件发生时TCNT的值。通过读取两次相邻事件 TCx 的值就可以计算出两次事件的间隔时间了。

TCTL3/TCTL4 寄存器(Timer Control Register 3/4

定时器控制寄存器TCTL3TCTL4中的EDGxBEDGxA位决定通道 有效跳变边沿是上升沿、下降沿或任意跳变。具体如何设置参见表格 2 的说明。

表格 2 输入捕捉跳变边沿类型

EDGxB

EDGxA

类型

0

0

禁止

0

1

上升沿

1

0

下降沿

1

1

任意跳变

图 14 TCTL3/TCTL4 寄存器

TCxH寄存器(Timer Input Capture Holding Registers 0-3)

    当开启输入捕捉功能时,对应事件发生时TCNT的值会被拷贝到TCx 寄存器中。对于输入捕捉的前4个通道,在这个拷贝发生之前还要完成一件事情,就是将TCx 的值拷贝到TCxH。因此,当输入捕捉中断发生时,TCx 中存储的是发生当前事件时 的TCNT 的值,TCxH 中存放的则是上一次事件发生时TCNT 的值。这两个值的差可以计算出两次事件间隔的时间。

程序中还要使用到的寄存器包括TIOS寄存器Timer Input Capture/Output Compare Select)、TSCR1寄存器Timer System Control Register 1)、TFLG1寄存器Main T
imer Interrupt Flag 1
)和TIE寄存器Timer Interrupt Enable Register)。在前面的介绍中已经提到过这些寄存器了,这里就不重复了。

 

下面是例子程序的部分代码,功能很简单。连续捕捉十次上升沿对应的TCNT,然后计算周期。

#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include "sci.h"
void ECTInit(void) 
{    
    TIOS_IOS0 = 0; // channel 0 as output compare
    TIE_C0I = 1;  // 使能 channel 0 中断
    
    TCTL4_EDG0A = 1;
    TCTL4_EDG0B = 0;  // 检测上升沿
    
    TSCR1_TEN  = 1;  //timer enable    
}
unsigned short buf[11];
char flag;
void main(void) 
{
    long interval = 0;
    char i;
    SCIInit();
    SCISetBaudRate (SCI0, 9600, 8192000L);
    ECTInit();
  
    EnableInterrupts;
    
    flag = 0;
    for(;;) 
    {
        if(flag == 1)
        {
            for( i = 0; i < 10; i++)
            {
                interval += buf[i+1] - buf[i];
            }
            SCIPutShort(SCI0, interval >> 16);
            SCIPutShort(SCI0, interval & 0xffff);
        }
        _FEED_COP(); /* feeds the dog */
    } /* loop forever */
}
                
                
interrupt VectorNumber_Vtimch0 void ECT_0_ISR(void) 
{
    static int i = 0;
    TFLG1 = TFLG1_C0F_MASK;   //clear channel 0 interrupt flag
    buf[i++] = TC0;
    if (i == 11) 
    {
      flag = 1;
      i = 0;
      TIE_C0I = 0; //关闭中断
    }
}



信号源还是采用 USBee AX,利用通道7 输出的 7.8125KHz 方波。

 

串口传上来的数据为:10486

简单计算一下:T = 10486*1/8192.0/10 = 0.128 ms

f : 1/T = 7.815 KHz

 

说明测量的结果还是很准确的。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AD模块的飞思卡尔调试程序全部文件: #include <hidef.h> /* common defines and macros */ #include "derivative.h" /* derivative-specific definitions */ int i; unsigned char RX_ID[4],RX_DS[8]; unsigned int r[8]; unsigned int temp[2],s; void setbusclock(void) { CLKSEL=0X00; // disengage PLL to system PLLCTL_PLLON=1; // turn on PLL SYNR=0x01; // VCOFRQ[7:6];SYNDIV[5:0] // fVCO= 2*fOSC*(SYNDIV + 1)/(REFDIV + 1) // fPLL= fVCO/(2 × POSTDIV) // fBUS= fPLL/2 // VCOCLK Frequency Ranges VCOFRQ[7:6] // 32MHz <= fVCO <= 48MHz 00 // 48MHz < fVCO <= 80MHz 01 // Reserved 10 // 80MHz < fVCO <= 120MHz 11 REFDV=0x01; // REFFRQ[7:6];REFDIV[5:0] // fREF=fOSC/(REFDIV + 1) // REFCLK Frequency Ranges REFFRQ[7:6] // 1MHz <= fREF <= 2MHz 00 // 2MHz < fREF <= 6MHz 01 // 6MHz < fREF <= 12MHz 10 // fREF > 12MHz 11 // pllclock=2*osc*(1+SYNR)/(1+REFDV)=32MHz; POSTDIV=0x00; // 4:0, fPLL= fVCO/(2xPOSTDIV) // If POSTDIV = $00 then fPLL is identical to fVCO (divide by one). _asm(nop); // BUS CLOCK=16M _asm(nop); while(!(CRGFLG_LOCK==1)); //when pll is steady ,then use it; CLKSEL_PLLSEL =1; //engage PLL to system 分频; } //[设置总线时钟频率为16MHZ] ; // void ATDInit(void) { ATD0CTL2=0x42; // ATD启动,禁止外部触发,允许ATD中断; ATD0CTL3=0x88; // 背景调试模式下继续转换,每1次转换一个转换序列,继续转换; ATD0CTL4=0x01; // 采样时间为 2个时钟周期,转化按10位进行,总分频系数为8; ATD0CTL5=0x20; // 数据右对齐,无符号,单通道采集, } //[AD进行初始化];

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值