当前位置:网站首页>CMT2380F32模块开发10-高级定时器例程

CMT2380F32模块开发10-高级定时器例程

2022-08-11 05:24:00 andylauren

Advanced Timer 是一个包含三个定时器 Timer4/5/6。Timer4/5/6 功能相同的高性能计数器,可用于计数产生不同形式的时钟波形,1 个定时器可以产生互补的一对 PWM 或者独立的 2 路 PWM 输出,可以捕获外界输入进行脉冲宽度或周期测量。

波形有锯齿波、三角波。
基本功能有递加、递减计数方向,软件同步,硬件同步,缓存功能,正交编码计数,通用 PWM 输出,保护机制,AOS 关联动作。
中断类型有计数比较匹配中断,计数周期匹配中断,死区时间错误中断。

这个软件高级软件定时器功能十分强大,pwm波形就能产生非常复杂的,还能产生互补波形,甚至是相位差波形。文档写的很详细,而且例程也很详细,如果你是从头跟到这里,每个例程都有自己读过的话应该很容易的明白这些功能。
这里我就挑几个比较常用的例子讲解一下,剩下的可以自行阅读,没有太大障碍。

CaptureInput例程

本样例主要展示ADT捕获输入功能。连接P23(IA0)与P15(IB0)。串口输出捕获值与计数值非常接近。PIN为P35. 波特率为9600, 8N1。

    stcAdtBaseCntCfg.enCntMode = AdtSawtoothMode;
    stcAdtBaseCntCfg.enCntDir = AdtCntUp;
    stcAdtBaseCntCfg.enCntClkDiv = AdtClkPClk0Div1024;
    Adt_Init(enAdt, &stcAdtBaseCntCfg);  // ADT载波、计数模式、时钟配置

    u16Period = 0xC000;
    Adt_SetPeriod(enAdt, u16Period);  //周期设置

    enAdtCompareA = AdtCompareA;
    u16CompareA = 0x6000;
    Adt_SetCompareValue(enAdt, enAdtCompareA, u16CompareA);  //通用比较基准值寄存器A设置
    stcAdtTIM4ACfg.enCap = AdtCHxCompareOutput;
    stcAdtTIM4ACfg.bOutEn = TRUE;
    stcAdtTIM4ACfg.enPerc = AdtCHxPeriodLow;
    stcAdtTIM4ACfg.enCmpc = AdtCHxCompareHigh;
    stcAdtTIM4ACfg.enStaStp = AdtCHxStateSelSS;
    stcAdtTIM4ACfg.enStaOut = AdtCHxPortOutLow;
    Adt_CHxXPortConfig(enAdt, AdtCHxA, &stcAdtTIM4ACfg);  //端口CHA配置,比较输出功能

    stcAdtTIM4BCfg.enCap = AdtCHxCompareInput;
    Adt_CHxXPortConfig(enAdt, AdtCHxB, &stcAdtTIM4BCfg);  //端口CHB配置,捕获输入功能

    Adt_ConfigHwCaptureB(enAdt, AdtHwTrigTimxBRise);  //硬件捕获B条件配置

    Adt_ConfigIrq(enAdt, AdtCMBIrq, TRUE, Adt4CaptureBCalllback);  //捕获中断B配置

    Adt_StartCount(enAdt);

通道A输出定时器,通道B捕获。

Irq例程

本样例主要展示ADT中断功能。连接P33与P32(TrigB)。查看串口输出:在计数到0x1000、0x3000、0x5000、0x7000时产生比较输出A、B、C、D中断;端口TrigB上升沿和下降沿可产生捕获A、B中断;计数上溢出或下溢出时可产生上溢出或下溢出中断;死区时间错误时可产生死区时间错误中断;串口PIN为P35. 波特率为9600, 8N1。

这个例程就不贴代码了,因为代码注释很详细,就是各种中断的测试代码。

PhaseCount例程

本样例主要展示ADT正交编码位置计数功能,根据AIN和BIN的相位关系进行计数。
根据设定的不同,可以实现1倍计数、2倍计数、4倍计数。

