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波形很有意思,有示波器的可以看一下。
总之,这个定时器功能非常强大,可以做很多事情。建议把所有功能都了解一下,即使不用也要知道能做什么。