本帖最后由 oxygenzz 于 2019-4-8 18:18 编辑
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;
}
|