一.实验简介
通过定时器的timer模式来计时实现以1s为间隔将LED翻转。
二.板载定时器介绍
TM4C有两种定时器,一种为16/32bit的,一种是32/64bit的,两种定时器各有六个,对于每个定时器来说,它可以单独以较大的bit位作为一个定时器工作,也可以拆分为两个较小的bit位的定时器分别工作。比如对于16/32bit位的定时器,可以以32bit位的定时器工作,也可以以两个16bit的定时器A和B分别工作。
三.原理图及引脚分布
四.所需函数
用到的控制LED的GPIO相关函数与UART函数还有中断相关函数不再提起,有疑问的可以看我之前的文章
1.SysCtlPeripheralEnable(uint32_t ui32Peripheral)
参数:ui32Peripheral如果为16/32bit的定时器就是TIMER,如果是32/64bit的定时器就是WTIMER。
作用:使能外设
2.TimerConfigure(uint32_t ui32Base, uint32_t ui32Config)
参数:ui32Base为定时器基地址,ui32Config定时器所配置模式
作用:如果在定时器不拆分的情况下,可以将ui32Config设置为以下模式之一:
TIMER_CFG_ONE_SHOT – 单次减计数模式
TIMER_CFG_ONE_SHOT_UP – 单次加计数模式
TIMER_CFG_PERIODIC – 连续减计数模式
TIMER_CFG_PERIODIC_UP – 连续加计数模式
TIMER_CFG_RTC – 实时时钟模式
如果将定时器拆分的话则将ui32Config设置为TIMER_CFG_SPLIT_PAIR(分裂为一对)然后与以下模式进行或运算:
TIMER_CFG_A_ONE_SHOT – 定时器A单次减计数
TIMER_CFG_A_ONE_SHOT_UP –定时器A单次加计数
TIMER_CFG_A_PERIODIC – 定时器A连续减计数
TIMER_CFG_A_PERIODIC_UP – 定时器A连续加计数
TIMER_CFG_B_ONE_SHOT – 定时器B单次减计数
TIMER_CFG_B_ONE_SHOT_UP –定时器B单次加计数
TIMER_CFG_B_PERIODIC – 定时器B连续减计数
TIMER_CFG_B_PERIODIC_UP – 定时器B连续加计数
拆分之后的定时器AB都一样,用哪个就设置哪个,只是函数名有区别。
3.TimerLoadSet(uint32_t ui32Base, uint32_t ui32Timer, uint32_t ui32Value)
参数:ui32Base为定时器基地址,ui32Timer有TIMER_A,TIMER_B和TIMER_BOTH(单独A,单独B,AB都用)三种选择,在定时器拆分的情况下用哪个就设置哪个,在不拆分的情况下就设置为TIMER_A(对于其他函数也是,如果在级联的情况下还需要选择,那默认为选择TIMER_A),ui32Value为定时器加载值,一般来说定时时间=1/N,那么定时器加载值=SysCtlClockGet()/N-1,即根据自己的定时时间求出N,即可得定时器加载值。
此函数适用于16bit,32bit的定时器,即适用于16/32bit的定时器拆分与级联,32/64bit定时器的拆分三种情况,对于64bit的定时器,即32/64bit定时器的级联使用TimerLoadSet64。
作用:配置定时器加载值。
4.TimerIntRegister(uint32_t ui32Base, uint32_t ui32Timer,void (*pfnHandler)(void))
参数:ui32Base为定时器基地址,ui32Timer也是有TIMER_A,TIMER_B和TIMER_BOTH三种,对于级联的定时器设置为TIMER_A即可,void (*pfnHandler)(void)为中断函数名
作用:注册中断函数
5.TimerIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags)
参数:ui32Base为定时器基地址,ui32IntFlags为中断模式,在定时器状态下一般设置为TIMER_TIMB_TIMEOUT或TIMER_TIMA_TIMEOUT
作用:使能定时器中断
9.TimerEnable(uint32_t ui32Base, uint32_t ui32Timer)
参数:ui32Base为定时器基地址,ui32Timer也是有TIMER_A,TIMER_B和TIMER_BOTH三种。
五.代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82timer_timer.c /*此代码分别使用16/32bit的定时器拆分与32/64bit的定时器级联实现同样的功能*/ #include "timer.h" #include "timer_timer.h" #include "hw_memmap.h" #include "gpio.h" #include "sysctl.h" #include "interrupt.h" #include "hw_ints.h" _Bool flag=0; void TIMER_IRQHandler(void); void TIMER_WID_IRQHandler(void); //16/32bit定时器拆分 void Timer_Config(void) { //使能定时器TIMER0,16/32bit SysCtlPeripheralEnable( SYSCTL_PERIPH_TIMER0); //配置定时器,将定时器拆分,并配置拆分后的定时器A为周期性计数 TimerConfigure( TIMER0_BASE, TIMER_CFG_SPLIT_PAIR|TIMER_CFG_A_PERIODIC_UP); //设置定时器A装载值,因为要1ms进一次中断,所以1ms=1/1000, 所以重装载值为SysCtlClockGet()/1000-1 TimerLoadSet( TIMER0_BASE, TIMER_A, SysCtlClockGet()/1000-1); //为定时器A注册中断函数 TimerIntRegister( TIMER0_BASE, TIMER_A, TIMER_IRQHandler); //使能time0的定时器A为超时中断 TimerIntEnable( TIMER0_BASE, TIMER_TIMA_TIMEOUT); //设置中断优先级 IntPrioritySet( INT_TIMER0A, 0); //使能中断 IntEnable( INT_TIMER0A); IntMasterEnable(); //使能定时器 TimerEnable( TIMER0_BASE, TIMER_A); } void TIMER_IRQHandler(void) { static uint32_t time_count=0; //读取定时器中断状态 uint32_t status=TimerIntStatus( TIMER0_BASE, true); //清除中断标志位 TimerIntClear( TIMER0_BASE, status); //1ms进一次中断 time_count++; //进一千次,也就是1s,翻转flag if(time_count==1000) { time_count=0; flag=!flag; } } //32/64bit的定时器级联 void Timer_Wid_Config(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_WTIMER0); //设置不拆分并且周期计数 TimerConfigure(WTIMER0_BASE,TIMER_CFG_PERIODIC_UP); TimerLoadSet64( WTIMER0_BASE, SysCtlClockGet()/1000-1); //级联的情况下默认都是设置定时器A TimerIntEnable( WTIMER0_BASE, TIMER_TIMA_TIMEOUT); TimerIntRegister( WTIMER0_BASE, TIMER_A, TIMER_WID_IRQHandler); IntPrioritySet( INT_WTIMER0A, 1); IntEnable( INT_WTIMER0A); IntMasterEnable(); TimerEnable( WTIMER0_BASE, TIMER_A); } void TIMER_WID_IRQHandler(void) { static uint32_t time_count=0; uint32_t status=TimerIntStatus( WTIMER0_BASE, true); TimerIntClear( WTIMER0_BASE, status); time_count++; if(time_count==1000) { time_count=0; flag=!flag; } }
1
2
3
4
5
6
7
8
9timer_timer.h #ifndef __TIMER_TIMER_H #define __TIMER_TIMER_H extern _Bool flag; void Timer_Config(void); void TIMER_IRQHandler(void); void Timer_Wid_Config(void); void TIMER_WID_IRQHandler(void); #endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14led.c #include "led.h" #include "gpio.h" #include "sysctl.h" #include "hw_gpio.h" #include "hw_memmap.h" void LED_Config(void) { SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOF); GPIODirModeSet( GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_DIR_MODE_OUT); GPIOPadConfigSet( GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); }
1
2
3
4
5led.h #ifndef __LED_H #define __LED_H void LED_Config(void); #endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31main.c #include "tm4c123gh6pm.h" #include <stdint.h> #include <stdbool.h> #include "inc/hw_sysctl.h" #include "inc/hw_gpio.h" #include "inc/hw_memmap.h" #include "driverlib/gpio.h" #include "driverlib/sysctl.h" #include "uartstdio.h" #include "usart.h" #include "timer_timer.h" #include "led.h" void main(void) { SysCtlClockSet( SYSCTL_SYSDIV_4|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN|SYSCTL_USE_PLL); LED_Config(); //Timer_Config(); Timer_Wid_Config(); while(1) { if(flag==0) { GPIOPinWrite( GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2); } else { GPIOPinWrite( GPIO_PORTF_BASE, GPIO_PIN_2, 0); } } }
最后
以上就是霸气芒果最近收集整理的关于TM4C123系列(五)————timer定时器(timer模式)的全部内容,更多相关TM4C123系列(五)————timer定时器(timer模式)内容请搜索靠谱客的其他文章。
发表评论 取消回复