[Tiva] GPIOIntTypeSet()

임베디드/TI 2015. 7. 13. 10:55

void GPIOIntTypeSet(uint32_t ui32Port, uint8_t ui8Pins, uint32_t ui32IntType)

설명 : 특정한 핀에 대한 인터럽트 방식을 설정합니다.


uint32_t ui32Port

GPIO의 포트를 설정합니다.


uint8_t ui8Pins

설정하고자 하는 해당 포트의 핀번호를 선택합니다.


uint32_t ui32IntType

자신이 원하는 인터럽트의 신호를 선택합니다.


 여기서 ui32IntType를 통하여 다음과 같은 인터럽트 신호들을 감지할 수 있도록 설정할 수 있습니다.


GPIO_FALLING_EDGE

핀의 입력이 1에서 0으로 내려가는 순간에 인터럽트를 발생시킵니다.


GPIO_RISING_EDGE

핀의 입력이 0에서 1로 올라가는 순간에 인터럽트를 발생시킵니다.


GPIO_BOTH_EDGE

위의 GPIO_FALLING_EDGE와 GPIO_RISING_EDGE가 발생시 인터럽트를 발생시킵니다.


GPIO_LOW_LEVEL

핀의 입력이 0이 되었을 때 인터럽트를 발생시킵니다.


GPIO_HIGH_LEVEL

핀의 입력이 1이 되었을 때 인터럽트를 발생시킵니다.


GPIO_DISCRETE_INT

GPIO 포트에서의 각 핀에 대한 별개의 인터럽트를 설정합니다.



 인터럽트를 설정할 때 의도치 않은 인터럽트 설정을 피하기 위해 위의 함수를 사용할 시에 GPIO의 입력이 안정된 상태어야 합니다. 즉, Floating 현상으로 인해 의도치 않은 인터럽트가 발생할 수 있다는 점을 유의해야 합니다. Floating에 대한 자세한 설명은 아래 포스팅을 참조해 주시기 바랍니다.


http://elecs.tistory.com/15

300x250

[Tiva] Tiva 기반 MCU로 블루투스 모듈을 활용하여 UART 통신하기

임베디드/TI 2014. 9. 13. 02:04

 MCU를 활용하여 다른 기기와의 통신으로 UART를 많이 사용할 겁니다. 이러한 MCU에 블루투스 모듈을 사용하면 간단한 설정으로 무선으로 UART를 활용할 수 있다는 점은 상당히 매력적이지요.

 다만 아쉬운 점이라면 블루투스 모듈을 사용시 AT 커맨드 등 기본적인 활용 지식이 없는 상태에서 입문하기에는 공부할 것이 많다는 점이 블루투스에 입문하는데 장벽이 되고 있기도 하지요.


 아래의 코드는 MCU와 블루투스 모듈이 연결되어 있을 때 해당 코드를 활용하면 바로 다른 기기와 연결모드에 진입할 수 있습니다. 이후 다른 기기와 블루투스를 연결하면 UART 통신을 통해 블루투스와 연결된 기기간에 통신을 할 수 있게 됩니다.


 해당 코드는 TI사의 TM4C123GH6PM MCU를 활용하였으며 소스코드는 TI사의 Tivaware 라이브러리 내의 소스코드를 활용하였습니다. 블루투스 모듈은 FirmTech 사의 FB155BC를 사용하였음을 알립니다.


※UART0은 PC와 연결되어 있으며 UART7은 블루투스 모듈과 연결되어 있습니다.

※블루투스 모듈의 모드는 AT COMMAND를 받는 모드로 설정되어 있습니다.

※블루투스 모듈에 UART로 'AT+BTSCAN'을 전송하면 블루투스 모듈이 다른 기기의 연결을 기다리게 됩니다.




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
157
158
159
160
161
162
163
164
165
166
167
168
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/adc.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
 
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif
 
void ConfigureUART(void) {
    //
    // Enable the GPIO Peripheral used by the UART.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
 
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART7);
 
    //
    // 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);
    ROM_GPIOPinConfigure(GPIO_PE0_U7RX);
    ROM_GPIOPinConfigure(GPIO_PE1_U7TX);
    ROM_GPIOPinTypeUART(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1);
 
    //
    // Use the internal 16MHz oscillator as the UART clock source.
    //
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    
    UARTClockSourceSet(UART7_BASE, UART_CLOCK_PIOSC);
 
    //
    // Initialize the UART for console I/O.
    //
    ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200,
            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
            UART_CONFIG_PAR_NONE));
    ROM_UARTConfigSetExpClk(UART7_BASE, ROM_SysCtlClockGet(), 9600,
            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
            UART_CONFIG_PAR_NONE));
}
 
