2016年9月11日 星期日

[Raspberry] 在Raspberry Pi 2 使用GPIO(一)

查看gpio的物理地址:
cat /proc/iomem |grep  gpio | grep gpio
3f2000000=3f20000b3 : /soc/gpio@7e200000                         

程式:

#include <cstdlib>

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

#define BCM2708_PERI_BASE 0x3F000000  //0x20000000 --> Raspberry Pi的位址
#define GPIO_BASE (BCM2708_PERI_BASE +0x200000) /* GPIO controller*/
#define PAGE_SIZE  (4*1024)
#define BLOCK_SIZE (4*1024)

int mem_fd;
void *gpio_map;

//IO access
volatile unsigned *gpio;

//GPIO setup macros. Always use INP_GPIO(x) before using 
//OUT_GPIO(x) or SET_GPIO_ALT(x,y) 
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))

#define GPIO_SET *(gpio+7)  //sets bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) //clears bits which are 1 ignores bits which are 0
#define GET_GPIO(g) (*(gpio+13)&(1<<g)) //0 if Low, (1<<g) if High
#define GPIO_PULL *(gpio+37) //pull up/pull down

using namespace std;

void setup_io()
{
    if((mem_fd = open("/dev/mem",O_RDWR|O_SYNC))<0)
    {
        printf("Can not open /dev/mem \n");
        exit(-1);
    }
    
    //map GPIO
    gpio_map=mmap(
            NULL,                   //anyadress inourspace will do
            BLOCK_SIZE,             //map length
            PROT_READ|PROT_WRITE,   //enable reading & writting to mappedmemory
            MAP_SHARED,             //shared with other processes
            mem_fd,                 //fileto map
            GPIO_BASE               //offset to GPIOperipheral
            );
    
    close(mem_fd);      //No need to keep mem_fd open after map
    
    if(gpio_map==MAP_FAILED){
        printf("mmap error %d\n",(int)gpio_map);    //errnoalso set
        exit(-1);
    }   
    gpio=(volatile unsigned*)gpio_map;
}


int main(int argc, char** argv) {

    //set up gpi pointer for direct register access
    setup_io();

    printf("step 1 ok\r\n");    
    
    //MustuseINP_GPIO before we can use OUT_GPIO
    INP_GPIO(14);
    OUT_GPIO(14);

    for(int j=0;j<10;j++)
    {
        GPIO_SET=1<<14;
        sleep(1);
        GPIO_CLR=1<<14;
        sleep(1);
    }
        
    return 0;
}



開始跑出現 can not open /dev/mem,就停下來了

進入 NetBeans IDE 8.1 視窗
選擇 Run --> Set Project Configuration -->Customize…
左邊選擇Run,在右邊Run Command,加入 sudo
“${OUTPUT_PATH}” --> sudo “${OUTPUT_PATH}”      
成功運行了 !!!


沒有留言:

張貼留言