[Tiva] TM4C 시리즈에서 타이머 구현

임베디드/TI 2014. 7. 26. 13:53

 MCU를 다룰 때 타이머의 가장 인상적인 점이라면 개발자가 원하는 주기 마다 인터럽트를 발생시켜 구현하고자 하는 동작을 만들 수 있다는 점이지요.

 TM4C에서 타이머의 가장 큰 특징은 1개의 TIMER를 A와 B로 나누어서 사용할 수 있다는 점입니다. 본 예제에서는 각 타이머의 A만을 다루나 A를 B로 바꾸어서 쓰거나 B를 추가 하는 것 만으로도 동작이 되는 것을 보실 수 있습니다.

 2개의 타이머 인터럽트를 사용하여 1초씩 카운트 하는 프로그램을 구성해 보았습니다.

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
 
uint32_t count=0, count1=0;
 
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif
 
    //TIMER0을 설정하는 인터럽트 핸들러
void Timer0IntHandler(void) {
 
    //
    // Clear the timer interrupt.
    //
    ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
 
    count++;
    if(count>=100)
        count=0;
 
    ROM_IntMasterDisable();
    UARTprintf("\r%2d : %2d",count1, count);
    ROM_IntMasterEnable();
}
 
    //TIMER1을 설정하는 인터럽트 핸들러
void Timer1IntHandler(void) {
 
    //
    // Clear the timer interrupt.
    //
    ROM_TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
 
    count1++;
    if(count1>=60)
        count1=0;
 
    ROM_IntMasterDisable();
    UARTprintf("\r%2d : %2d",count1, count);
    ROM_IntMasterEnable();
}
 
    //UART 출력을 설정한다.
void ConfigureUART(void) {
    //
    // Enable the GPIO Peripheral used by the UART.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
 
    //
    // Enable UART0
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
 
    //
    // Configure GPIO Pins for UART mode.
    //
    ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
 
    //
    // Use the internal 16MHz oscillator as the UART clock source.
    //
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
 
    //
    // Initialize the UART for console I/O.
    //
    UARTStdioConfig(0, 115200, 16000000);
}
 
int main(void) {
    //
    // Enable lazy stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    ROM_FPULazyStackingEnable();
 
    //
    // Set the clocking to run directly from the crystal.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    SYSCTL_XTAL_16MHZ);
 
    //
    // Initialize the UART and write status.
    //
    ConfigureUART();
 
    //
    // TIMER0과 TIMER1이 동작할 수 있도록 설정해준다.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
 
    //
    // MCU가 인터럽트를 사용할 수 있도록 설정해준다.
    //
    ROM_IntMasterEnable();
 
    //
    // 타이머의 동작 방식을 설정해준다. 매 주기마다 동작할 수 있도록 TIMER_CFG_PERIODIC을 설정한다.
    //
    ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
 
    //
    // TIMERA의 주기를 설정한다. ROM_SysCtlClockGet()의 값은 MCU의 주파수를 뜻하며 1초당 동작수를 말한다.
    //
    ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ROM_SysCtlClockGet() / 100);
    ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ROM_SysCtlClockGet() / 1);
 
    //
    // 각 타이머의 인터럽트를 사용할 수 있도록 설정한다.
    //
    ROM_IntEnable(INT_TIMER0A);
    ROM_IntEnable(INT_TIMER1A);
 
    //
    // 설정한 타이머의 인터럽트가 동작할 수 있도록 허용한다.
    //
    ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
 
    //
    // 타이머를 동작시킨다.
    //
    ROM_TimerEnable(TIMER0_BASE, TIMER_A);
    ROM_TimerEnable(TIMER1_BASE, TIMER_A);
 
    //
    // Loop forever while the timers run.
    //
    while (1) {
    }
}
 




300x250