void findDevice() {
    UARTCharPut(UART7_BASE, 'A');
    UARTCharPut(UART7_BASE, 'T');
    UARTCharPut(UART7_BASE, '+');
    UARTCharPut(UART7_BASE, 'B');
    UARTCharPut(UART7_BASE, 'T');
    UARTCharPut(UART7_BASE, 'S');
    UARTCharPut(UART7_BASE, 'C');
    UARTCharPut(UART7_BASE, 'A');
    UARTCharPut(UART7_BASE, 'N');
    UARTCharPut(UART7_BASE, 0x0D);
}
 
void AT() {
    UARTCharPut(UART7_BASE, 'A');
    UARTCharPut(UART7_BASE, 'T');
    UARTCharPut(UART7_BASE, 0x0D);
    UARTCharPut(UART0_BASE, '0');
}
 
void UARTIntHandler() {
    unsigned char get;
    get = UARTCharGet(UART7_BASE);
    if (get == '\r') {
        UARTCharPut(UART0_BASE, '\n');
        UARTCharPut(UART0_BASE, '\r');
    } else
        UARTCharPut(UART0_BASE, get);
}
 
void InsertUART2() {
    unsigned char get;
    get = UARTCharGet(UART0_BASE);
    
    if (get == '\r') {
        UARTCharPut(UART7_BASE, '\r');
        UARTCharPut(UART7_BASE, '\n');
    } else
        UARTCharPut(UART7_BASE, get);
}
 
void SendString(char *str) {
    while (*str) {
        UARTCharPut(UART7_BASE, *str);
        SysCtlDelay(SysCtlClockGet() / 100);
        str++;
    }
    
}
 
int main(void) {
    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);
 
    //
    // Enable the GPIO port that is used for the on-board LED.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
 
    //
    // Enable the GPIO pins for the LED (PF2 & PF3).
    //
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);
 
    //
    // Initialize the UART.
    //
    ConfigureUART();
 
    IntMasterEnable();
 
    IntEnable(79);
    UARTIntEnable(UART7_BASE, UART_INT_RX | UART_INT_RT);
    UARTIntRegister(UART7_BASE, UARTIntHandler);
 
    IntEnable(21);
    UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
    UARTIntRegister(UART0_BASE, InsertUART2);
 
    SysCtlDelay(SysCtlClockGet() / 4);
    findDevice();
 
    while (1) {
    
    UARTCharPut(UART7_BASE, 'H');
    UARTCharPut(UART7_BASE, 'e');
    UARTCharPut(UART7_BASE, 'l');
    UARTCharPut(UART7_BASE, 'l');
    UARTCharPut(UART7_BASE, 'o');
    UARTCharPut(UART7_BASE, ',');
    UARTCharPut(UART7_BASE, 'W');
    UARTCharPut(UART7_BASE, 'o');
    UARTCharPut(UART7_BASE, 'r');
    UARTCharPut(UART7_BASE, 'l');
    UARTCharPut(UART7_BASE, 'd');
    UARTCharPut(UART7_BASE, '!');
    UARTCharPut(UART7_BASE, '\n');
    UARTCharPut(UART7_BASE, '\r');
    SysCtlDelay(SysCtlClockGet());
    
    }
}
 


300x250

[Tiva] Tiva C 기반의 MCU로 초음파센서 SRF-10 활용하기

임베디드/TI 2014. 9. 12. 23:51

[SRF-10 source code using tm4c123g]


본 소스코드는 TI 사에서 제공하는 TivaWare 기반으로 작성되었으며

TI 사의 tm4c123gh6pm MCU에서 동작을 확안하였음을 알립니다.


기타 문의사항이 있으시거나 코드에 문제가 있을 경우 알려주시면 감사하겠습니다.



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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/uart.h"
#include "driverlib/i2c.h"
#include "utils/uartstdio.h"
 
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif
 
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);
}
 
void DelaySoft(volatile unsigned long ulDelay) {
    SysCtlDelay((SysCtlClockGet() / 10000) * ulDelay);
}
 
#define    SLAVE_ADDRESS    0xE0 / 2
 
