01_GPIO 操作

主要介绍imx28x的GPIO操作

  • GPIO序号

gpio序号=BANK*32 + N

比如p2.4的GPIO序号就是:

2*32+4=68

imx283/287的四个GPIO的序号分别是:

描述名称序号
LED1GPIO3_26122
LED2GPIO3_22118
LED3GPIO3_20116
LED4GPIO2_771

GPIO的PIN定义可以查看bootloader/u-boot-2009.08/include/asm-arm/arch-mx28/pinctrl.h

  • GPIO操作
  1. 导出GPIO

cd /sys/class/gpio/

echo 71 >export

  1. 设置方向

echo in > direction

echo out > direction

  1. 设置高低电平

echo 0 >value

echo 1 >value

  1. 应用示例
#include     <stdio.h>
#include     <stdlib.h>
#include     <unistd.h>
#include     <sys/types.h>
#include     <sys/stat.h>
#include     <fcntl.h>
#include     <termios.h>
#include     <errno.h>

#define DEV_PATH        "/sys/devices/virtual/gpio/gpio68/value"

int main(void)
{
        int fd = 0;
        char value;

        fd = open(DEV_PATH, O_RDWR);
        if (fd < 0) {
                perror(DEV_PATH);
        }

        lseek(fd, 0, SEEK_SET);
        read(fd, &value, 1);
        printf("get value:%c \n", value);

        close(fd);
        return 0;
}


  • beep驱动

无源蜂鸣器需要2K~5K的方波驱动,所以BEEP的驱动就是控制GPIO产生PWM方波

驱动源文件位于:
3.Linux\4.开发示例\6、驱动示例\beep\

  1. BEEP驱动源码:
/*
   GPIO Driver driver for EasyARM-iMX283
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/delay.h>
#include <linux/bcd.h>
#include <linux/capability.h>
#include <linux/rtc.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>

#include <../arch/arm/mach-mx28/mx28_pins.h>

#define DEVICE_NAME	"imx283_beep"

/*--------------------------------------------------------------------------------------------------------
*/
static int gpio_open(struct inode *inode, struct file *filp);
static int  gpio_release(struct inode *inode, struct file *filp);
ssize_t gpio_write(struct file *filp, const char __user *buf, size_t count,
                loff_t *f_pos);
static int gpio_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg);
static int gpio_init(void);
static void gpio_exit(void);

/*--------------------------------------------------------------------------------------------------------
*/

static int gpio_open(struct inode *inode, struct file *filp)
{
	gpio_request(MXS_PIN_TO_GPIO(PINID_LCD_D21), "beep");

	return 0;
}

static int  gpio_release(struct inode *inode, struct file *filp)
{
	gpio_free(MXS_PIN_TO_GPIO(PINID_LCD_D21));
	return 0;
}


ssize_t gpio_write(struct file *filp, const char __user *buf, size_t count,
                loff_t *f_pos)
{
	char data[2];

	copy_from_user(data, buf, count);
	gpio_direction_output(MXS_PIN_TO_GPIO(PINID_LCD_D21), data[0]);

	return count;
}

static int gpio_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)
{
	int data;
	
	switch (command) {
	case 0: 
		gpio_direction_output(MXS_PIN_TO_GPIO(PINID_LCD_D21), 1);
		break;
	
	case 1:
		gpio_direction_output(MXS_PIN_TO_GPIO(PINID_LCD_D21), 0);
		break;
	}

	return 0;
}

static struct file_operations gpio_fops={
	.owner		= THIS_MODULE,
	.open 		= gpio_open,
	.write		= gpio_write,
	.release	= gpio_release,
	.ioctl		= gpio_ioctl,
};

static struct miscdevice gpio_miscdev = {
	.minor  = MISC_DYNAMIC_MINOR,
	.name	= DEVICE_NAME,
	.fops	= &gpio_fops,
};	

static int __init gpio_init(void)
{

	misc_register(&gpio_miscdev);
	printk(DEVICE_NAME" up. \n"); 

	return 0;
}

static void __exit gpio_exit(void)
{


	misc_deregister(&gpio_miscdev);
	printk(DEVICE_NAME " down.\n");
}

