Study/임베디드시스템및실험

[Exercise 05] 버튼 2개 이용하여 LED 켜기

ansui 2023. 10. 18. 00:44

Exercise 05_버튼 2개 이용하여 LED 켜기
 


< User Buttons Initialization  >

> PxDIR: GPIO 포트 1번의 pin 1번과, pin 4번을 0으로 주어 입력 모드로 설정

- Input(Button): 0 / Output(LED): 1

( 1<<1 ) | (1<<4) → ( 00000010 | 00010000 ) → 00010010

~ ( 1<<1 | 1<<4 )   ~ ( 00010010 )     11101101

 

> PxREN: pullup resistor 켜기

- Pullup or Pulldown disabled: 0 / Pullup or Pulldown enabled: 1

- 1번 핀과 4번 핀만 1값을 주어 pull-up/pull-down 활성화

( 1<<1 ) | ( 1<<4 ) → ( 00000010 | 00010000 ) → 00010010

 

> PxOUT:  OUT에서 pull-up 으로 선택하기

- Pulldown selected: 0 / Pullup selected: 1

- out이라서 출력만 관여한다고 생각하겠지만, 입력 모드로 사용 시에는 out으로도 pull-up 활성화를 지정

- P1OUT은 pull-up/ pull-down 둘 다 가능해서 특정 입력 모드를 꼭 선택해야 한다.

( 1<<1 ) | ( 1<<4 ) → ( 00000010 | 00010000 ) → 00010010

 

>  PxIN: GPIO Input Register

- 해당 핀에 넣을 HIGH/LOW 신호 지정

- LOW: 0 / High: 1

 

→ 해당 자리에 1 값이 들어가 있는지 확인

- P1.1에 HIGH 신호를 넣었는지 확인

if ((P1->IN & (1<<1)) == (1<<1))

 

- P1.4에 HIGH 신호를 넣었는지 확인

if ((P1->IN & (1<<4)) == (1<<4))

#include "msp.h"

// S1BUT: P1.1 == 0 (pull-up register: 스위치 누르면 low)
#define S1BUT ((P1->IN & (1<<1)) == 0x00)

void main(void)
{
	P1->DIR &= ~(1<<1 | 1<<4); // P1.1, P1.4 0으로 설정(input mode)
	P1->REN = (1<<1) | (1<<4); // P1.1, P1.4에서 pull-up register 켜기
	P1->OUT = (1<<1) | (1<<4); // P1.1, P1.4에서 pull-up register 사용
}

 

 

< 0, 1 정리 >

0 1

 - False
 - Input (DIR): Button

 - Pullup or Pulldown disabled (REN)
 - Pulldown selected (OUT)
 - LOW (IN)
 - Pullup 레지스터에서 스위치 눌렀을 때
 - Pulldown 레지스터에서 스위치 뗐을 때

 - True ( 0이 아닌 모든 숫자 )
 - Output (DIR): LED

 - Pullup or Pulldown enabled (REN)
 - Pullup selected (OUT)

 - HIGH (IN)
 - Pullup 레지스터에서 스위치 뗐을 때
 - Pulldown 레지스터에서 스위치 눌렀을 때

 

 

< Programming Exercise >

- If S2 button is pressed, then the color of RGB LED P2.{012} becomes WHITE! (RGB가 매우 빠르게 반복되기 때문이다.)

- If S2 button is pressed and the released, the color of RGB LED P2.{012} is chosen randomly among Red, Green, Blue (어느 순간에 멈추는지 알 수 없기 때문이다.)

 

> WHITE 이유?

: 프로세서가 손가락보다 빠르므로 버튼을 누르는 순간 RGB가 반복해서 움직이기 때문에 흰색처럼 보이게 된다.

 

 

< State Machine (FSM: Finite-State Machine) >

- polling loop에서 loop을 몇번 돌았는 지 통제할 수 없다.

→ 계속 누르는 상태에서 하얀색이 나오는 것을 방지

 

 

< RGB LED - State Machine for Button >

 


< Excercise 04 >
> Exercise Objective
S1, S2 버튼을 눌렀을 때 P1.0 LED 에 빨간색 불이 들어오고 버튼을 떼면 불이 꺼지도록 설계한다. S1 버튼을 눌렀을 때 P2.0 LED 에 R→BG 의 순서로 불이 들어오도록 하고, S2 버튼을 눌렀을 때 P2.0 LED 에 RGB 의 순서로 불이 들어오도록 설계하는 것이 이번 프로젝트의 목표이다.

> 코드

P1.1 - S1 버튼 / P1.4 - S2버튼 : Input

P1.0 - P1.0 LED (R) : Output

P2.0, P2.1, P2.2 - P2.0 LED (R, G, B) : Output

#include "msp.h"

#define S1BUT ((P1->IN & (1<<1)) == 0x00) // S1 버튼을 눌렀는 지 확인
#define S2BUT ((P1->IN & (1<<4)) == 0x00) // S2 버튼을 눌렀는 지 확인

#define S1_INIT 1
#define S1_DOWN 2
#define S1_UP 3

#define S2_INIT 1
#define S2_DOWN 2
#define S2_UP 3

void main(void) {
  int p2_pos = 0;
  
  int s1but_bs = S1_INIT; // S1 버튼의 State 변수 초기화
  int s2but_bs = S2_INIT; // S2 버튼의 State 변수 초기화
 
  P1->DIR &= ~(1<<4|1<<1); // 1.1, 1.4를 Input(0)으로 설정
  P1->DIR |= 1<<0; // 1.0을 Output(1)으로 설정
  P2->DIR |= 1<<2|1<<1|1<<0; //2.0, 2.1, 2.2를 Output(1)으로 설정
  
  P1->REN = 1<<4|1<<1; // Pullup, Pulldown 켜기(1)
  P1->OUT = 1<<4|1<<1; // Pullup 레지스터 선택(1)
  
  P1->OUT &= ~(1<<0); // 1.0 LED 끄기(0x00)
  P2->OUT = 1<<p2_pos; // 초기 위치(00000001)로 설정 Red LED on
  
  while(1){
    //S1버튼을 누른 경우
    if (S1BUT) {
      P1->OUT |= 1<<0; //1.0 Red Led on
      
      if (s1but_bs == S1_UP) {
        if (p2_pos > 0)
          p2_pos--;
        else
          p2_pos = 2;
      P2->OUT = 1<<p2_pos;
      }
      s1but_bs = S1_DOWN;
    }
    
    //S2버튼을 누른 경우
    else if (S2BUT) {
      P1->OUT |= 1<<0; //1.0 Red Led on
      
      if (s2but_bs == S2_UP) {
        if (p2_pos < 2)
          p2_pos++;
        else
          p2_pos = 0;
      P2->OUT = 1<<p2_pos;
      }
      s2but_bs = S2_DOWN;
    }
 
    //처음 아무 버튼도 누르지 않았을 경우 & 버튼이 떼어진 경우
    else { 
      s1but_bs = S1_UP;
      s2but_bs = S2_UP;
      P1->OUT &= ~(1<<0); //1.0 LED off 
    }
  }
}

자료는 이화여자대학교 윤명국 교수님의 임베디드시스템및실험 강의에서 가져온 것입니다.