一、可以使用的GPIO管脚

去掉占用调用的GPIO驱动,包括leds,buzzer,camera ov5640,WIFI mt6620 ,Keyboards

  • VIDEO_OV5640– Device Drivers

    • – Multimedia support(MEDIA_SUPPORT [=y])
    • – Video capture adapters(VIDEO_CAPTURE_DRIVERS [=y])(去掉)
  • MTK_COMBO_CHIP_MT6620– Device Drivers
    • – MediaTek Connectivity Combo Chip Config
    • – MediaTek Connectivity Combo Chip Support (MTK_COMBO [=y])(去掉)
    • – Select Chip (<choice> [=y])
  • Enable LEDS config– Device Drivers
    • – Character devices
    • – Enable LEDS config
  • Enable BUZZER config
    • – Device Drivers
    • – Character devices
    • – Enable BUZZER config
  • Enable Keyboards
    • Device Drivers  --->
    • Input device support  --->
    • Keyboards  --->
  1. static int led_gpios[] = {
  2. EXYNOS4_GPL2(), EXYNOS4_GPK(),    /* Led IO 2个 */
  3. EXYNOS4_GPD0(),              /* BUZZER IO 1个 */
  4.  
  5. EXYNOS4_GPX1(), EXYNOS4_GPX1(),EXYNOS4_GPX1(),EXYNOS4_GPX1(),    /* 矩阵健盘8个 */
  6. EXYNOS4_GPX3(),EXYNOS4_GPX2(),EXYNOS4_GPX2(),EXYNOS4_GPX3(),
  7.  
  8. EXYNOS4212_GPJ1(),EXYNOS4_GPL0(),EXYNOS4_GPL0(),EXYNOS4212_GPJ1(),      /* 摄像头14个 */
  9. EXYNOS4212_GPJ1(),EXYNOS4212_GPJ1(),EXYNOS4212_GPJ0(),EXYNOS4212_GPJ0(),
  10. EXYNOS4212_GPJ0(),EXYNOS4212_GPJ0(),EXYNOS4212_GPJ0(),EXYNOS4212_GPJ0(),
  11.    EXYNOS4212_GPJ0(),EXYNOS4212_GPJ0(),
  12.  
  13. EXYNOS4_GPK3(),EXYNOS4_GPK3(),EXYNOS4_GPK3(),EXYNOS4_GPK3(),      /* WIFI 7个 */
  14. EXYNOS4_GPK3(),EXYNOS4_GPK3(),EXYNOS4_GPC1(),
  15. };

led_gpios数组

二、设计思路

  • 通过外部中断来处理电路上升沿和下降沿的跳变处理
  • 通过读取IO管脚,来判断是上升沿触发还是下降沿触发
  • 使用do_gettimeofday来获取时间戳,从而计算高电平时间

