리눅스/라즈베리파이

라즈베리파이 gpio led 시스템 레지스터 메모리 맵 입출력 방식

피어나는 열정 2020. 9. 3. 16:57

 

 주소         /  필드명

0x7E20 0004 GPFSEL1 : 입출력 선택 

0x7E20 001C GPSET0 : 출력 설정

0x7E20 0028 GPCLR0 : 출력 해제

 

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>



#define BCM_IO_BASE 0x3F000000 // 라즈베리 2나 3의 메모리 주소
#define GPIO_BASE (BCM_IO_BASE + 0X200000) //컨트롤러 주소
#define GPIO_SIZE (256)

#define GPIO_IN(g) (*(gpio+((g)/10)) &= ~(7<<(((g)%10)*3)))
#define GPIO_OUT(g) (*(gpio+((g)/10)) |= (1<<(((g)%10)*3)))

#define GPIO_SET(g) (*(gpio +7) = 1<<g)
#define GPIO_CLR(g) (*(gpio +10) = 1<<g)
#define GPIO_GET(g) (*(gpio +13) &(1<<g))


volatile unsigned *gpio;

int main( int argc, char **argv) // 쉘 영역에서 입력 받고 시작하는 코드임

{
int gno,i,mem_fd;
void *gpio_map;

if(argc<2){
printf("usage :%s gpio_no\n",argv[0]);
return -1;

}

gno =atoi(argv[1]); // atoi 문자열을 정수 타입으로
if ((mem_fd =open("/dev/mem", O_RDWR | O_SYNC)) <0){ // 디바이스 열기
perror("open() /dev/mem\n");
return -1;

}



gpio_map = mmap( NULL, GPIO_SIZE, PROT_READ | PROT_WRITE, //gpio 와 mmap
MAP_SHARED, mem_fd, GPIO_BASE );

if ( gpio_map == MAP_FAILED ){
printf( " Error : mmap \n" );
perror -1;
}

gpio = (volatile unsigned *)gpio_map;
GPIO_OUT(gno); // 출력 설정 gpio18번
for(i=0;i<10000;i++){ 
GPIO_SET(gno); //해당 gpio  핀 값 설정
sleep(1); //1초
GPIO_CLR(gno); //해당 gpio  핀 값 해제
sleep(1);
}

munmap(gpio_map, GPIO_SIZE);
close(mem_fd);
return 0;

}