module_init(gpio_init);
module_exit(gpio_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("zhuguojun, ZhiYuan Electronics Co, Ltd.");
MODULE_DESCRIPTION("GPIO DRIVER FOR MAGICARM270.");
  1. 测试程序

这个测试程序运行后BEEP不会响,原因是sleep()时间太长,产生的方波不满足BEEP的工作需求,将sleep()函数改为usleep()

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <limits.h>
#include <asm/ioctls.h>
#include <time.h>
#include <pthread.h>


int main(void)
{
	int fd;
	char buf[1] = {0};

	fd = open("/dev/imx283_beep", O_RDWR);
	if (fd < 0) {
		perror("open /dev/imx283_gpio");
	}

	printf("test write....\n");
	buf[0] = 1;
	write(fd, buf, 1);
	sleep(2);

	buf[0] = 0;
	write(fd, buf, 1);
	sleep(1);	

	printf("test ioctl..... \n");
	ioctl(fd, 0);
	sleep(2);
	ioctl(fd, 1);
	sleep(1);
}

修改后的程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <limits.h>
#include <asm/ioctls.h>
#include <time.h>
#include <pthread.h>

int main(void)
{
	int fd;
	char buf[1] = {0};

	fd = open("/dev/imx283_beep", O_RDWR);
	if (fd < 0) {
		perror("open /dev/imx283_gpio");
	}

	printf("test write....\n");

	while(1){
	buf[0] = 1;
	write(fd, buf, 1);
	usleep(50);


	buf[0] = 0;
	write(fd, buf, 1);
	usleep(50);
}	

	printf("test ioctl..... \n");
	ioctl(fd, 0);
	sleep(2);
	ioctl(fd, 1);
	sleep(1);
}
  • led驱动

根据pinctrl.h中的定义

#define PINID_SSP0_DATA7 PINID_ENCODE(2, 7)

修改驱动控制led4

#define LED_GPIO MXS_PIN_TO_GPIO(PINID_SSP0_DATA7)

  1. led驱动程序
/*
   GPIO Driver driver for EasyARM-iMX283
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/delay.h>
#include <linux/bcd.h>
#include <linux/capability.h>
#include <linux/rtc.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>

#include <../arch/arm/mach-mx28/mx28_pins.h>

#define DEVICE_NAME	"imx28x_led"

#define LED_GPIO	MXS_PIN_TO_GPIO(PINID_SSP0_DATA7)		//for 283 287A/B
//#define LED_GPIO	MXS_PIN_TO_GPIO(PINID_SAIF0_MCLK)	//for 280

/*--------------------------------------------------------------------------------------------------------
*/
static int gpio_open(struct inode *inode, struct file *filp);
static int  gpio_release(struct inode *inode, struct file *filp);
ssize_t gpio_write(struct file *filp, const char __user *buf, size_t count,
                loff_t *f_pos);
static int gpio_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg);
static int gpio_init(void);
static void gpio_exit(void);

/*--------------------------------------------------------------------------------------------------------
*/

static int gpio_open(struct inode *inode, struct file *filp)
{
	gpio_request(LED_GPIO, "led");

	return 0;
}

static int  gpio_release(struct inode *inode, struct file *filp)
{
	gpio_free(LED_GPIO);
	return 0;
}


ssize_t gpio_write(struct file *filp, const char __user *buf, size_t count,
                loff_t *f_pos)
{
	char data[2];

	copy_from_user(data, buf, count);
	gpio_direction_output(LED_GPIO, data[0]);

	return count;
}

static int gpio_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)
{
	int data;
	
	switch (command) {
	case 0: 
		gpio_direction_output(LED_GPIO, 0);
		break;
	
	case 1:
		gpio_direction_output(LED_GPIO, 1);
		break;
	}

	return 0;
}

static struct file_operations gpio_fops={
	.owner		= THIS_MODULE,
	.open 		= gpio_open,
	.write		= gpio_write,
	.release	= gpio_release,
	.ioctl		= gpio_ioctl,
};

static struct miscdevice gpio_miscdev = {
	.minor  = MISC_DYNAMIC_MINOR,
	.name	= DEVICE_NAME,
	.fops	= &gpio_fops,
};	

static int __init gpio_init(void)
{

	misc_register(&gpio_miscdev);
	printk(DEVICE_NAME" up. \n"); 

	return 0;
}

static void __exit gpio_exit(void)
{
	misc_deregister(&gpio_miscdev);
	printk(DEVICE_NAME " down.\n");
}

module_init(gpio_init);
module_exit(gpio_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("zhuguojun, ZhiYuan Electronics Co, Ltd.");
MODULE_DESCRIPTION("GPIO DRIVER FOR EasyARM-i.MX28xx");


  1. led测试程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <limits.h>
#include <asm/ioctls.h>
#include <time.h>
#include <pthread.h>


int main(void)
{
	int fd;
	char buf[1] = {0};

	fd = open("/dev/imx28x_led", O_RDWR);
	if (fd < 0) {
		perror("open /dev/imx283_led");
	}

	printf("test write....\n");
	buf[0] = 0;
	write(fd, buf, 1);
	sleep(2);

	buf[0] = 1;
	write(fd, buf, 1);
	sleep(1);	

	printf("test ioctl..... \n");
	ioctl(fd, 0);
	sleep(2);
	ioctl(fd, 1);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值