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;
}