打印
[PIC®/AVR®/dsPIC®产品]

使用MCC学习PIC单片机 – SMT 信号测量定时器

[复制链接]
1913|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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;

}



使用特权

评论回复
沙发
请叫我树人| | 2019-4-9 08:34 | 只看该作者
好帖子啊!帮你顶住啊!感谢分享啊! 真是不错啊!赞一个啊!

使用特权

评论回复
板凳
consumption| | 2019-4-10 16:41 | 只看该作者
感谢分享!很不错的经验

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

46

主题

190

帖子

11

粉丝