1、PIC32参考资源
PIC32系列参考手册 中文版 链接地址:PIC32系列参考手册 第14章 定时器(https://download.csdn.net/download/Huangtop/20299476?spm=1001.2014.3001.5503)
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灯闪烁。
————————————————
版权声明:本文为CSDN博主「Huangtop」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Huangtop/article/details/119274909