C언어로 라즈베리파이4 레지스터 접근하여 LED점멸시키기

imalright.tistory.com/6

 

C언어로 라즈베리파이4 GPIO 레지스터 접근하여 LED점멸시키기

사용하려는 GPIO는 GPFSEL1 레지스터에서 GPIO18번을 사용하려고 합니다. gpio[GPFSEL1/4] |= (1< GPIO18번의 비트가 24~26비트까지기 떄문에 24~26번째 비트의 값을 001로 바꾸어주면 GPIO18번핀은 출력모드가..

imalright.tistory.com

를 해봤는데

이번에는 버튼을추가해서 버튼을 누르면 LED가 켜지고 손을 떼면 LED가 꺼지게 됩니다.

지난번 글에서 해놓았던 GPIO18번에는 LED가 연결되어 있습니다.

GPIO17번으로부터 값을 가져오기 떄문에 17번비트의 값이 1인지 여부만 알면 됩니다.

버튼을 누르게 되면 5V가 핀으로 입력되어서 해당핀에대응되는 비트는 1로 변경되기 때문입니다.

#include <stdlib.h>    
#include <stdio.h>    
#include <sys/types.h>    
#include <sys/stat.h>    
#include <fcntl.h>    
#include <sys/mman.h>    
      
      
#define GPIO_BASE 0x3F200000    
#define GPFSEL1   0x04  
#define GPLEV0    0x34  
#define GPSET0    0x1C  
#define GPCLR0    0x28    
      
      
int main()    
{    
    int fd = open( "/dev/gpiomem", O_RDWR|O_SYNC );    
    if ( fd < 0 ){    
        printf( "can't open /dev/gpiomem \n" );    
        exit(-1);    
    }    
      
      
    char *gpio_memory_map = (char *)mmap( 0, 4096, PROT_READ|PROT_WRITE,    
        MAP_SHARED, fd, GPIO_BASE );    
      
    if ( gpio_memory_map == MAP_FAILED )    
    {    
        printf( " Error : mmap \n" );    
        exit(-1);    
    }    
      
          
    volatile unsigned int* gpio = (volatile unsigned int*)gpio_memory_map;    
   
    gpio[GPFSEL1/4] |= (1<<24);    
       
    while(1)    
    {   
        int input = gpio[GPLEV0/4] & (0x01<<17);  
  
        if ( input > 0 )   
            gpio[GPSET0/4] |= (1<<18);   
        else  
            gpio[GPCLR0/4] |= (1<<18);  
    }    
      
     munmap( gpio_memory_map, 4096);    
  
    return 0;    
}    

컴파일할때는

pi@raspberrypi:~$ g++ btn.c -o btn

 

실행은

pi@raspberrypi:~$ sudo ./btn

 

으로 실행하시면 버튼을 누르고 있을때 led가 켜지고 손을떼면 led가 꺼지는 것을 확인할 수 있습니다

 

라즈베리파이와 브레드보드 연결입니다.

 

사용하려는 GPIO는 GPFSEL1 레지스터에서 GPIO18번을 사용하려고 합니다.

gpio[GPFSEL1/4] |= (1<<24);

GPIO18번의 비트가 24~26비트까지기 떄문에 24~26번째 비트의 값을 001로 바꾸어주면 GPIO18번핀은 출력모드가 됩니다.

 

그리고 다음레지스터들에서 GPIO18번 위치에 해당되는 비트들을 세팅해주면 LED를 ON,OFF시킬수 있습니다.

gpio[GPSET0/4] |= (1<<18); 

 

gpio[GPCLR0/4] |= (1<<18);

 

전체소스코드 입니다.

#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 GPIO_BASE 0x3F200000    
#define GPFSEL1   0x04  
#define GPSET0    0x1C  
#define GPCLR0    0x28    
        
        
int main()    
{    
    int fd = open( "/dev/gpiomem", O_RDWR|O_SYNC );    
    if ( fd < 0 ){    
        printf( "can't open /dev/gpiomem \n" );    
        exit(-1);    
    }    
        
        
    char *gpio_memory_map = (char *)mmap( 0, 4096, PROT_READ|PROT_WRITE,    
        MAP_SHARED, fd, GPIO_BASE );    
        
    if ( gpio_memory_map == MAP_FAILED )    
    {    
        printf( " Error : mmap \n" );    
        exit(-1);    
    }    
        
            
    volatile unsigned int* gpio = (volatile unsigned int*)gpio_memory_map;    
    //gpio[GPFSEL1/4] = 0b00000001000000000000000000000000;    
    gpio[GPFSEL1/4] |= (1<<24);    
        
    int i;    
    for ( i=0; i<5; i++ )    
    {    
        //gpio[GPSET0/4] = 0b00000000000001000000000000000000;    
        gpio[GPSET0/4] |= (1<<18);   
        sleep(1);    
        
        //gpio[GPCLR0/4] = 0b00000000000001000000000000000000;   
        gpio[GPCLR0/4] |= (1<<18);  
        sleep(1);    
    }    
        
     munmap( gpio_memory_map, 4096);    
    
    return 0;    
} 

라즈베리파이 2나3에선 /dev/mem 을 사용했지만 라즈베리파이4부터는 /dev/gpiomem 을 사용해서 gpio의 레지스터에 접근해서 사용할 수 있습니다.

 

컴파일 할땐

pi@raspberrypi:~$ g++ led.c -o led

이런식으로 명령어를 사용해주시고 실행할땐 관리자권한이 필요하기 때문에

pi@raspberrypi:~$ sudo ./led

sudo 를 사용해서 관리자권한을 주셔야 합니다.

실행하면 LED가 5번 깜빡이는것을 볼 수 있습니다.

+ Recent posts