void ChangeAddress(int old, int new) {
    ROM_I2CMasterSlaveAddrSet(I2C1_BASE, old, false);
 
    ROM_I2CMasterDataPut(I2C1_BASE, 0x00);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    ROM_I2CMasterDataPut(I2C1_BASE, 0xA0);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    //SysCtlDelay(SysCtlClockGet() / 1000000 * 2);
 
    ROM_I2CMasterDataPut(I2C1_BASE, 0x00);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    ROM_I2CMasterDataPut(I2C1_BASE, 0xAA);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    //SysCtlDelay(SysCtlClockGet() / 1000000 * 2);
 
    ROM_I2CMasterDataPut(I2C1_BASE, 0x00);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    ROM_I2CMasterDataPut(I2C1_BASE, 0xA5);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    //SysCtlDelay(SysCtlClockGet() / 1000000 * 2);
 
    ROM_I2CMasterDataPut(I2C1_BASE, 0x00);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    ROM_I2CMasterDataPut(I2C1_BASE, new);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
}
 
int getI2CValue(int ADDR) {
    uint32_t rcv1 = 0;
    uint32_t rcv2 = 0;
    uint32_t rcv = 0;
 
    ROM_I2CMasterSlaveAddrSet(I2C1_BASE, ADDR, false);
 
    ROM_I2CMasterDataPut(I2C1_BASE, 0x00);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    ROM_I2CMasterDataPut(I2C1_BASE, 0x51);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    SysCtlDelay(SysCtlClockGet() / 1000000 * 2);
 
    ROM_I2CMasterDataPut(I2C1_BASE, 0x02);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    ROM_I2CMasterDataPut(I2C1_BASE, 93);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    DelaySoft(115);
 
    ROM_I2CMasterSlaveAddrSet(I2C1_BASE, ADDR, false);
    ROM_I2CMasterDataPut(I2C1_BASE, 0x02);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    ROM_I2CMasterSlaveAddrSet(I2C1_BASE, ADDR, true);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    rcv1 = ROM_I2CMasterDataGet(I2C1_BASE);
    rcv = rcv1 << 8;
 
    SysCtlDelay(SysCtlClockGet() / 1000000 * 2);
 
    ROM_I2CMasterSlaveAddrSet(I2C1_BASE, ADDR, false);
    ROM_I2CMasterDataPut(I2C1_BASE, 0x03);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    ROM_I2CMasterSlaveAddrSet(I2C1_BASE, ADDR, true);
    ROM_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    rcv2 = ROM_I2CMasterDataGet(I2C1_BASE);
    rcv += rcv2;
 
    //ROM_I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, true);
    //ROM_I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
    //rcv = ROM_I2CMasterDataGet(I2C0_BASE);
 
    while (ROM_I2CMasterBusy(I2C1_BASE)) {
 
    }
 
    //DelaySoft(500);
    DelaySoft(300);
 
    return rcv;
}
 
int main(void) {
    //volatile uint32_t ui32Loop;
    uint32_t var1, var2;
 
    //
    // 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_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
    SYSCTL_OSC_MAIN);
 
    //
    // Enable the GPIO port that is used for the on-board LED.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
 
    ROM_GPIOPinConfigure(GPIO_PA6_I2C1SCL);
    ROM_GPIOPinConfigure(GPIO_PA7_I2C1SDA);
 
    ROM_GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
    ROM_GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
 
    ROM_I2CMasterInitExpClk(I2C1_BASE, SysCtlClockGet(), false);
 
    ROM_I2CMasterSlaveAddrSet(I2C1_BASE, SLAVE_ADDRESS, false);
 
    ROM_I2CMasterEnable(I2C1_BASE);
 
 ConfigureUART();
 
 //I2C Slave의 주소를 바꿀 때 사용합니다.
 //이 때, ChangeAddress의 첫 번째 인자는 원래 주소, 두 번째 인자는 바꾸기를 원하는 주소를 입력합니다.
 //단, 첫 번째 인자의 경우 7비트로 전송해야 하므로 원래 주소 / 2 를 하여 전송하고
 //두 번째 인자의 경우 변경하기 원하는 주소를 그대로 입력해줍니다.
    //ChangeAddress(0xE0 / 2, 0xE2);
 
    //
    // We are finished.  Hang around doing nothing.
    //
    while (1) {
 
        //I2C를 통해 SRF10 초음파 거리측정 센서와 통신하여 거리를 측정합니다.
             //getI2CValue() 함수 사용시 인자는 측정을 원하는 센서의 주소를 입력합니다.
             //단, 7비트로 전송해야 하므로 원래주소 / 2 를 하여 전송합니다.
        var1 = getI2CValue(0xE0 / 2);
        var2 = getI2CValue(0xE2 / 2);
 
        UARTprintf("LEFT : %5d, RIGHT : %5d\r", var1, var2);
    }
}
 


