3

ピンを設定およびクリアする簡単なプログラムを作成しています (目的は、そのピンをカスタム spi_CS として使用することです)。そのピン (gpio1_17、ポート 9 ピン 23 bb ホワイト) をエクスポートして、ファイルシステム経由で使用することはできますが、高速に駆動する必要があります。

これはコードです:

uint32_t *gpio;

int fd = open("/dev/mem", O_RDWR|O_SYNC);
if (fd < 0){
    fprintf(stderr, "Unable to open port\n\r");
    exit(fd);
}

gpio =(uint32_t *) mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO1_offset); // start of GPIOA

if(gpio == (void *) -1) {
    printf("Memory map failed.\n");
    exit(0);
} else {
    printf("Memory mapped at address %p.\n", gpio);
}

printf("\nGPIO_OE:%X\n",gpio[GPIO_OE/4]);
gpio[GPIO_OE/4]=USR1;
printf("\nGPIO_OE:%X\n",gpio[GPIO_OE/4]);

printf("\nGPIO_CLEARDATAOUT:%X\n",gpio[GPIO_CLEARDATAOUT/4]);
gpio[GPIO_CLEARDATAOUT/4]=USR1;
printf("\nGPIO_CLEARDATAOUT:%X\n",gpio[GPIO_CLEARDATAOUT/4]);


sleep(1);

printf("\nGPIO_SETDATAOUT%X\n",gpio[GPIO_SETDATAOUT/4]);
gpio[GPIO_DATAOUT/4]=USR1;
printf("\nGPIO_SETDATAOUT%X\n",gpio[GPIO_SETDATAOUT/4]);

#define GPIO1_offset  0x4804c000
#define GPIO1_size  0x4804cfff-GPIO1_offset
#define GPIO_OE  0x134
#define GPIO_SETDATAOUT  0x194
#define GPIO_CLEARDATAOUT  0x190
#define GPIO_DATAOUT 0x13C
#define USR1  1<<17

プログラムを実行する前にピンを高くすると、そのピンが低くなるため、そのピンを出力可能にすることができます。しかし、私はそれを設定してリセットすることはできません。何か案は?

4

1 に答える 1

-1

なぜレジスタを直接変更するのですか? Linux GPIO として使用する方が簡単です。

#define GPIO_1_17                  "49"                        

int gpio;
status_codes stat = STATUS_SUCCESS;

//Export our GPIOs for use
if((gpio = open("/sys/class/gpio/export", O_WRONLY)) >= 0) {
    write(gpio, GPIO_1_17, strlen(GPIO_1_17));
    close(gpio);
} else {
    stat = STATUS_GPIO_ACCESS_FAILURE;
    break;
}

//Set the direction and pull low
if((gpio = open("/sys/class/gpio/gpio" GPIO_1_17 "/direction", O_WRONLY)) >= 0) {
    write(gpio, "out", 3);  // Set out direction
    close(gpio);
} else {
    stat = STATUS_GPIO_ACCESS_FAILURE;
    break;
}
if((gpio = open("/sys/class/gpio/gpio" GPIO_1_17 "/value", O_WRONLY)) >= 0) {
    write(gpio, "0", 1);    // Pull low
    close(gpio);
} else {
    stat = STATUS_GPIO_ACCESS_FAILURE;
    break;
}

次に、initでgpioとして多重化されていることを確認してください。

上記の mmap メソッドに関する限り、アドレス指定は正しいように見えます。refマニュアルのアドレスはバイトアドレスであり、32ビットポインターを使用しているため、そこにあるものは正しいです。しかし、この行: gpio[GPIO_OE/4]=USR1 は GPIO1 のすべてのピンを出力にしますが、17 は入力になります (0 = 出力、1 = 入力)。あなたはおそらくこれを意味しました: gpio[GPIO_OE/4] &= ~USR1

また、gpio[GPIO_SETDATAOUT/4]=USR1; を持つつもりだったと思います。gpio[GPIO_DATAOUT/4]=USR1 の代わりに; どちらも GPIO1_17 を設定します。ただし、持っているものを使用すると、GPIO1 の他のすべてのピンも 0 に設定されます。

カーネルによっても制御されているものを mmap すると問題が発生する可能性があるため、設計されたカーネル インターフェイスを使用することを強くお勧めします。

幸運を!: )

編集: あなたがファイルシステムを介して直接駆動しない理由をあなたが言ったことに気づきました。なぜなら、それをより速く駆動する必要があるからです! 速度が必要な場合は、カーネルランドで処理が行われるように、SPI ドライバーの作成/変更を検討することもできます。omap gpio インターフェースも簡単に使用できます。リクエストして設定するだけです : )。

于 2015-06-09T12:42:09.727 に答える