连接P14与P34(IA1),连接P15与P33(IB1)。读取串口输出计数值,并与AN220中图13-17位置模式时相位差计数动作设定(1倍)、图13-18置模式时相位差计数动作设定(2倍)、图13-19位置模式时相位差计数动作设定(4倍)中计数值比较。

    stcAdtTIM5ACfg.bFltEn = TRUE;
    stcAdtTIM5ACfg.enFltClk = AdtFltClkPclk0Div64;
    Adt_CHxXPortConfig(AdTIM5, AdtCHxA, &stcAdtTIM5ACfg);  //端口CHA默认输入,滤波使能

    stcAdtTIM5BCfg.bFltEn = TRUE;
    stcAdtTIM5BCfg.enFltClk = AdtFltClkPclk0Div64;
    Adt_CHxXPortConfig(AdTIM5, AdtCHxB, &stcAdtTIM5BCfg);  //端口CHB默认输入,滤波使能

    Gpio_SetIO(1, 4, FALSE);
    Gpio_SetIO(1, 5, TRUE);
    delay1ms(1000);

#ifdef DEBUG_PRINT
    printf("*************************************\n");
    printf("ADT phase count 1x\n");
#endif
    Adt_ClearHwCntUp(AdTIM5);
    Adt_ClearHwCntDwn(AdTIM5);
    Adt_ConfigHwCntUp(AdTIM5,
                      AdtHwCntTimxBHighTimxARise);  //硬件递加计数条件:CHxB端口为高电平时,CHxA端口上采样到上升沿
    Adt_ConfigHwCntDwn(AdTIM5,
                       AdtHwCntTimxBLowTimxARise);  //硬件递减计数条件:CHxB端口为低电平时,CHxA端口上采样到上升沿
    Adt_SetCount(AdTIM5, 3);
    Adt_StartCount(AdTIM5);
    genClkIn();
    Adt_StopCount(AdTIM5);
    Adt_ClearCount(AdTIM5);
#ifdef DEBUG_PRINT
    printf("\n");
#endif

    Gpio_SetIO(1, 4, FALSE);
    Gpio_SetIO(1, 5, TRUE);
    delay1ms(1000);

#ifdef DEBUG_PRINT
    printf("*************************************\n");
    printf("ADT phase count 2x\n");
#endif
    Adt_ClearHwCntUp(AdTIM5);
    Adt_ClearHwCntDwn(AdTIM5);
    Adt_ConfigHwCntUp(AdTIM5,
                      AdtHwCntTimxBHighTimxARise);  //硬件递加计数条件:CHxB端口为高电平时,CHxA端口上采样到上升沿
    Adt_ConfigHwCntUp(AdTIM5,
                      AdtHwCntTimxBLowTimxAFall);  //硬件递加计数条件:CHxB端口为低电平时,CHxA端口上采样到下降沿
    Adt_ConfigHwCntDwn(AdTIM5,
                       AdtHwCntTimxAHighTimxBRise);  //硬件递减计数条件:CHxA端口为高电平时,CHxB端口上采样到上升沿
    Adt_ConfigHwCntDwn(AdTIM5,
                       AdtHwCntTimxALowTimxBFall);  //硬件递减计数条件:CHxA端口为低电平时,CHxB端口上采样到下降沿
    Adt_SetCount(AdTIM5, 3);
    Adt_StartCount(AdTIM5);
    genClkIn();
    Adt_StopCount(AdTIM5);
    Adt_ClearCount(AdTIM5);
#ifdef DEBUG_PRINT
    printf("\n");
#endif

    Gpio_SetIO(1, 4, FALSE);
    Gpio_SetIO(1, 5, TRUE);
    delay1ms(1000);

#ifdef DEBUG_PRINT
    printf("*************************************\n");
    printf("ADT phase count 4x\n");
#endif
    Adt_ClearHwCntUp(AdTIM5);
    Adt_ClearHwCntDwn(AdTIM5);
    Adt_ConfigHwCntUp(AdTIM5,
                      AdtHwCntTimxBHighTimxARise);  //硬件递加计数条件:CHxB端口为高电平时,CHxA端口上采样到上升沿
    Adt_ConfigHwCntUp(AdTIM5,
                      AdtHwCntTimxBLowTimxAFall);  //硬件递加计数条件:CHxB端口为低电平时,CHxA端口上采样到下降沿
    Adt_ConfigHwCntUp(AdTIM5,
                      AdtHwCntTimxAHighTimxBFall);  //硬件递加计数条件:CHxA端口为高电平时,CHxB端口上采样到下降沿
    Adt_ConfigHwCntUp(AdTIM5,
                      AdtHwCntTimxALowTimxBRise);  //硬件递加计数条件:CHxA端口为低电平时,CHxB端口上采样到上升沿
    Adt_ConfigHwCntDwn(AdTIM5,
                       AdtHwCntTimxAHighTimxBRise);  //硬件递减计数条件:CHxA端口为高电平时,CHxB端口上采样到上升沿
    Adt_ConfigHwCntDwn(AdTIM5,
                       AdtHwCntTimxALowTimxBFall);  //硬件递减计数条件:CHxA端口为低电平时,CHxB端口上采样到下降沿
    Adt_ConfigHwCntDwn(AdTIM5,
                       AdtHwCntTimxBHighTimxAFall);  //硬件递减计数条件:CHxB端口为高电平时,CHxA端口上采样到下降沿
    Adt_ConfigHwCntDwn(AdTIM5,
                       AdtHwCntTimxBLowTimxARise);  //硬件递减计数条件:CHxB端口为低电平时,CHxA端口上采样到上升沿
    Adt_SetCount(AdTIM5, 3);
    Adt_StartCount(AdTIM5);
    genClkIn();
    Adt_StopCount(AdTIM5);
    Adt_ClearCount(AdTIM5);