참고 자료 : http://www.robot-electronics.co.uk/htm/srf10tech.htm

300x250

[CCS] The program generated is not compatible with any of the CPUs in your target configuration.

임베디드/TI 2014. 8. 28. 14:04

 Code Composer Studio를 활용하여 MCU를 실행하기 위해 프로젝트 파일을 디버그를 시도하려 할 때 이러한 경고 메시지가 뜨면서 작동이 되지 않는 경우기 있습니다.


 The program generated by "프로젝트명" is not compatible with any of the CPUs in your target configuration. The program will not be looaded.





 위의 경우를 해결하는 방법은 다음과 같습니다.



1. 해당 프로젝트에서 오른쪽 버튼을 누른 후 Properties -> General 메뉴로 들어가면 다음과 같은 화면을 보실 수 있습니다.



Main 탭에서 Connection 란이 비어있는 것을 확인하실 수 있습니다.


2. 설정되어 있지 않은 Connection을 클릭하신 후 MCU와 USB 사이에 연결하는 방식을 설정합니다.

Tiva 시리즈의 경우 "Stellaris In-Circuit Debug Interface"를 선택하시면 되겠습니다.



다음과 같이 설정하신 후 디버그를 시도하면 프로그램이 정상적으로 동작됨을 확인하실 수 있습니다.


참고 : http://e2e.ti.com/support/development_tools/code_composer_studio/f/81/t/319982.aspx

300x250

[Tiva] TM4C MCU와 ECHO UART 통신

임베디드/TI 2014. 8. 27. 21:30

 Tiva MCU를 활용하여 UART의 RX와 TX의 동작을 간단하게 확인할 수 있는 코드입니다.

 MCU가 키보드로부터 입력받은 값을 다시 TX로 출력하는 코드입니다.



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
#include <stdint.h>
#include <stdbool.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/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
 
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif
void ConfigureUART(void) {
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
 
    ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
 
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    UARTStdioConfig(0, 115200, 16000000);
}
 
int main(void) {
    unsigned char getChar;
    ROM_FPULazyStackingEnable();
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
    SYSCTL_OSC_MAIN);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);
 
    ConfigureUART();
    while (1) {
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);
        SysCtlDelay(SysCtlClockGet() / 10 / 3);
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
        SysCtlDelay(SysCtlClockGet() / 10 / 3);
 
        getChar = UARTCharGet(UART0_BASE);
        if(getChar=='\r'){
            UARTCharPut(UART0_BASE, '\n');
            UARTCharPut(UART0_BASE, '\r');
        }else{
            UARTCharPut(UART0_BASE, getChar);
        }
    }
}



 위의 코드를 적용한 후 Port 통신을 실행하여 키보드로 값을 입력하면 그 값을 그대로 컴퓨터로 다시 전송하여 값을 출력한다.




300x250

[Tiva] I2CMasterDataGet()

임베디드/TI 2014. 8. 26. 00:23

 uint32_t I2CMasterDataGet(uint32_t ui32Base)

 설명 : I2C 통신을 통해 Slave로부터 받아온 값을 return값으로 받습니다.


 uint32_t ui32Base

 Slave와 통신을 했던 I2C의 Base Address를 설정합니다.


 위 함수를 사용하기 위해 I2CMasterControl() 함수를 사용하에 Slave로부터 값을 받아야 합니다.


 다음은 위의 함수를 실행하기 위한 코드와 그 결과입니다.



unsigned int rcv = 0;

ROM_I2CMasterSlaveAddrSet(I2C0_BASE, 0xE0 / 2, true);

ROM_I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

rcv = ROM_I2CMasterDataGet(I2C0_BASE);


while (ROM_I2CMasterBusy(I2C0_BASE)) {


}



① : START

② : Slave address
7비트로 전송된 Slave의 address값은 7비트이므로 0xE0 / 2 입니다.

③ : R/S
HIGH 상태이므로 SLAVE로부터 DATA를 전달받게 됩니다.

④ : ACK

⑤ : DATA
Slave로부터 DATA를 전달받습니다. 전달받게된 DATA의 값은 0x00입니다.

⑥ : ACK

⑦ : STOP


300x250

[Tiva] I2CMasterControl()

