PIC实现SMT信号测量定时器
Leon
|
2020.01.04
|
0
+关注

PIC实现SMT信号测量定时器

SMT 是一款24 位定时计数器,经配置可测量各种数字信号参数,例如脉冲宽度、频率和占空比,渡越时间(Time Of Flight / TOF)等。

下面是MCC配置界面和数据手册上原理框图。模块主要设置与其功能的对应关系由红色注释标示出。

SMT模块输入

输入有三种,时钟,SMT信号和SMT窗口。

SMT模块输出

输出有两种,2种测量结果值,3个中断

测量结果寄存器:SMTxCPR 周期测量结果,SMTxCPW 脉宽测量结果

中断:匹配中断,周期采集中断,脉宽采集中断

工作模式

为方便记忆理解,可分为计时类和计数类。计时(Timer)类,使用时钟信号做时基,每时钟周期,24位定时器数值加1。

计数(Counter)类,使用SMT信号来驱动24位定时器,在每个SMT信号的上升沿或下降沿,24位定时器数值加1.

计时类操作包括:

1.定时器:最基本的定时操作,定时到产生中断信号

2.门控定时器:门控(SMT信号)有效时,持续定时;无效时,暂停计时

3.周期和占空比测量:测SMT信号的周期和脉宽,进而可计算出占空比

4.高电平和低电平时间测量:测SMT信号的高电平时间和低电平时间

5.窗口测量:SMT窗口源的相邻上升沿时间

6.门控窗口测量:门控有效时,测量SMT窗口源的相邻上升时间;门控无效时,暂停计时

7.渡越(TOF)时间测量:SMT窗口源和SMT信号两个信号上升沿之间的时间间隔。SMT窗口源为发射信号,SMT信号源为回波接收信号,可以测量出发射和回波接收之间的时间差。

8.捕捉模式:捕捉SMT窗口源的上升沿/下降沿时刻

计数类操作

1.计数器:基本的计数器功能,每个输入脉冲递增定时器。

2.门控计数器:门控(SMT窗口源)有效时,进行计数操作;无效则暂停。

3.窗口计数器:它在检测到SMT窗口源输入上升沿时开始计数,在下降沿时停止计数。

MCC代码

使用MCC生成代码。代码在smt1.c中。

初始化

voidSMT1_Initialize(void)

{

// WPOL high/rising edge enabled; SMT1STProlls over to 24'h000000; SMT1SPOL high/rising edge enabled; SMT1EN enabled;SMT1PS 1:4 Prescaler; SMT1CPOL rising edge;

SMT1CON0 = 0x82;

// SMT1REPEAT Single Acquisition mode;SMT1MODE Period and Duty-Cycle Acquisition; SMT1GO disabled;

SMT1CON1 = 0x02;

// SMT1CPWUP SMT1CPW1 update complete;SMT1CPRUP SMT1PR1 update complete; SMT1RST SMT1TMR1 update complete;

SMT1STAT = 0x00;

// SMT1CSEL MFINTOSC/16;

SMT1CLK = 0x05;

// SMT1WSEL SMT1WINPPS;

SMT1WIN = 0x00;

// SMT1SSEL SMT1SIGPPS;

SMT1SIG = 0x00;

// SMT1PR 0;

SMT1PRU = 0x00;

// SMT1PR 0;

SMT1PRH = 0x00;

// SMT1PR 100;

SMT1PRL = 0x64;

// Enabling SMT1 period acquisitioninterrupt.

PIE8bits.SMT1PRAIE = 1;

}

开始测量

voidSMT1_DataAcquisitionEnable(void)

{

// Start the SMT module by writing toSMTxGO bit

SMT1CON1bits.SMT1GO = 1;

}

停止测量

voidSMT1_DataAcquisitionDisable(void)

{

// Start the SMT module by writing toSMTxGO bit

SMT1CON1bits.SMT1GO = 0;

}

寄存器匹配时,保留计数值。

voidSMT1_HaltCounter(void)

{

SMT1CON0bits.SMT1STP = 1;

}

设置配置值(定时周期)

voidSMT1_SetPeriod(uint32_t periodVal)

{

// Write to the SMT1 Period registers

SMT1PRU = (periodVal >> 16);

SMT1PRH = (periodVal >> 8);

SMT1PRL = periodVal;

}

得到匹配设定值

uint32_tSMT1_GetPeriod()

{

return (SMT1PR);

}

单次操作

voidSMT1_SingleDataAcquisition(void)

{

SMT1CON1bits.SMT1REPEAT = 0;

}

重复操作

voidSMT1_RepeatDataAcquisition(void)

{

SMT1CON1bits.SMT1REPEAT = 1;

}

手动周期缓冲区更新

voidSMT1_ManualPeriodBufferUpdate(void)

{

SMT1STATbits.SMT1CPRUP = 1;

}

手动脉宽缓冲区更新

voidSMT1_ManualPulseWidthBufferUpdate(void)

{

SMT1STATbits.SMT1CPWUP = 1;

}

定时器复位

voidSMT1_ManualTimerReset(void)

{

SMT1STATbits.SMT1RST = 1;

}

窗口状态(打开 或者关闭?)

boolSMT1_IsWindowOpen(void)

{

return (SMT1STATbits.SMT1WS);

}

查询SMT采集是否正在进行

boolSMT1_IsSignalAcquisitionInProgress(void)

{

return (SMT1STATbits.SMT1AS);

}

SMT运行值状态

boolSMT1_IsTimerIncrementing(void)

{

return (SMT1STATbits.SMT1TS);

}

脉宽寄存器值

uint32_tSMT1_GetCapturedPulseWidth()

{

return (SMT1CPW);

}

周期寄存器值

uint32_tSMT1_GetCapturedPeriod()

{

return (SMT1CPR);

}

得到24位定时器值

uint32_tSMT1_GetTimerValue()

{

return (SMT1TMR);

}

周期采集中断服务程序

voidSMT1_PR_ACQ_ISR(void)

{

// Disabling SMT1 period acquisitioninterrupt flag bit.

PIR8bits.SMT1PRAIF = 0;

}

精选留言
延伸阅读
更多报告干货
写留言
3966
阅读
收藏
回到顶部