下面是我的源码:

  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3.  
  4. /* */
  5. #include <linux/platform_device.h>
  6. #include <linux/miscdevice.h>
  7. #include <linux/fs.h>
  8.  
  9. #include <linux/gpio.h>
  10. #include <plat/gpio-cfg.h>
  11. #include <mach/gpio.h>
  12. #include <mach/gpio-exynos4.h>
  13.  
  14. #include <asm/uaccess.h>
  15. #include <linux/irq.h>
  16. #include <linux/interrupt.h>
  17.  
  18. #include <linux/time.h>
  19.  
  20. #define DRIVER_NAME "ReadPwm"
  21. #define DEVICE_NAME "read_pwm"
  22.  
  23. MODULE_LICENSE("Dual BSD/GPL");
  24. MODULE_AUTHOR("TOPEET");
  25.  
  26. #define GPIO_CHG_FLT EXYNOS4_GPX1(0)
  27.  
  28. static int up_flag = ;
  29. struct platform_device *dev_int;
  30. /* led: KP_COL0, VDD50_EN */
  31. /* BUZZER: MOTOR_PWM */
  32. /* keyboards: CHG_FLT, HOOK_DET, CHG_UOK, XEINT14_BAK, GM_INT1,
  33. 6260_GPIO1, CHG_COK, XEINT29/KP_ROW13/ALV_DBG25 */
  34. /* camera: CAM_MCLK, CAM2M_RST, CAM2M_PWDN, CAM_D5, CAM_D7, CAM_D6,
  35. CAM_D4, CAM_D3, CAM_D2, CAM_D1, CAM_PCLK, CAM_D0, CAM_VSYNC, CAM_HREF */
  36. /* WIFI: WIFI_D3, WIFI_CMD, WIFI_D1, WIFI_CLK, WIFI_D0, WIFI_D2,GPC1_1 */
  37. struct timeval tv_begin, tv_end;
  38. static int interval = ;
  39. struct semaphore sem;
  40.  
  41. static irqreturn_t qint8_interrupt(int irq, void *dev_id)
  42. {
  43. int ret;
  44. ret = gpio_get_value(GPIO_CHG_FLT);
  45. if(ret == ) {
  46. do_gettimeofday(&tv_end);
  47. if(tv_end.tv_usec - tv_begin.tv_usec > ) {
  48. down(&sem);
  49. interval = tv_end.tv_usec - tv_begin.tv_usec;
  50. up(&sem);
  51. }
  52. // if(printk_ratelimit()) {
  53. // printk("tv_end.usec:%d - tv_begin.usec:%d =\n%d\n", tv_end.usec,
  54. // tv_begin.usec, tv_end.usec - tv_begin.usec);
  55. // }
  56. } else if(ret == ) {
  57. do_gettimeofday(&tv_begin);
  58. }
  59. return IRQ_HANDLED;
  60. }
  61.  
  62. static int read_pwm_open(struct inode *inode, struct file *file)
  63. {
  64. printk(KERN_EMERG "read pwm open\n");
  65. return ;
  66. }
  67.  
  68. static int read_pwm_release(struct inode *inode, struct file *file)
  69. {
  70. printk(KERN_EMERG "read pwm release\n");
  71. return ;
  72. }
  73.  
  74. static ssize_t read_pwm_read(struct file *filp, char __user *buff, size_t size, loff_t *ppos)
  75. {
  76. unsigned int key_value = ;
  77. char temp[];
  78. int ret;
  79. // printk(KERN_EMERG "sizeof(key_value) is %d\n", sizeof(key_value));
  80. if(size != sizeof(temp)) {
  81. return -;
  82. }
  83. down(&sem);
  84. key_value = interval;
  85. up(&sem);
  86.  
  87. temp[] = ((key_value)&0xff);
  88. temp[] = ((key_value>>)&0xff);
  89.  
  90. ret = copy_to_user(buff, temp, sizeof(temp));
  91.  
  92. return ret;
  93. }
  94.  
  95. static struct file_operations read_pwm_ops = {
  96. .owner = THIS_MODULE,
  97. .open = read_pwm_open,
  98. .release = read_pwm_release,
  99. .read = read_pwm_read,
  100. };
  101.  
  102. static struct miscdevice read_pwm_dev = {
  103. .minor = MISC_DYNAMIC_MINOR,
  104. .name = DEVICE_NAME,
  105. .fops = &read_pwm_ops,
  106. };
  107.  
  108. static int read_pwm_probe(struct platform_device *pdv)
  109. {
  110. int ret;
  111. printk(KERN_EMERG "\tread pwm start initialized\n");
  112. /* set up gpio */
  113. // ret = gpio_request(GPIO_CHG_FLT, "GPX1_0");
  114. // if(ret < 0) {
  115. // printk(KERN_EMERG "request GPIO %d for read pwm failed\n", GPIO_CHG_FLT);
  116. // return ret;
  117. // }
  118.  
  119. // s3c_gpio_cfgpin(GPIO_CHG_FLT, S3C_GPIO_INPUT);
  120. // s3c_gpio_setpull(GPIO_CHG_FLT, S3C_GPIO_PULL_NONE);
  121. ret = request_irq(IRQ_EINT(), qint8_interrupt, IRQ_TYPE_EDGE_BOTH, "my_eint8", pdv);
  122. if(ret < ) {
  123. printk(KERN_EMERG "request irq 8 failed.\n");
  124. return ;
  125. }
  126. up_flag = ;
  127. dev_int = pdv;
  128. sema_init(&sem, );
  129. /* register */
  130. ret = misc_register(&read_pwm_dev);
  131. if(ret < ) {
  132. gpio_free(GPIO_CHG_FLT);
  133. misc_deregister(&read_pwm_dev);
  134. return -EINVAL;
  135. }
  136.  
  137. return ;
  138. }
  139.  
  140. static int read_pwm_remove(struct platform_device *pdv)
  141. {
  142. printk(KERN_EMERG "\tread pwm remove\n");
  143.  
  144. // gpio_free(GPIO_CHG_FLT);
  145. free_irq(IRQ_EINT(), pdv);
  146. misc_deregister(&read_pwm_dev);
  147. return ;
  148. }
  149.  
  150. static void read_pwm_shutdown(struct platform_device *pdv)
  151. {
  152.  
  153. }
  154.  
  155. static int read_pwm_suspend(struct platform_device *pdv, pm_message_t pmt)
  156. {
  157. return ;
  158. }
  159.  
  160. static int read_pwm_resume(struct platform_device *pdv)
  161. {
  162. return ;
  163. }
  164.  
  165. struct platform_driver read_pwm_driver = {
  166. .probe = read_pwm_probe,
  167. .remove = read_pwm_remove,
  168. .shutdown = read_pwm_shutdown,
  169. .suspend = read_pwm_suspend,
  170. .resume = read_pwm_resume,
  171. .driver = {
  172. .name = DRIVER_NAME,
  173. .owner = THIS_MODULE,
  174. }
  175. };
  176.  
  177. static int read_pwm_init(void)
  178. {
  179. int DriverState;
  180.  
  181. printk(KERN_EMERG "Read pwm init enter!\n");
  182. DriverState = platform_driver_register(&read_pwm_driver);
  183.  
  184. printk(KERN_EMERG "\tDriverState is %d\n", DriverState);
  185. return ;
  186. }
  187.  
  188. static void read_pwm_exit(void)
  189. {
  190. printk(KERN_EMERG "Read pwm exit!\n");
  191. platform_driver_unregister(&read_pwm_driver);
  192. }
  193.  
  194. module_init(read_pwm_init);
  195. module_exit(read_pwm_exit);