임베디드/TI 2014. 8. 25. 23:58

 void I2CMasterControl(uint32_t ui32Baseuint32_t ui32Cmd)

 설명 : I2C 통신시 Master의 동작을 설정하는 함수입니다.

 

 uint32_t ui32Base

 I2C 통신을 하게 될 Master의 Base Address를 설정합니다.


 uint32_t ui32Cmd

 I2C 통신을 하게 될 Master가 하게 될 동작을 설정합니다. 이 인자의 경우 다음과 같은 값들을 입력하실 수 있습니다.


I2C_MASTER_CMD_SINGLE_SEND

I2C_MASTER_CMD_SINGLE_RECEIVE

I2C_MASTER_CMD_BURST_SEND_START

I2C_MASTER_CMD_BURST_SEND_CONT

I2C_MASTER_CMD_BURST_SEND_FINISH

I2C_MASTER_CMD_BURST_SEND_ERROR_STOP

I2C_MASTER_CMD_BURST_RECEIVE_START

I2C_MASTER_CMD_BURST_RECEIVE_CONT

I2C_MASTER_CMD_BURST_RECEIVE_FINISH

I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP

I2C_MASTER_CMD_QUICK_COMMAND

I2C_MASTER_CMD_HS_MASTER_CODE_SEND


 이들 중 빈번하게 사옹되는 것으로 다음과 같은 값들이 있습니다.


 I2C_MASTER_CMD_SINGLE_SEND

 Master가 Slave에게 명령어를 전달하는 모드입니다.


 I2C_MASTER_CMD_SINGLE_RECEIVE

 Master가 Slave로부터 명령어를 전달받는 모드입니다.


 I2C_MASTER_CMD_BURST_SEND_START

 Master가 Slave에게 명령어를 전달하는 모드입니다. 위의 I2C_MASTER_CMD_SINGLE_SEND와 달리 바로 명령어를 전달하지 않고 일단 Slave에게 명령어를 전달하겠다는 설정만 합니다.


 I2C_MASTER_CMD_BURST_SEND_CONT

 위의 I2C_MASTER_CMD_BURST_SEND_START를 실행한 후 Slave에게 입력할 명령어를 전달합니다.


 I2C_MASTER_CMD_BURST_SEND_FINISH

 Slave에게 마지막 명령어를 전달한 후 I2C 통신을 종료합니다.


 I2C_MASTER_CMD_BURST_RECEIVE_START

 I2C_MASTER_CMD_BURST_RECEIVE_CONT

 I2C_MASTER_CMD_BURST_RECEIVE_FINISH


 Master가 Slave로부터 명령어를 전달받는 모드로 SINGLE모드와 BURST 모드의 차이는 위의 SEND와 유사합니다.


다음은 SINGLE 모드와 BURST 모드로 I2C통신시 파형을 나타냅니다.


SINGLE_SEND


ROM_I2CMasterSlaveAddrSet(I2C0_BASE, 0xE0 / 2, false);

ROM_I2CMasterDataPut(I2C0_BASE, 0x7E);

ROM_I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);


while (ROM_I2CMasterBusy(I2C0_BASE)) {


}




BURST_SEND


ROM_I2CMasterSlaveAddrSet(I2C0_BASE, 0xE0 / 2, true);

ROM_I2CMasterDataPut(I2C0_BASE, 0x02);

ROM_I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);


while (ROM_I2CMasterBusy(I2C0_BASE)) {


}


ROM_I2CMasterDataPut(I2C0_BASE, 0xFF);

ROM_I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);


while (ROM_I2CMasterBusy(I2C0_BASE)) {


}









300x250

[Tiva] tm4c 시리즈 MCU로 TextLCD(CLCD) 동작

임베디드/TI 2014. 8. 21. 02:30

 MCU로 프로그램을 실행할 때 자신이 확인하고 싶은 값을 보기 위해서 주로 UART통신 또는 TextLCD에 값을 띄워보는 방법이 있습니다.

 MCU가 컴퓨터와 항상 연결되어 있을 때엔 당연히 UART를 통해 원하는 값을 모니터에 출력하는 것이 가능합니다. 그러나 일반적으로 MCU를 응용하시는 분들께서는 컴퓨터와 연결하여 사용하는 경우는 많지 않으실 겁니다. 이럴 때 가장 좋은 방법이 TextLCD를 활용하는 것이지요.


 자신이 원하는 값이 숫자와 같은 수치라면 FND를 사용하는 방법또한 있습니다만 FND의 경우 원하는 값을 얻기애 연결해야 하는 핀의 수가 TextLCD보다 상대적으로 많이 사용되는 편이기도 합니다. 심지어 TextLCD는 텍스트 값 또한 출력이 가능하기 때문에 간단한 수치를 확인하는 목적 이상을 원한다면 TextLCD를 사용하는 쪽이 바람직할 듯 합니다.


 가장 많이 사용되는 TextLCD는 2 X 16일 겁니다. 인터넷 상에서도 Atmega128을 기반으로 한 소스코드도 쉽게 구할 수 있어 생각보다 번거롭지 않게 TextLCD에 값을 출력하실 수 있을 것입니다.


 아래의 코드는 Atmega128에서 많이 사용되는 코드를 TivaWare를 활용하는 MCU에서 바로 사용할 수 있게 작성되었습니다.



