메뉴 건너뛰기

제어 - RaspberryPi.NCLab

GPIO를 이용한 간단한 입력 예제

NCLab9th.강유건 2015.02.24 20:57 조회 수 : 2400 추천:1

GPIO를 이용한 간단한 입력 예제

소스파일 : gpio_control.c



0) 정의 & 함수 선언

#define INPUT            0
#define OUTPUT          1
#define LOW              0
#define HIGH             1
 
#define BLOCK_SIZE      (4*1024)
#define BCM2708_PERI_BASE                    0x20000000
#define GPIO_BASE       (BCM2708_PERI_BASE + 0x00200000)
// Data Sheet의 Address Map에서 확인한바와 같이
// 물리 메모리 0x2000 0000이 Peripheral의 Base Address이고 
// 여기에 0x0020 0000을 더한 주소가 GPIO의 Base Address 이다.

static volatile unsigned int *gpio;
// GPIO의 주소를 저장할 변수이므로 
//32bit 포인터로 선언하고 static, volatile로 선언한다.
void pin_25_Mode( int mode);
//25번 GPIO Pin의 Fuction Set을 하는 함수
int digitalRead_pin_25();
//25번 GPIO Pin의 값을 읽어오는 함수



1) 장치파일을 열어서, 메모리에 매핑시킨다.

int main(){
 
	int fd;
	// 물리 메모리를 파일처럼 사용자 영역에서 사용하는 방법으로
	// /dev/mem 파일을 open()하여 mmap()를 통해 자신이 원하는 
	// 물리메모리 주소에 접근하는 방법을 사용한다.
	if((fd = open("/dev/mem", O_RDWR | O_SYNC) )  < 0){
		printf("Fail open /dev/mem\n");
	}
	// /dev/mem 로 open한 file descriptor와 GPIO_BASE 주소를 인자로 
	// mmap()하게 되면 GPIO_BASE에 대한 주소 값을 리턴 한다.
	gpio = ( unsigned int *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, 
	MAP_SHARED, fd, GPIO_BASE);
 
	// 25번 GPIO의 Function Set을 INPUT으로 한다.
	pin_25_Mode(INPUT);
 
	while(1){
	// digitalRead_pin_25() 함수를 통해 값을 읽어온다.
		printf("%d\n",digitalRead_pin_25());
		sleep(1);
	}
 
	return 0;
}


2) GPFSEL의 해당 비트를 000(input)으로 바꾼다.

GPIO25의 경우, GPFSEL2의 15-17bit를 설정

void pin_25_Mode(int mode)
{
 
	int fSel, shift, alt ;
 
	fSel    = 2;
	shift   = 15;
	//BCM2835-ARM-Peripherals P93에서 보듯이 GPIO 25번의 Function Select를
	//위해 해당 레지스터의 비트에 접근한다. 인자로 받은 값에 따라 Read/Write으로
	//설정 가능하다.
	if (mode == INPUT)
	// 접근하는 주소의 비트가 실제 25번 GPIO의 FSEL 레지스터 비트인지 직접 확인해보기 바란다.
		*(gpio + fSel ) = (*(gpio + fSel) & ~(7 << shift)) ; // Sets bits to     zero = input
	else if (mode == OUTPUT)
		*(gpio + fSel ) = (*(gpio + fSel) & ~(7 << shift)) | (1 << shift) ;
}


3) GPLEV의 해당 비트를 읽는다.

GPIO25의 경우, GPLEV0의 25번 bit를 읽는다.

int digitalRead_pin_25()
{
	int gpioToGPLEV=13;
	//BCM2835-ARM-Peripherals P96에서 보듯이
	// GPIO_BASE Address 기준으로 GPIO 25번의 값을 읽어 올 수 있는
	// 레지스터에 접근한다.
	// 접근하는 주소의 비트가 실제 25번 GPIO의 GPLEV 레지스터 비트인지 직접 확인해보기 바란다.
	if ((*(gpio + gpioToGPLEV) & (1 << ( 25 & 31))) != 0)
		return HIGH ;
	else
		return LOW ;
}



5) 실습


5-1) C파일을 scp명령어를 이용하여 라즈베리파이로 보낸다.

ex) scp gpio_control.c root@<RaspberryPi's IP Address>:/

scp gpio_control.PNG


5-2) 라즈베리파이에서 gcc를 이용하여 컴파일한다.

ex) gcc -o gpio_control gpio_control.c

ssh RaspPi.PNG

gpio_control compile.PNG


5-3) 어플리케이션 실행 ( control + c로 종료 )

ex) ./gpio_control

gpio_control 실행.PNG


RaspberrPi B+001.jpg



a) GPIO25에 5V 입력을 줬을 때

gpio_control input high for real.jpg



gpio_control input high.PNG

b) GPIO25에 GND 입력을 줬을 때

gpio_control input low for real.jpg



gpio_control input low.PNG






출처 : NCLab RaspberryPi강의노트 

Chapter06_라즈베리파이_GPIO&SPI_센서연동실습.ver1.0

위로