对于TTC和AXI_Timer,都可以用来用作定时器,也可以用来输出PWM波形。
使用这几个定时器,都需要设置相关中断,中断的产生主要和设置的模式以及设置定时器装载值相关,当定时器有关计数寄存器到计数中期调用中断服务函数/中断处理函数,输出标志位或者干一些其他时间周期要求的事。
对于使用TTC,模式配置需要配置TmrCntrSetup结构体,相关选项的宏有以下几个:
#define XTTCPS_OPTION_EXTERNAL_CLK 0x00000001U /**< External clock source */
#define XTTCPS_OPTION_CLK_EDGE_NEG 0x00000002U /**< Clock on trailing edge for
external clock*/
#define XTTCPS_OPTION_INTERVAL_MODE 0x00000004U /**< Interval mode */
#define XTTCPS_OPTION_DECREMENT 0x00000008U /**< Decrement the counter */
#define XTTCPS_OPTION_MATCH_MODE 0x00000010U /**< Match mode */
#define XTTCPS_OPTION_WAVE_DISABLE 0x00000020U /**< No waveform output */
#define XTTCPS_OPTION_WAVE_POLARITY 0x00000040U /**< Waveform polarity */
结构体包含的元素如下,设置的选型就是设置Options:
typedef struct {
u32 OutputHz; /* Output frequency */
XInterval Interval; /* Interval value */
u8 Prescaler; /* Prescaler value */
u16 Options; /* Option settings */
} TmrCntrSetup;
一般用来做最基本的计时,选择XTTCPS_OPTION_INTERVAL_MODE和XTTCPS_OPTION_WAVE_DISABLE。
其他的用来设置输出频率、间隔值和预分频器。一般间隔值和预分频器初始设为0就行。XTtcPs_CalcIntervalFromFreq函数会通过频率计算间隔值和预装载值。得出间隔值和预分频值后通过XTtcPs_SetInterval、XTtcPs_SetPrescaler设置。
如果结构体里面设置的频率是100Hz,在中断程序中进行计数,当XTTCPS_IXR_INTERVAL_MASK不等于0的时候,计数加1,计数到100的时候为1s。我的理解就是TTC间隔1/100s。
对于使用AXI_Timer,时钟周期的设置和AXI_Timer使用的频率有关。一般连的是硬核出来的那个时钟,对于7系列,就是50MHz,这个时候设置装载值就是5*10^7*计数时间(以秒为单位)-1。即每个周期的间隔是1/50MHz,根据这个基本的周期时间计算想要的定时器计数时间。注意这里有个坑就是直接填装载值,如果不设置向下计数模式,默认AXI_Timer是往上加的,不是减。如果设置默认模式,计算方法和这个不同,得用寄存器最大值减去装载值,根据这个差算需要的计时器周期。
使用XTmrCtr_SetOptions函数对计数器的模式进行配置。一般设置为:
XTmrCtr_SetOptions(&TimerCounterInst, TIMER_CNTR_0,
XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION |XTC_DOWN_COUNT_OPTION);
对于私有定时器,其采用CPU时钟,计时相关的寄存器,填入的装载值计算就是:CPU_CLK_HZ/(预分频值+1)-1。需要设置Auto_Reload模式,调用官方BSP库里面的XScuTimer_LoadTimer填入装载值,私有定时器默认向下计数。
XScuTimer_EnableAutoReload(&TimerInstance);
XScuTimer_LoadTimer(&TimerInstance, Load_Val);
三种Zynq定时器设置解析
1252

被折叠的 条评论
为什么被折叠?