참고로 회로는 다음과 같이 연결하시면 되겠습니다.

RS    = A6,    RW    = GND,    EN    = A7

데이터0~7    = B0 ~ B7


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
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
 
void EnablePulse(void) {
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7, GPIO_PIN_7);
    SysCtlDelay(SysCtlClockGet() / 1200);
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_7, 0);
}
 
void sendLCDcommand(unsigned char command) {
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6, 0);
    GPIOPinWrite(GPIO_PORTB_BASE, 0xFF, command);
    EnablePulse();
    SysCtlDelay(SysCtlClockGet() / 1200);
}
 
void InitLcd(void) {
    SysCtlDelay(SysCtlClockGet() / 10);
    sendLCDcommand(0x38);
    sendLCDcommand(0x0C);
    sendLCDcommand(0x01);
    SysCtlDelay(SysCtlClockGet() / 1200);
}
 
void sendLCDdata(unsigned char data) {
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6, GPIO_PIN_6);
    GPIOPinWrite(GPIO_PORTB_BASE, 0xFF, data);
    EnablePulse();
    SysCtlDelay(SysCtlClockGet() / 1200);
 
}
 
void displayStr(char *str){
    while(*str){
        sendLCDdata(*str);
        str++;
    }
}
 
void setLocate(int x, int y){
    unsigned char addr;
    if(x==0)
        addr = 0x80+y;
    else
        addr = 0xC0+y;
    sendLCDcommand(addr);
}
 
void setLcdShift(char a){
    unsigned char shift;
    //0 == Left    1 == Right
    if(a==0)
        shift = 0x18;
    else if(a==1)
        shift = 0x1C;
    sendLCDcommand(shift);
    SysCtlDelay(SysCtlClockGet() / 10);
}
 
int main(void) {
 
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
 
    GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE,
            GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4
                    | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
 
    GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7, 0x00);
    GPIOPinWrite(GPIO_PORTB_BASE,
            GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4
                    | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7, 0x00);
 
 
    InitLcd();
    setLocate(0,1);
    displayStr("Hello, World!");
    setLocate(1,0);
    displayStr("http://elecs.tistory.com/");
 
    while (1) {
        setLcdShift(0);
    }
}
 


해당 코드를 런치패드에 실행시키면 CLCD에 다음과 같은 값이 출력됨을 확인하실 수 있습니다.



300x250

[Tiva]startup_ccs.c 파일에 외부 인터럽트 추가하기

임베디드/TI 2014. 8. 9. 22:33

 Tiva C 기반의 MCU로 외부 인터럽트를 설정할 때 일반적으로 메인함수에서 IntRegister()와 같이 해당 인터럽트가 발생하였을 때 실행할 함수를 직접 설정하는 방법이 있습니다. 이 방법 이외에 인터럽트 함수를 등록할 수 있는 방법이 하나 존재합니다!

 프로젝트 내부에 있는 startup_ccs.c 파일에 인터럽트 함수명을 설정해두면 main() 함수에서 정의를 하지 않아도 해당 함수를 인터럽트로 바로 사용하실 수 있습니다.



프로젝트에서 startup_ccs.c 파일을 열어보면 다음과 같은 함수들을 확인하실 수 있습니다.


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
#include <stdint.h>
#include "inc/hw_nvic.h"
#include "inc/hw_types.h"
 
extern void Timer0IntHandler(void);
extern void Timer1IntHandler(void);
 