PwmHwComp例子

本样例主要展示ADT硬件设定GCMBR互补PWM输出,在三角波A模式下,
用于TIMxB端口波形输出的通用比较基准值寄存器(GCMBR)的值由通用比较基准值
寄存器(GCMAR)和死区时间基准值寄存器(DTUAR、DTDAR)的值运算决定。

    stcAdtBaseCntCfg.enCntMode = AdtTriangleModeA;
    stcAdtBaseCntCfg.enCntDir = AdtCntUp;
    stcAdtBaseCntCfg.enCntClkDiv = AdtClkPClk0Div8;
    Adt_Init(enAdt, &stcAdtBaseCntCfg);  // ADT载波、计数模式、时钟配置

    u16Period = 0xEEEE;
    Adt_SetPeriod(enAdt, u16Period);  // ADT载波、计数模式、时钟配置

    enAdtCompare = AdtCompareA;
    u16Compare = 0x9999;
    Adt_SetCompareValue(enAdt, enAdtCompare, u16Compare);  //通用比较基准值寄存器A设置

    enAdtCompare = AdtCompareB;
    u16Compare = 0;
    Adt_SetCompareValue(enAdt, enAdtCompare, u16Compare);  //通用比较基准值寄存器B设置

    enAdtCompare = AdtCompareC;
    u16Compare = 0x8888;
    Adt_SetCompareValue(enAdt, enAdtCompare, u16Compare);  //通用比较基准值寄存器C设置

    Adt_EnableValueBuf(enAdt, AdtCHxA, TRUE);
    // Adt_EnableValueBuf(enAdt, AdtCHxB, TRUE);

    stcAdtTIM4ACfg.enCap = AdtCHxCompareOutput;
    stcAdtTIM4ACfg.bOutEn = TRUE;
    stcAdtTIM4ACfg.enPerc = AdtCHxPeriodKeep;
    stcAdtTIM4ACfg.enCmpc = AdtCHxCompareInv;
    stcAdtTIM4ACfg.enStaStp = AdtCHxStateSelSS;
    stcAdtTIM4ACfg.enStaOut = AdtCHxPortOutLow;
    stcAdtTIM4ACfg.enStpOut = AdtCHxPortOutLow;
    Adt_CHxXPortConfig(enAdt, AdtCHxA, &stcAdtTIM4ACfg);  //端口CHA配置

    stcAdtTIM4BCfg.enCap = AdtCHxCompareOutput;
    stcAdtTIM4BCfg.bOutEn = TRUE;
    stcAdtTIM4BCfg.enPerc = AdtCHxPeriodKeep;
    stcAdtTIM4BCfg.enCmpc = AdtCHxCompareInv;
    stcAdtTIM4BCfg.enStaStp = AdtCHxStateSelSS;
    stcAdtTIM4BCfg.enStaOut = AdtCHxPortOutHigh;
    stcAdtTIM4BCfg.enStpOut = AdtCHxPortOutHigh;
    Adt_CHxXPortConfig(enAdt, AdtCHxB, &stcAdtTIM4BCfg);  //端口CHB配置

    Adt_SetDTUA(enAdt, 0x6666);
    Adt_SetDTDA(enAdt, 0x6666);
    Adt_ConfigDT(enAdt, TRUE, TRUE);

    Adt_ConfigIrq(enAdt, AdtUDFIrq, TRUE, Adt4UnderFullCalllback);  //下溢中断配置

    Adt_StartCount(enAdt);

 这个pwm波形很有意思,有示波器的可以看一下。

总之,这个定时器功能非常强大,可以做很多事情。建议把所有功能都了解一下,即使不用也要知道能做什么。

原网站

版权声明
本文为[andylauren]所创,转载请带上原文链接,感谢
https://blog.csdn.net/andylauren/article/details/126241166