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

控制IO端口 s3c2410_gpio_setpin()的使用

发布时间:2020-08-26 发布时间:
|
本文基于FL2440 ARM开发板

Linux内核版本 2.6.28.7

arm-linux-gcc 3.4.1

  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6. #include /*设置中断方式*/  
  7. #include   
  8. #include   
  9. #include   
  10. #include   
  11. #include   
  12. //设备名  
  13. #define IO_DEVICE_NAME "my_io"  
  14. //主设备号  
  15. #define IO_DEVICE_MAJOR 240  
  16. //次设备号  
  17. #define IO_DEVICE_SECONDARY 32  
  18. //返回一个数x的第y位  
  19. #define MYBIT(x,y) ((x>>y)%2)  
  20. #ifndef _LINUX_IRQRETURN_H  
  21. #define _LINUX_IRQRETURN_H  
  22. typedef int irqreturn_t;  
  23. #define IRQ_EINT0   0  
  24. #define IRQ_EINT2   2  
  25. #define IRQ_EINT3   3  
  26. #define IRQ_EINT4   32  
  27. #define IRQ_NONE       (0)  
  28. #define IRQ_HANDLED       (1)  
  29. #define IRQ_RETVAL(x)      ((x) != 0)  
  30. #endif  
  31. /* 
  32.  * S3C2410 GPIO edge detection for IRQs: 
  33.  * IRQs are generated on Falling-Edge, Rising-Edge, both, low level or higg level. 
  34.  * This must be called *before* the corresponding IRQ is registered. 
  35.  */  
  36. #define EXT_LOWLEVEL        0  
  37. #define EXT_HIGHLEVEL       1  
  38. #define EXT_FALLING_EDGE    2  
  39. #define EXT_RISING_EDGE     4  
  40. #define EXT_BOTH_EDGES      6  
  41. static int flag_0,flag_2;//中断转换标志  
  42. static int cnt;  
  43. DECLARE_WAIT_QUEUE_HEAD(io_wait);//声明等待队列  
  44. void io_con_set();  
  45. static irqreturn_t io_interrupt_0(int irq,void * dev_id,struct pt_regs *regs)  
  46. {  
  47.     printk("**********the interrupt 0 works**********/n");  
  48.     if(flag_0==0)  
  49.     {  
  50.         cnt=(cnt+1)%2;  
  51.         flag_0=1;  
  52.         if(cnt==0)  
  53.         {  
  54.             printk("IN/n");  
  55.             s3c2410_gpio_setpin(S3C2410_GPB5,0);  
  56.             s3c2410_gpio_setpin(S3C2410_GPB6,1);  
  57.         }  
  58.         wake_up_interruptible(&io_wait);  
  59.     }  
  60.     return IRQ_HANDLED;  
  61. }  
  62. static irqreturn_t io_interrupt_2(int irq,void * dev_id,struct pt_regs *regs)  
  63. {  
  64.     printk("**********the interrupt 2 works**********/n");  
  65.     if(flag_2==0)  
  66.     {  
  67.         cnt=(cnt+1)%2;  
  68.         flag_2=1;  
  69.         if(cnt==0)  
  70.         {  
  71.             printk("OUT/n");  
  72.             s3c2410_gpio_setpin(S3C2410_GPB5,1);  
  73.             s3c2410_gpio_setpin(S3C2410_GPB6,0);  
  74.         }  
  75.         wake_up_interruptible(&io_wait);  
  76.     }  
  77.     return IRQ_HANDLED;  
  78. }  
  79. static int io_open(struct inode * inode,struct file * file)//打开设备函数  
  80. {  
  81.     int ret;  
  82.     set_irq_type(IRQ_EINT0,EXT_FALLING_EDGE);//设置中断0 触发方式  
  83.     set_irq_type(IRQ_EINT2,EXT_FALLING_EDGE);//设置中断2 触发方式  
  84.     // EXT_LOWLEVEL  
  85.     // EXT_HIGHLEVEL  
  86.     // EXT_FALLING_EDGE  
  87.     // EXT_RISING_EDGE  
  88.     // EXT_BOTH_EDGES  
  89.     disable_irq(IRQ_EINT0);  
  90.     disable_irq(IRQ_EINT2);  
  91.     enable_irq(IRQ_EINT0);  
  92.     enable_irq(IRQ_EINT2);  
  93.     ret=request_irq(IRQ_EINT0,io_interrupt_0,IRQF_SHARED,IO_DEVICE_NAME,1);//注册中断0  
  94.     if(ret<0)  
  95.     {  
  96.         printk("IRQ %d can not request/n",IRQ_EINT0);  
  97.         return ret;  
  98.     }  
  99.     ret=request_irq(IRQ_EINT2,io_interrupt_2,IRQF_SHARED,IO_DEVICE_NAME,1);//注册中断2  
  100.     if(ret<0)  
  101.     {  
  102.         printk("IRQ %d can not request/n",IRQ_EINT2);  
  103.         return ret;  
  104.     }  
  105.     printk("the device is opened/n");  
  106.     io_con_set();  
  107.     cnt=0;  
  108.     return 0;  
  109. }  
  110. void io_con_set()//IO端口控制寄存器初始化  
  111. {  
  112.      s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_EINT0);  
  113.      s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_EINT2);  
  114.      s3c2410_gpio_cfgpin(S3C2410_GPB5,S3C2410_GPB5_OUTP);  
  115.      s3c2410_gpio_cfgpin(S3C2410_GPB6,S3C2410_GPB6_OUTP);  
  116. }  
  117. static int io_close(struct inode * inode,struct file * file)//设备关闭函数  
  118. {  
  119.     free_irq(IRQ_EINT0,1);//释放中断  
  120.     free_irq(IRQ_EINT2,1);//释放中断  
  121.     printk("the device is closed/n");  
  122.     return 0;  
  123. }  
  124. static ssize_t io_read(struct file * filp,char  * buff,size_t count,loff_t  * f_ops)//读取IO端口  
  125. {  
  126.     wait_event_interruptible(io_wait,flag_0);  
  127.     wait_event_interruptible(io_wait,flag_0);  
  128.     flag_0=0;  
  129.     flag_2=0;  
  130.     //printk("the value is %d/n",io_data);  
  131.     copy_to_user(buff,(char *)&cnt,sizeof(cnt));  
  132. }  
  133. static struct file_operations io_device_fops =   
  134. {  
  135.     .owner=THIS_MODULE,  
  136.     .read=io_read,  
  137.     .open=io_open,  
  138.     .release=io_close,  
  139. };  
  140. static int __init io_init(void)//insmod加载驱动时执行  
  141. {  
  142.     int ret;  
  143.     ret=register_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME,&io_device_fops);  
  144.     if(ret<0)  
  145.     {  
  146.         printk("Fail to regist the device/n");  
  147.         return ret;  
  148.     }  
  149.     return 0;  
  150. }  
  151. static int __exit io_exit(void)//rmmod卸载驱动时执行  
  152. {  
  153.     unregister_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME);  
  154.     printk("the device has been unregisted/n");  
  155. }  
  156. module_init(io_init);  
  157. module_exit(io_exit);  
  158. MODULE_LICENSE("GPL");    
 

 