#pragma DATA_SECTION(g_pfnVectors, ".intvecs")
void (* const g_pfnVectors[])(void) =
{
    (void (*)(void))((uint32_t)&__STACK_TOP),
                                            // The initial stack pointer
    ResetISR,                               // The reset handler
    NmiSR,                                  // The NMI handler
    FaultISR,                               // The hard fault handler
    //--------코드 생략--------//
    Timer0IntHandler,                       // Timer 0 subtimer A
    IntDefaultHandler,                      // Timer 0 subtimer B
    Timer1IntHandler,                       // Timer 1 subtimer A
    IntDefaultHandler,                      // Timer 1 subtimer B
    IntDefaultHandler,                      // Timer 2 subtimer A
    IntDefaultHandler,                      // Timer 2 subtimer B
    //--------코드 생략--------//
    IntDefaultHandler,                      // PWM 1 Generator 0
    IntDefaultHandler,                      // PWM 1 Generator 1
    IntDefaultHandler,                      // PWM 1 Generator 2
    IntDefaultHandler,                      // PWM 1 Generator 3
    IntDefaultHandler                       // PWM 1 Fault
};


위의 함수에서 extern void는 사용하게 될 인터럽트의 명칭들입니다.

그리고 아래는 등록하고자 하는 코드들의 모임입니다.


extern void로 Timer0IntHandler()와 Time1IntHandler() 함수를 다음과 같이 입력한 후

아래 주석 부분에 자신이 해당 코드를 실행하고자 하는 인터럽트 부분에 함수명을 적어주면 됩니다.


이 과정을 거치신 후 프로그램을 실행하시면 인터럽트가 원활하게 동작되는 것을 확인하실 수 있습니다.

300x250

[Tiva] I2CMasterSlaveAddrSet()

임베디드/TI 2014. 8. 1. 21:02

I2CMasterSlaveAddrSet(uint32_t ui32Base, uint8_t ui8SlaveAddr, bool bReceive)


 이 함수는 MCU가 I2C 통신을 개시하기 전에 통신할 Slave의 주소값을 설정한 후 통신을 개시할 때 쓰는 함수이다.


uint32_t ui32Base

첫 번째 인자는 I2C 통신을 하게 될 Master 의 Base Address이다.


uint8_t ui8SlaveAddr

두 번째 인자는 I2C 통신시 전달할 Slave의 Address이다. 이 때 Slave의 Address값은 7bit값이어야 한다.

시중에 있는 I2C 통신의 DataSheet에서 설정되어 있는 주소는 일반적으로 8비트로 구성되어있는데

이는 해당 8비트 주소의 오른쪽 끝부분이 R/S를 설정하는 부분이기 때문이다.

DataSheet에 설정된 Address를 사용할 경우 실제 Slave의 Address를 오른쪽으로 비트이동을 하면 된다. 간단하게 ui8SlaveAddr / 2를 하면 쉽게 적용할 수 있다.


bool bReceive

세 번째 인자는 I2C 통신시 Slave에게 하고자 하는 R/S를 설정합니다.

true - R(Slave로부터 데이터를 읽어옵니다.)

false - S(Slave에 값을 저장합니다.)



다음은 해당 함수를 적용한 소스코드와 결과이다.


ROM_I2CMasterSlaveAddrSet(I2C0_BASE, 0xE0 / 2, false);

ROM_I2CMasterDataPut(I2C0_BASE, 0x7E);

ROM_I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);


while (ROM_I2CMasterBusy(I2C0_BASE)) {


}




① : SLAVE의 ADDRESS 주소

② : R/S

③ : SLAVE의 ACK

④ : R의 경우 = Master가 Slave로부터 전달되는 값을 읽음

S의 경우 = Master가 Slave에게 값을 전달함

⑤ : Master의 ACK


300x250

[Tiva] TM4C의 I2C 통신 파형 보는 방법

임베디드/TI 2014. 7. 28. 21:50

 I2C 통신을 처음 입문하는 분들은 종종 파형의 원리를 깨닫지 못해 많이 해메는 경우가 많습니다. 코드 상으로는 감이 오지 않는 I2C 통신을 오실로스코프를 통해 파형을 확인해보면 그 원리를 쉽게 알 수 있습니다.




 위 사진은 오실로스코프에 찍은 I2C 통신중인 파형이고 노란색은 SDA, 파란색은 SCL입니다. 아래는 I2C 회로를 설계하는데 참고할 수 있는 데이터시트의 파형입니다.


 위 사진의 파형을 쉽게 구분할 수 있게 7단계로 나누었고 그에 대한 각각의 부분은 다음과 같이 설명할 수 있습니다.


① : START

SCL이 HIGH 상태일 때 SDA가 HIGH에서  LOW로 변하는 것으로 I2C 통신을 개시합니다.


