×
单片机 > 单片机程序设计 > 详情

ARM开发之用linux通用GPIO接口宏函数操作IO口

发布时间:2020-08-21 发布时间:
|

ARM开发板:S5PV210




驱动步骤:


1.定义一个cdev设备结构体变量


2.给cdev申请设备号


3.定义一个文件操作集


4.设备初始化


5.注册设备进内核


6.申请GPIO口




GPIO相关函数接口:


1.gpio_request(引脚,给引脚的名字)   ----申请GPIO口


第一个参数:


在内核代码 \arch\arm\mach-s5pv210\include\mach\gpio.h 中有定义,如下图(部分)

如GPJ2寄存器的第一个引脚,就是 S5PV210_GPJ2(0)




第二个参数:


为管脚起一个名字而已。


例如:


申请GPJ2CON的第一个管脚,并取名为GPJ2_0:


gpio_request(S5PV210_GPJ2(0),"GPJ2_0");;





2.gpio_free(引脚)  ----释放引脚


既然有 gpio_request来申请引脚,那用完了就要释放掉。释放引脚用函数 gpio_free


例如:


释放GPJ2_0引脚:gpio_free(S5PV210_GPJ2(0));




3.gpio_direction_output(引脚,0/1)   ----给引脚置0或1,并把引脚设置为输出模式


例如:


给引脚GPJ2_0设置为输出模式,并置1:gpio_direction_output(S5PV210_GPJ2(0),1);


返回值:失败返回负值






4.gpio_direction_intput(引脚)   ----给引脚设置成输入模式


例如:


给GPJ2_0 设置成输入模式:gpio_direction_input(SPPV210_GPJ2(0));





5.gpio_set_value(引脚,0/1)   ----给引脚置0或1


例如:


给引脚GPJ2_0设置为1(高电平):gpio_set_value(S5PV210_GPJ2(0),1);


返回值:失败返回负值






6.gpio_get_value(引脚)   ----获取引脚的电平。看是0还是1


例如:


获取GPJ2_0 的电平: int  ret;ret = gpio_get_value(S5PV210_GPJ2(0));






下面给出驱动代码和应用程序代码:(实现Led灯轮流闪烁)


#include

#include

#include

#include

#include

#include

#include

#include

#include

 

/*1.定义设备结构体*/

static struct cdev led_cdev;

static dev_t dev_num;

static char *gpio_name[]={"GPJ20","GPJ21","GPJ22","GPJ23"};

static struct class *led_class = NULL;

static struct device *led_device = NULL;

static char wbuf[1]={0};

 

 

static int led_open(struct inode *inode, struct file *f)

{

int i;

printk("led open\n");

for(i=0;i<4;i++)

{

gpio_direction_output(S5PV210_GPJ2(i),1);

}

return 0;

}

 

void led_up(char i)

{

char j;

int k = i-'0';

printk("GET[%c]\n",i);

printk("GET[%d]\n",k);

for(j=0;j<4;j++)

{

gpio_set_value(S5PV210_GPJ2(j),1);

}

gpio_set_value(S5PV210_GPJ2(k),0);

}

 

static ssize_t led_write(struct file *f, const char __user*buf,

size_t len, loff_t *t)

{

copy_from_user(wbuf,buf,len);

if(wbuf[0]=='0')

{

led_up(wbuf[0]);

}

 

if(wbuf[0]=='1')

{

led_up(wbuf[0]);

}

 

if(wbuf[0]=='2')

{

led_up(wbuf[0]);

}

 

if(wbuf[0]=='3')

{

led_up(wbuf[0]);

}

return 0;

}

 

/*3.定义文件操作集*/

static const struct file_operations fops={

.owner = THIS_MODULE,

.open = led_open,

.write = led_write,

};

 

 

static int __init led_init(void)

{

int ret;

int i;

/*2.申请设备号*/

ret = alloc_chrdev_region(&dev_num,0,1,"led");

if(ret<0)

{

printk("failed to register dev num\n");

goto failed_register;

}

 

/*4.字符设备的初始化*/

cdev_init(&led_cdev,&fops);

/*5.注册设备*/

ret = cdev_add(&led_cdev,dev_num,1);

if(ret<0)

{

printk("failed to add cdev\n");

goto failed_add;

}

 

/*6.申请IO口*/

for(i=0;i<4;i++)

{

ret = gpio_request(S5PV210_GPJ2(i),gpio_name[i]);

if(ret<0)

{

printk("failed to request GPIO\n");

goto failed_request_IO;

}

}

/*7.创建设备类*/

led_class = class_create(THIS_MODULE,"led_class");

if(led_class == NULL)

{

printk("failed to create class\n");

goto failed_create_class;

}

/*创建设备文件结点*/

led_device = device_create(led_class,NULL,dev_num,NULL,"led_dev");

if(led_device == NULL)

{

printk("failed to create device\n");

goto failed_create_device;

}

printk("init completed\n");

return 0;

 

failed_create_device:

class_destroy(led_class);

failed_create_class:

failed_request_IO:

while(i--)

{gpio_free(S5PV210_GPJ2(i));}

cdev_del(&led_cdev);

failed_add:

unregister_chrdev_region(dev_num,1);

failed_register:

return -1;

}

 

static void __exit led_exit(void)

{

device_destroy(led_class,dev_num);

class_destroy(led_class);


gpio_free(S5PV210_GPJ2(3));

gpio_free(S5PV210_GPJ2(2));

gpio_free(S5PV210_GPJ2(1));

gpio_free(S5PV210_GPJ2(0));

 

cdev_del(&led_cdev);

unregister_chrdev_region(dev_num,1);

printk("led uninstall!\n");

}

 

module_init(led_init);

module_exit(led_exit);

MODULE_LICENSE("GPL");


应用程序:

#include

#include

 

int main()

{

char buf[1];

char i;

 

int fd = open("/dev/led_dev",O_WRONLY);

if(fd<0)

{

perror("failed to open");

return -1;

}

while(1)

{

for(i='0';i

{

buf[0]=i;

write(fd,buf,1);

sleep(1);

}

}

return 0;

}




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C8051F020的UART