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

[Lecture 04] LED

ansui 2023. 10. 16. 16:25

Lecture 04_LED

 


< LED (Lignt-Emitting Diode) >

> LED:  current가 흐를 때 발광하는 semiconductor(diode) light source

 

> Diode: current (primarily)가 한방향으로 흐르는 Two-terminal electronic component 

- positive side: anode - 긴 다리

- negative side: cathode - 짧은 다리

- 한쪽 방향은 low resistance(거의 0), 다른 한쪽은 high resistance(거의 무한)

- If you connect an LED directly to a current source,

it will try to dissipate(소멸) as much power as it's allowed to draw, then, it will destroy itself.
→ Registers limit the current in the circuit and protect the LED from trying to draw too much current.

 

 

< An Example of Basic Red 5mm Oval LED >

: LED가 켜져있다면 2V·20mA 허용

예시) 해당 led는 16-18mA 전류 추천, 20mA까지 충분, 최대 30mA

20mA 전류가 흐를 때 최소 1.8V - 최대 2.2V

 

 

< Resistors >

: 절대 변하지 않는 electrical resistance를 갖는 electonic components

: circuit의 전자 흐름을 제한

*Short circuit

: 짧은 회로에서 positive, negative side를 직접적으로 연결하면 전선이 타거나 배터리가 망가진다. 

 

- Series resistors (직렬)

총 저항 값 = 연결된 모든 저항의 합

- Parallel resistors (병렬)

총 저항 값 = 각 저항의 역수를 합하고 다시 역수

 

> 옴의 법칙

V = I * R

→ 전압(Voltage) = 전류(Current) * 저항(Resistance)

→ 단위: V = A * Ω

 5V 전원과 1Ω이 연결되어 있다면, 전류는 5A  직렬 연결: 2Ω과 3Ω → 총 저항 값 5Ω

 5V 전압이 공급될 때 전류 1A

 1A → 2Ω 저항에 공급되는 전압 2V
 1A → 3Ω 저항에 공급되는 전압 3V

 

> Voltage divider

: 큰 전압을 작은 전압으로 바꿔주는 registor circuit

: 직렬 연결된 두개의 resistors만을 사용하여 output voltage를 계산한다.

 

EX) if R1 was 1.7k Ω and R2 was 3.3k Ω.

5V input voltage could be turned into 3.3V at the Vout terminal.

V = 5V * ( 3.3k / ( 1.7k Ω + 3.3k Ω ) ) = 3.3V


> LED current limiting

: Red 5mm LED는 보통 최대 전류를 20mA로 제한한다.

 

EX) assume you have a 9V battery to power an LED.

It might have a forward voltage around 1.8V.

If you want to limit the current to 10mA.

R = ( 9V - 1.8V ) / 0.010A = 720 Ω

 

 

< Schematic for P1.0 Red LED >

Current: High(1): LED 켜기 → Low(0): LED끄기

 

 

< Memory Map for P1.0 Red LED >

: 메모리에 접근 → control

Pin#4 is connected to P1.0 Red LED and configured as GPIO.

 

> Memory address range for GPIO.

> GPIO memory map: 0x40004C00 (base address) ~ 0x40004FFF (16진수)
- Size of the map: 1024 Byte
- 접근 방법: byte 단위(8 bits)로 offset을 조정하여 접근한다

 

> GPIO port: a group of multiple GPIO pins port 1 부터 10.
- 예) P1.0: GPIO port 1 (00000001) / pin 0 

*02h = 02, 0Ah = 10

 

> Port direction register (PxDIR)

: Configure a specific GPIO pin as either input or output

- input(0): switch button

- output(1): LED on/off

- Size: 1 byte = 8 bits → 8개의 핀 의미

- Value: binary number (00000000, 00000001) → hexadecimal number (0x00, 0x01)

 

 

< GPIO P1.0 Output >

1. Find the port direction register (P1DIR) address = Base Address + offset = 0x40004C00 + 0x04

2. Find the corresponding bit for pin#0 in port 1 (P1.0)
3. Set the pin#0 as output (HIGH 1) → 00000001 → 0x01

4. Find the port output register (P1OUT) address = Base Address + offset = 0x40004C00 + 0x02

5. Find the corresponding bit for pin#0 in port 1 (P1.0)
6. Set the pin#0 as output (HIGH 1) → 00000001 → 0x01

 

 

< Using C Pointer to Access a Specific Address >

> Pointer in C

: 다른 object의 address를 포함하는 constant나 variable

 

> Referencing pointer

- Program code는 pointer가 지정한 주소에 값을 읽고 쓸 수 있다.

 

> Access hardware using C pointer

: 하드웨어에 memory map의 주소를 가진 C 포인터를 사용하여 값을 읽고 쓸 수 있다

 

 

< Using C Pointer to Access a Specific Address >

#include <stdio.h>

int main(void) {
  int a;
  int *ptr;
  ptr = &a; // ptr에 a의 메모리 주소 할당
  *ptr = 10; // 메모리 위치에 10 저장 -> a = 10

  printf("a = %d\n", a); // a = 10
  printf("*ptr = %d, ptr = %p\n", *ptr, ptr); // *ptr = 10, ptr = 메모리 주소
  return 0;
}

 

 

< Dealing with Registers for GPIO in C >

: Declare and initialize a pointer variable for GPIO P1DIR/P1OUT register

→ Read/Write a value from/to the GPIO P1DIR/P1OUT register.

volatile unsigned char *gpio_p1dir, *gpio_p1out;  // volatile: gpio 변경 가능

gpio_p1dir = (unsigned char *)(0x40004C04);  // offset 4만큼 이동

gpio_p1out = (unsigned char *)(0x40004C02);  // offset 2만큼 이동

 

 

< volatile Keyword in C >

- 일반적으로 compiler는 어떤 변수도 program code 내에서만 변경 가능하다고 가정한다.

- 변수를 volatile로 선언하는 것: compiler가 구현 외부에서 언제든지 변수를 수정할 수 있다.

→ 포인터가 memory mapped된 하드웨어를 지정할 경우 volatile 키워드를 사용해야 한다.

- 제외해도 되는 코드를 없앰으로써 성능 최적화을 하는데 이로 인해 외부 하드웨어 제어 시 문제가 발생한다.

 

예) buffer가 full일 때 buffer_full =1, 아니면 0이라고 가정

buffer_full을 volatile로 선언 X → 컴파일러가 값이 loop 외부에서 수정되지 않았다고 가정하므로 값 reloading을 생략

 

 

< Basic C Integer Data Types >

 

 

 

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