② : Slave address

Master가 통신하기 원하는 Salve address 주소를 전송합니다. 1번째부터 7번째 SCL의 edge 클록에서의 7비트가 Slave Address 주소입니다.


③ : R/S

Master가 Salve 에서 할 동작을 설정합니다. HIGH일 때는 Slave로부터 데이터를 전달받고 LOW일 때는 Slave에 데이터를 전송합니다.


④ : ACK

Slave가 Master에게 데이터를 제대로 전송하였음을 확인하는 신호입니다. Slave가 데이터를 완벽히 수신하였을 때 SDA의 값을 LOW로 끌어내려 SCL에 edge 클록이 들어올 때 까지 고정시키다가 값이 제대로 전달되면 SDA를 놓아줍니다다.


⑤ : DATA

R/S에서 설정 대로 데이터를 보내거나 받는다. 데이터 값은 8비트입니다.


⑥ : ACK

Master가 Slave에게 보내는 ACK 신호입니다.


⑦ : STOP

SCL이 HIGH 상태일 때 SDA가 LOW에서 HIGH로 변하는 것으로 I2C 통신을 종료합니다.


300x250

[Tiva] TM4C 시리즈에서 외부인터럽트 구현

임베디드/TI 2014. 7. 26. 22:09

 MCU를 활용하는 사람이면 거의 대다수가 맨 처음 프로그램을 구동할 때GPIO(General Purpose Input Output)를 구현하여 동작을 확인하는 경험을 해보셨을 것이라 생각합니다. TI에서 제공하는 Tiva C 시리즈인 TM4C MCU 시리즈 또한 이를 잘 구현해 놓았지요.


 ATmega시리즈로 순식간에 인터럽트를 설정하시던 분들도 Tiva 시리즈를 다룰 때 다소 해메시는 분들도 계실것이라 생각합니다. 하지만 그렇다고 처음부터 겁을 먹을 필요는 없습니다. 코드로 표현하는 방식이 다를 뿐 다른 MCU들 처럼 구현할 수 있는 기능은 똑같으니 말이지요.


 이번에는 MCU 프로그램의 필수 요소라 할 수 있는 Interrupt를 구현해보도록 하겠습니다. 인터럽트와 관련이 있는 부분은 직접 주석으로 적어두었으므로 하나씩 읽으면서 익혀두셨으면 합니다.

 

 단, 처음에 Input으로 설정한 핀을 그대로 입력하고자 하는 곳에 꽃게 되면 플로팅 상태가 되기 때문에 입력값이 들쭉날쭉 하는 현상이 벌어집니다. 플로팅 상태의 입력을 안정하게 하는 방법은 다음 포스트를 참고해주시길 바랍니다.

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
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_gpio.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_nvic.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/systick.h"
#include "driverlib/timer.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
 
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif
 
    //자신이 설정하고자 하는 인터럽트 핸들러를 설정한다.
void INT_IntHandler(void) {
    ROM_IntDisable(INT_GPIOA);
    GPIOIntClear(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_6);
 
    UARTprintf("Hello, Interrput!\n");
    ROM_IntEnable(INT_GPIOA);
}
 
 
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_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
 
    //INTERRUPT를 사용할 GPIO핀을 활성화 시킨다.
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
 
    // Initialize the UART.
    ConfigureUART();
 
    //인터럽트를 받아들일 핀을 Input으로 설정한다.
    ROM_GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_6);
 
    //인터럽트되는 핀의 입력 형태를 선택한다. LOW에서 HIGH 상태로 넘어갈 때 인터럽트를 발생시키고자 하면
    //GPIO_RISING_EDGE를 선택한다.
    ROM_GPIOIntTypeSet(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_6, GPIO_RISING_EDGE);
 
    //PORTA의 GPIO 인터럽트를 허용한다.
    GPIOIntEnable(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_6);
 
    //PORTA에서 인터럽트가 발생하였을 때 실행할 함수를 설정한다.
    GPIOIntRegister(GPIO_PORTA_BASE, INT_IntHandler);
 
    //인터럽트가 시작되기 전 Clear 시켜준다.(인터럽트 관련 레지스터를 0으로 만든다.)
    GPIOIntClear(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_6);
 
    ROM_IntEnable(INT_GPIOA);
 
    while (1) {
    }
}


4번 핀과 6번 핀에 HIGH_EDGE 입력이 들어오면 mcu에서 인터럽트가 발생하여 설정된 함수를 실행한다.



300x250