검색결과 리스트
글
[Tiva] TM4C의 I2C 통신 파형 보는 방법
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 통신을 종료합니다.
'임베디드 > TI' 카테고리의 다른 글
[Tiva]startup_ccs.c 파일에 외부 인터럽트 추가하기 (0) | 2014.08.09 |
---|---|
[Tiva] I2CMasterSlaveAddrSet() (0) | 2014.08.01 |
[Tiva] TM4C 시리즈에서 외부인터럽트 구현 (12) | 2014.07.26 |
[Tiva] TM4C 시리즈에서 타이머 구현 (0) | 2014.07.26 |
[Tiva] Tera Term으로 런치패드와 UART 통신하기 (0) | 2014.07.23 |
설정
트랙백
댓글
글
MCU 입력으로 설정한 핀의 값이 일정하지 않을 때(Floating)
MCU를 설계할 때 많은 빈도로 사용되는 기능 중 하나는 아마 GPIO(General Purpose Input Output)일 겁니다. 거의 모든 MCU 설계의 기본이기도 하지요.
MCU를 처음으로 설계하는 분들 중 MCU의 핀 하나를 입력으로 설정하여 입력을 받는게 받아들이는 값이 지멋대로 튀어 원치않는 값을 받는 경우를 경험하신 분들이 계실거라 생각합니다. 분명 VCC에 걸리면 HIGH 상태가 되고 GND에 연결하면 LOW 상태가 확실히 걸리는데 유독 아무런 값도 걸지 않은 상태에서는 값이 자기 맘대로 튀어 당황하신 분들도 계실거라 생각합니다.
이와 같은 현상을 플로팅(Floating)이라 하며, 해당 핀의 상태가 HIGH도 아니고 LOW도 아닌 값을 가지고 있는 상황이 되는 것입니다. 즉, 확실한 값을 가지고 있지 않기 때문에 이 상태에서 입력값을 받으면 MCU는 계속해서 이상한 값을 가지게 되는 것입니다.
이러한 상태를 해결하는 방법으로 풀업(pull-up)과 풀다운(pull-down) 방식이 있습니다.
pull-up방식은 해당 입력핀의 연결라인 중간에 저항을 연결하고 해당 저항이 HIGH상태(주로 VCC)에 연결되어 있는 상황을 말합니다. 이렇게 회로를 설계하면 해당 입력핀의 값은 HIGH를 유지하다가 전압이 0으로 내려가면 LOW상태가 되며 값이 플로팅 상태 때보다 매우 안정적인 값을 얻으실 수 있습니다. pull-up 방식은 주로 I2C 통신에서 많이 사용되는 회로 입니다.
위 그림은 I2C회로의 간략한 회로입니다. I2C회로는 각 기기들과 2개의 선으로 연결되어 있는데 해당 2개의 선인 SDA와 SCL은 다른 기기들과 그냥 연결하게 되면 Open Drain 상태가 되여 마스터의 입력이 HIGH가 되어도 Slave는 LOW값을 받아들이는 상태만 지속됩니다. 이러한 두 선에 pull-up 회로를 연결하게 되면 보통때에 HIGH 상태를 유지하던 회로가 MASTER에 의해 LOW 상태가 되면 똑같이 LOW 상태를 보이며 회로가 원하는 디래 동작을 할 수 있게 됩니다.
pull-down 방식은 위해서 설명한 pull-up 방식과는 반대로 저항의 끝에 GND를 연결하여 LOW 상태를 유지하게 해줍니다. 이 상태에서 HIGH 값이 들어오게 되면 입력핀에서도 HIGH 값을 받을 수 있게 되는 것입니다.
위 그림은 pull-down 방식이 적용된 MCU의 상황입니다. 저항과 GND를 연결한 상태로 값이 들어오고 있지 않는 상황에서는 LOW 상태를 유지하다가 VCC나 다른 장치로부터 값이 들어오게 되면 MCU가 HIGH 상태를 인식할 수 있게 되는 것이지요.
위와 같은 회로를 설계에 참고하신다면 입력값의 Floating 상태를 적절하게 방지하실 수 있을 것으로 보입니다.
좀 더 자세한 내용을 알고 싶으신 분들께 관련 내용이 잘 정리되어 있는 블로그를 알려드리겠습니다.
'임베디드 > MCU' 카테고리의 다른 글
Infineon AURIX TC237 사용기(2) - TriCore™ 컴파일 후 프로그램 실행 (5) | 2016.06.26 |
---|---|
Infineon AURIX TC237 사용기(1) - TriCore™ Entry Tool Chain 설치하기 (1) | 2016.04.26 |
Timer를 활용하여 특정 파형간 간격 측정방법 (0) | 2015.03.25 |
mcu를 활용한 진동모터 회로 설계 (0) | 2014.07.25 |
I2C(TWI) 통신 (2) | 2014.07.24 |
설정
트랙백
댓글
글
[Tiva] TM4C 시리즈에서 외부인터럽트 구현
MCU를 활용하는 사람이면 거의 대다수가 맨 처음 프로그램을 구동할 때GPIO(General Purpose Input Output)를 구현하여 동작을 확인하는 경험을 해보셨을 것이라 생각합니다. TI에서 제공하는 Tiva C 시리즈인 TM4C MCU 시리즈 또한 이를 잘 구현해 놓았지요.
ATmega시리즈로 순식간에 인터럽트를 설정하시던 분들도 Tiva 시리즈를 다룰 때 다소 해메시는 분들도 계실것이라 생각합니다. 하지만 그렇다고 처음부터 겁을 먹을 필요는 없습니다. 코드로 표현하는 방식이 다를 뿐 다른 MCU들 처럼 구현할 수 있는 기능은 똑같으니 말이지요.
이번에는 MCU 프로그램의 필수 요소라 할 수 있는 Interrupt를 구현해보도록 하겠습니다. 인터럽트와 관련이 있는 부분은 직접 주석으로 적어두었으므로 하나씩 읽으면서 익혀두셨으면 합니다.
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에서 인터럽트가 발생하여 설정된 함수를 실행한다.
'임베디드 > TI' 카테고리의 다른 글
[Tiva] I2CMasterSlaveAddrSet() (0) | 2014.08.01 |
---|---|
[Tiva] TM4C의 I2C 통신 파형 보는 방법 (4) | 2014.07.28 |
[Tiva] TM4C 시리즈에서 타이머 구현 (0) | 2014.07.26 |
[Tiva] Tera Term으로 런치패드와 UART 통신하기 (0) | 2014.07.23 |
[Tiva] Tiva C 런치패드에 프로그램 올리기 (0) | 2014.07.21 |