Makefile同上一篇的Makefile

 

 

obj-m := my_io.o

KERNELDIR ?= /arm/linux-2.6.28.7-2440

PWD := $(shell pwd)

default:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:

rm -f *.o *.ko *.order *.symvers

这次本人修改了下内核头文件的目录,将目录./arch/arm/include下asm文件夹复制到./include

将目录./arch/arm/mach-s3c2410/include下mach文件夹复制到./include下

驱动修改版

 

  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6. #include /*设置中断方式*/  
  7. #include   
  8. #include   
  9. #include   
  10. #include   
  11. #include   
  12. //设备名  
  13. #define IO_DEVICE_NAME "my_io"  
  14. //主设备号  
  15. #define IO_DEVICE_MAJOR 240  
  16. //次设备号  
  17. #define IO_DEVICE_SECONDARY 32  
  18. //返回一个数x的第y位  
  19. #define MYBIT(x,y) ((x>>y)%2)  
  20. #ifndef _LINUX_IRQRETURN_H  
  21. #define _LINUX_IRQRETURN_H  
  22. typedef int irqreturn_t;  
  23. #define IRQ_EINT0   0  
  24. #define IRQ_EINT2   2  
  25. #define IRQ_EINT3   3  
  26. #define IRQ_EINT4   32  
  27. #define IRQ_NONE       (0)  
  28. #define IRQ_HANDLED       (1)  
  29. #define IRQ_RETVAL(x)      ((x) != 0)  
  30. #endif  
  31. /* 
  32.  * S3C2410 GPIO edge detection for IRQs: 
  33.  * IRQs are generated on Falling-Edge, Rising-Edge, both, low level or higg level. 
  34.  * This must be called *before* the corresponding IRQ is registered. 
  35.  */  
  36. #define EXT_LOWLEVEL        0  
  37. #define EXT_HIGHLEVEL       1  
  38. #define EXT_FALLING_EDGE    2  
  39. #define EXT_RISING_EDGE     4  
  40. #define EXT_BOTH_EDGES      6  
  41. static int flag_0,flag_2;//中断转换标志  
  42. static int cnt;  
  43. DECLARE_WAIT_QUEUE_HEAD(io_wait);//声明等待队列  
  44. void io_con_set();  
  45. static irqreturn_t io_interrupt_0(int irq,void * dev_id,struct pt_regs *regs)  
  46. {  
  47.     if(flag_0==0)  
  48.     {  
  49.         printk("**********the interrupt 0 works**********/n");  
  50.         cnt=(cnt+1)%2;  
  51.         flag_0=1;  
  52.         if(cnt==0)  
  53.         {  
  54.             printk("IN/n");  
  55.             s3c2410_gpio_setpin(S3C2410_GPB5,0);  
  56.             s3c2410_gpio_setpin(S3C2410_GPB6,1);  
  57.         }  
  58.         wake_up_interruptible(&io_wait);  
  59.     }  
  60.     return IRQ_HANDLED;  
  61. }  
  62. static irqreturn_t io_interrupt_2(int irq,void * dev_id,struct pt_regs *regs)  
  63. {  
  64.     if(flag_2==0)  
  65.     {  
  66.         printk("**********the interrupt 2 works**********/n");  
  67.         cnt=(cnt+1)%2;  
  68.         flag_2=1;  
  69.         if(cnt==0)  
  70.         {  
  71.             printk("OUT/n");  
  72.             s3c2410_gpio_setpin(S3C2410_GPB5,1);  
  73.             s3c2410_gpio_setpin(S3C2410_GPB6,0);  
  74.         }  
  75.         wake_up_interruptible(&io_wait);  
  76.     }  
  77.     return IRQ_HANDLED;  
  78. }  
  79. static int io_open(struct inode * inode,struct file * file)//打开设备函数  
  80. {  
  81.     int ret;  
  82.     set_irq_type(IRQ_EINT0,EXT_FALLING_EDGE);//设置中断0 触发方式  
  83.     set_irq_type(IRQ_EINT2,EXT_FALLING_EDGE);//设置中断2 触发方式  
  84.     // EXT_LOWLEVEL  
  85.     // EXT_HIGHLEVEL  
  86.     // EXT_FALLING_EDGE  
  87.     // EXT_RISING_EDGE  
  88.     // EXT_BOTH_EDGES  
  89.     disable_irq(IRQ_EINT0);  
  90.     disable_irq(IRQ_EINT2);  
  91.     enable_irq(IRQ_EINT0);  
  92.     enable_irq(IRQ_EINT2);  
  93.     ret=request_irq(IRQ_EINT0,io_interrupt_0,IRQF_SHARED,IO_DEVICE_NAME,1);//注册中断0  
  94.     if(ret<0)  
  95.     {  
  96.         printk("IRQ %d can not request/n",IRQ_EINT0);  
  97.         return ret;  
  98.     }  
  99.     ret=request_irq(IRQ_EINT2,io_interrupt_2,IRQF_SHARED,IO_DEVICE_NAME,1);//注册中断2  
  100.     if(ret<0)  
  101.     {  
  102.         printk("IRQ %d can not request/n",IRQ_EINT2);  
  103.         return ret;  
  104.     }  
  105.     printk("the device is opened/n");  
  106.     io_con_set();  
  107.     cnt=0;  
  108.     return 0;  
  109. }  
  110. void io_con_set()//IO端口控制寄存器初始化  
  111. {  
  112.      s3c2410_gpio_cfgpin(S3C2410_GPF0,S3C2410_GPF0_EINT0);  
  113.      s3c2410_gpio_cfgpin(S3C2410_GPF2,S3C2410_GPF2_EINT2);  
  114.      s3c2410_gpio_cfgpin(S3C2410_GPB5,S3C2410_GPB5_OUTP);  
  115.      s3c2410_gpio_cfgpin(S3C2410_GPB6,S3C2410_GPB6_OUTP);  
  116. }  
  117. static int io_close(struct inode * inode,struct file * file)//设备关闭函数  
  118. {  
  119.     free_irq(IRQ_EINT0,1);//释放中断  
  120.     free_irq(IRQ_EINT2,1);//释放中断  
  121.     printk("the device is closed/n");  
  122.     return 0;  
  123. }  
  124. static ssize_t io_read(struct file * filp,char  * buff,size_t count,loff_t  * f_ops)//读取IO端口  
  125. {  
  126.     wait_event_interruptible(io_wait,flag_0&flag_2);  
  127.     flag_0=0;  
  128.     flag_2=0;  
  129.     //printk("the value is %d/n",io_data);  
  130.     copy_to_user(buff,(char *)&cnt,sizeof(cnt));  
  131. }  
  132. static struct file_operations io_device_fops =   
  133. {  
  134.     .owner=THIS_MODULE,  
  135.     .read=io_read,  
  136.     .open=io_open,  
  137.     .release=io_close,  
  138. };  
  139. static int __init io_init(void)//insmod加载驱动时执行  
  140. {  
  141.     int ret;  
  142.     ret=register_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME,&io_device_fops);  
  143.     if(ret<0)  
  144.     {  
  145.         printk("Fail to regist the device/n");  
  146.         return ret;  
  147.     }  
  148.     return 0;  
  149. }  
  150. static int __exit io_exit(void)//rmmod卸载驱动时执行  
  151. {  
  152.     unregister_chrdev(IO_DEVICE_MAJOR,IO_DEVICE_NAME);  
  153.     printk("the device has been unregisted/n");  
  154. }  
  155. module_init(io_init);  
  156. module_exit(io_exit);  
  157. MODULE_LICENSE("GPL");    
 

 

这个驱动实际上是通过红外传感器检测电平变化,来实现人数的统计,改进后能够实现正确的通过中断先后来识别方向,还排除了单一中断的

抖动干扰。

关键字:控制IO端口  s3c2410

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

热门文章 更多
51单片机CO2检测显示程序解析