read_pwm.c

还有一个问题,卸载模块后再装载就会报错,不知道为什么。

app源码:

  1. #include <sys/types.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <sys/stat.h>
  6.  
  7. #define READ_PWM "/dev/read_pwm"
  8.  
  9. int main()
  10. {
  11. long value = ;
  12. int fd;
  13. char buff[];
  14. int ret;
  15.  
  16. fd = open(READ_PWM, O_RDWR|O_NDELAY);
  17. if(fd < ) {
  18. perror("open");
  19. }
  20.  
  21. while(ret = read(fd, buff, sizeof(buff)) >= ) {
  22. printf("value is %d\n", buff[]|buff[]<<);
  23. usleep();
  24. }
  25. printf("sizeof(value) is %d\n", sizeof(buff));
  26. printf("read return is %d\n", ret);
  27. return ;
  28. }

read_pwm_app

4412 gpio读取pwm的更多相关文章

  1. 4412 GPIO初始化

    一.GPIO的初始化 • 在内核源码目录下使用命令“ls drivers/gpio/*.o”,可以看到“gpioexynos4”被编译进了内核.通过搜索*.o文件,可以知道内核编译内哪些文件.针对的看 ...

  2. 4412 4路pwm输出

    一.4412 xpwmTOUT1 这是4412的GPD0_1路,itop中被使用为LCD的背光电路的pwm功能.因此如果使用教程中的代码,同样操作GPD0_1是行不通的. 会出现错误,所以需要解除在内 ...

  3. 4412 GPIO读 和 ioremap控制GPIO寄存器

    一.配置GPIO读 在视频14的基础上做 1.利用拨码开关来实现GPIO输入 所以AP_SLEEP对应GPC0_3,然后在drivers/gpio/gpio-exynos4.c中对应EXYNOS4_G ...

  4. 使用linux内核hrtimer高精度定时器实现GPIO口模拟PWM,【原创】

    关键词:Android  linux hrtimer 蜂鸣器  等待队列 信号量 字符设备 平台信息:内核:linux3.4.39 系统:android/android5.1平台:S5P4418  作 ...

  5. 树莓派GPIO开发(二)RGB模块-PWM调节

    配置环境 系统:Raspbian11(官方64位) 设备:树莓派CM4 一.PWM简单介绍 全称:Pulse-width modulation,脉冲宽度调制,简单的数模转换方法 1.基本原理 脉冲宽度 ...

  6. nrf51 官方PWM库

    地址:https://github.com/NordicSemiconductor/nrf51-pwm-library nrf_pwm_init函数 初始化PWM参数 设置输出pwm的gpio pin ...

  7. STM32 - GPIO

    买了一个STM32F4的开发板,想把上面的东西重新学一下 快速过: 一.GPIO控制 void GPIO_DeInit(GPIO_TypeDef* GPIOx); //把某一个IO口恢复到默认值 /* ...

  8. wiringPi库的pwm配置及使用说明

    本文介绍树莓派(raspberry pi)在linux c 环境下的硬件pwm配置及使用方法. 1. 下载安装wiringPi 此步骤建议参考官网指南,wiringPi提供了对树莓派的硬件IO访问,包 ...

  9. RK3399/NanoPC-T4开发板使用/sys/class/gpio操作外接GPIO设备-【申嵌视频-RK3399篇】

    实验2:RK3399/NanoPC-T4开发板使用/sys/class/gpio操作外接GPIO设备,比如外接一个LED模块,通过GPIO1_A0管脚 1 介绍   LED模块   Matrix-LE ...

随机推荐

  1. Spring Boot 读取外部的配置文件

    Spring Boot 程序会按优先级从下面这些路径来加载application.properties 或者 application.yml 配置文件 jar包同级目录下的/config目录jar包同 ...

  2. php面向对象三大特性

    1.封装: 目的:使类更加安全 步骤:1.成员变量变成private(私有的)2.设置方法/调用方法3.在方法中增加限制 <?php class shao { private $aa;//必须是 ...

  3. java Json 技术记录

    1.Json-lib json-lib最开始的也是应用最广泛的json解析工具,json-lib 不好的地方确实是依赖于很多第三方包,包括commons-beanutils.jar,commons-c ...

  4. PHP防采集方法代码

    <?php /** * FileName:test.php * Summary: 防采集 */ $HTTP_REFERER = $_SERVER["HTTP_REFERER" ...

  5. 排序算法三:堆排序(Heapsort)

    堆排序(Heapsort)是一种利用数据结构中的堆进行排序的算法,分为构建初始堆,减小堆的元素个数,调整堆共3步. (一)算法实现 protected void sort(int[] toSort) ...

  6. LOJ 2183 / SDOI2015 序列统计 (DP+矩阵快速幂)

    题面 传送门 分析 考虑容斥原理,用总的方案数-不含质数的方案数 设\(dp1[i][j]\)表示前i个数,和取模p为j的方案数, \(dp2[i][j]\)表示前i个数,和取模p为j的方案数,且所有 ...

  7. 11、numpy——字符串函数

    NumPy 字符串函数 以下函数用于对 dtype 为 numpy.string_ 或 numpy.unicode_ 的数组执行向量化字符串操作. 它们基于 Python 内置库中的标准字符串函数. ...

  8. Codeforces - 1176E - Cover it! - bfs

    https://codeforc.es/contest/1176/problem/E 久了不写bfs了.一开始用dfs写,的确用dfs是很有问题的,一些奇怪的情况就会导致多染一些色. 注意无向图的边要 ...

  9. vue 移动端列表筛选功能实现

    最近兴趣所致,打算使用vant搭建一个webapp,由于需要使用列表筛选,没有找到合适组件,于是写了一个简单的功能,权当记录. 效果如下:        HTML: <div class=&qu ...

  10. 廖雪峰Python电子书总结

    函数 1.注意:函数的默认参数必须指向不可变对象 未修改前: def add_end(L=[]): L.append('END') return L 存在的问题:如果连续调用多次,会出现多个 'END ...