PIC32系列 定时器TMR-16位定时器使用
1、PIC32参考资源
PIC32系列参考手册 中文版 链接地址:PIC32系列参考手册 第14章 定时器
2、使用Harmony3配置定时器生成代码
1、启动MPLAB Harmony3 Configurator组件;
2、选择Harmony路径,不用管,按照给定的就可以,点击Launch;
3、选择器件库和CMSIS组件,按照给定的就可以,点击Launch;
4、启动后界面组件内容如下,左侧为可用的功能组件,右侧为项目功能图形显示;
5、在左侧的列表中打开Peripherals,选择TMR下的TMR2,也就是定时器2,将其拖入右侧的界面中;
6、拖入后右侧界面显示如下,可以看到右侧多了一个TMR2组件;
7、点击组件,右侧Configuration Options显示组件信息,此时可按照需求进行组件配置,图中的配置为,分频系数为2,16位定时器模式,时钟源使用内部时钟,定时时间为1ms,在空闲模式下继续工作;
8、组件配置完成后点击左侧的Generate Code按钮生成代码;
9、点击后会有生成的信息需要确认,是否需要修改;
10、代码生成后需要的操作;
1、启动定时器;
在初始化完成后启动定时器;
TMR2_Start();
2、添加中断任务内容;
在plib_tmr2.c的TIMER_2_InterruptHandler函数中添加内容
uint16_t u16Counter=0;
void TIMER_2_InterruptHandler (void)
{
uint32_t status = 0U;
status = IFS0bits.T2IF;
IFS0CLR = _IFS0_T2IF_MASK;
if(u16Counter<500)
{
u16Counter++;
}
else
{
u16Counter=0;
GPIO_RB0_Toggle();
}
if((tmr2Obj.callback_fn != NULL))
{
tmr2Obj.callback_fn(status, tmr2Obj.context);
}
}
11、编译运行将代码烧录到开发板中;
点击编译按钮,编译提示BUILD SUCCESSFUL,点击烧录,提示Programming/Verify complete,开发板上的LED灯闪烁。
3、工程代码分析
1、TMR2 Configuration Options配置分析
Enable Interrupts?
使能中断服务,勾选该项后,会生成中断相关的代码及函数;
在plib_tmr2.c文件中
初始化完成后使能中断:IEC0SET = _IEC0_T2IE_MASK;
void TIMER_2_InterruptHandler (void)
void TMR2_InterruptEnable(void)
void TMR2_InterruptDisable(void)
void TMR2_CallbackRegister(TMR_CALLBACK callback_fn, uintptr_t context)
在interrupt.c文件中生成中断服务函数
void __ISR(_TIMER_2_VECTOR, ipl1SOFT) TIMER_2_Handler (void)
在plib_evic.c文件中的void EVIC_Initialize( void )函数增加中断优先级设置
IPC2SET = 0x4 | 0x0; /* TIMER_2: Priority 1 / Subpriority 0 */
Select Prescaler
选择分频系数,分频系数修改后会影响计时时间
在初始化时,TCKPS会变化,即T2CONSET;PR2也会变化;
uint32_t TMR2_FrequencyGet(void)函数会返回计时频率;
32-Bit Timer Mode Select Bit
可选Odd numbered and even numbered timers form separate 16-bit timers奇数和偶数定时器形成单独的16位定时器
以及Odd numbered and even numbered timers form a 32-bit timer奇数和偶数定时器组成一个32位定时器
T32位为32位定时器判断,32位定时器中断控制在Slave定时器中
Select Timer Clock Frequency选择时钟源;
可选择Internal peripheral clock或External clock from TxCK pin
选择外部时钟源时需要指定时钟频率
TCS 位为时钟选择位
Timer Clock Frequency 时钟频率,计算得到,是分频后得到的值,定时器时钟;
Timer Period Unit 为定时器时间单位,可选millisecond、microsecond、nanosecond;也就是毫秒、微秒以及纳秒;
Time为计时时间,与上面的单位结合使用,Period Register为周期寄存器数值,通过时间计算得到;
Stop in Idle Mode bit停止在空闲模式位,可选Continue operation even in Idle mode(空闲模式下继续)或Discontinue operation when device enters Idle mode(当设备进入空闲模式时停止)
该位影响SIDL位
SIDL :空闲模式停止位
1 = 在器件进入 Idle (空闲)模式时停止工作;0 = 即使在 Idle (空闲)模式下仍继续工作
2、具体代码分析
//定时器初始化函数
void TMR2_Initialize(void)
{
/* Disable Timer */
T2CONCLR = _T2CON_ON_MASK; //禁止定时器,清零ON控制位
/*
SIDL = 0 //空闲模式停止位
TCKPS =1 //预分频设置
T32 = 0 //32定时器
TCS = 0 //时钟源选择,内部时钟源或外部时钟源
*/
T2CONSET = 0x10; //TxCON与定时器相关的 16 位控制寄存器
/* Clear counter */
TMR2 = 0x0; //TMRx 16位定时器计数器寄存器
/*Set period */
PR2 = 39999U; //PRx与定时器相关的 16 位周期寄存器
/* Enable TMR Interrupt */
IEC0SET = _IEC0_T2IE_MASK; //TxIE中断允许控制位在IEC0中断寄存器中
}
//开启定时器
void TMR2_Start(void)
{
T2CONSET = _T2CON_ON_MASK; //TxIF中断标志状态位在IFS0 中断寄存器中;
}
//关闭定时器
void TMR2_Stop (void)
{
T2CONCLR = _T2CON_ON_MASK; //TxIF中断标志状态位在IFS0 中断寄存器中;
}
//设置周期寄存器
void TMR2_PeriodSet(uint16_t period)
{
PR2 = period; //PRx与定时器相关的16位周期寄存器
}
//获取周期寄存器
uint16_t TMR2_PeriodGet(void)
{
return (uint16_t)PR2; //PRx与定时器相关的16位周期寄存器
}
//获取计数值
uint16_t TMR2_CounterGet(void)
{
return (uint16_t)(TMR2); //TMRx 16位定时器计数器寄存器
}
//获取定时器频率
uint32_t TMR2_FrequencyGet(void)
{
return (40000000); //返回定时器的时钟频率
}
//定时器中断服务函数
void TIMER_2_InterruptHandler (void)
{
uint32_t status = 0U;
status = IFS0bits.T2IF;
IFS0CLR = _IFS0_T2IF_MASK; //清零IFSx寄存器中的TxIF中断标志位
/*可在这添加中断处理内容*/
if((tmr2Obj.callback_fn != NULL))
{
tmr2Obj.callback_fn(status, tmr2Obj.context);
}
}
//中断使能
void TMR2_InterruptEnable(void)
{
IEC0SET = _IEC0_T2IE_MASK; //TxIE中断允许控制位在IEC0中断寄存器
}
//禁止中断
void TMR2_InterruptDisable(void)
{
IEC0CLR = _IEC0_T2IE_MASK; //TxIE中断允许控制位在IEC0中断寄存器
}
//
void TMR2_CallbackRegister(TMR_CALLBACK callback_fn, uintptr_t context)
{
/* Save callback_fn and context in local memory */
tmr2Obj.callback_fn = callback_fn;
tmr2Obj.context = context;
}
//中断服务函数,在interrupts.c中,调用TIMER_2_InterruptHandler
void __ISR(_TIMER_2_VECTOR, ipl1SOFT) TIMER_2_Handler (void)
{
TIMER_2_InterruptHandler();
}
4、16 位同步计数器的初始化步骤
1. 清零 ON 控制位 (TxCON<15> = 0)以禁止定时器。
2. 清零 TCS 控制位 (TxCON<1> = 0)以选择内部 PBCLK 源。
3. 选择所需的定时器输入时钟预分频比。
4. 装载 / 清零定时器寄存器 TMRx。
5. 将所需的 16 位匹配值装入周期寄存器 PRx。
6. 如果使用了中断:
a) 清零 IFSx 寄存器中的 TxIF 中断标志位。
b) 在 IPCx 寄存器中配置中断优先级和子优先级。
c) 将 IECx 寄存器中的 TxIE 中断允许位置 1。
7. 将 ON 控制位置 1 (TxCON<15> = 1)以使能定时器。
4、定时器定时时间计算
T=(P+1)*N/F
其中T为定时时间,单位为s;P为周期数,16位定时器最大值为65535;N为分频数;F为时钟频率;内部时钟频率为80MHz;
5、实验验证
点击编译按钮,编译提示BUILD SUCCESSFUL,点击烧录,提示Programming/Verify complete,开发板上的LED灯闪烁。
时间:2021.07.31