一、可以使用的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  --->
static int led_gpios[] = {
EXYNOS4_GPL2(), EXYNOS4_GPK(),    /* Led IO 2个 */
EXYNOS4_GPD0(),              /* BUZZER IO 1个 */ EXYNOS4_GPX1(), EXYNOS4_GPX1(),EXYNOS4_GPX1(),EXYNOS4_GPX1(),    /* 矩阵健盘8个 */
EXYNOS4_GPX3(),EXYNOS4_GPX2(),EXYNOS4_GPX2(),EXYNOS4_GPX3(), EXYNOS4212_GPJ1(),EXYNOS4_GPL0(),EXYNOS4_GPL0(),EXYNOS4212_GPJ1(),      /* 摄像头14个 */
EXYNOS4212_GPJ1(),EXYNOS4212_GPJ1(),EXYNOS4212_GPJ0(),EXYNOS4212_GPJ0(),
EXYNOS4212_GPJ0(),EXYNOS4212_GPJ0(),EXYNOS4212_GPJ0(),EXYNOS4212_GPJ0(),
   EXYNOS4212_GPJ0(),EXYNOS4212_GPJ0(), EXYNOS4_GPK3(),EXYNOS4_GPK3(),EXYNOS4_GPK3(),EXYNOS4_GPK3(),      /* WIFI 7个 */
EXYNOS4_GPK3(),EXYNOS4_GPK3(),EXYNOS4_GPC1(),
};

led_gpios数组

二、设计思路

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

下面是我的源码:

#include <linux/init.h>
#include <linux/module.h> /* */
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/fs.h> #include <linux/gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio.h>
#include <mach/gpio-exynos4.h> #include <asm/uaccess.h>
#include <linux/irq.h>
#include <linux/interrupt.h> #include <linux/time.h> #define DRIVER_NAME "ReadPwm"
#define DEVICE_NAME "read_pwm" MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("TOPEET"); #define GPIO_CHG_FLT EXYNOS4_GPX1(0) static int up_flag = ;
struct platform_device *dev_int;
/* led: KP_COL0, VDD50_EN */
/* BUZZER: MOTOR_PWM */
/* keyboards: CHG_FLT, HOOK_DET, CHG_UOK, XEINT14_BAK, GM_INT1,
6260_GPIO1, CHG_COK, XEINT29/KP_ROW13/ALV_DBG25 */
/* camera: CAM_MCLK, CAM2M_RST, CAM2M_PWDN, CAM_D5, CAM_D7, CAM_D6,
CAM_D4, CAM_D3, CAM_D2, CAM_D1, CAM_PCLK, CAM_D0, CAM_VSYNC, CAM_HREF */
/* WIFI: WIFI_D3, WIFI_CMD, WIFI_D1, WIFI_CLK, WIFI_D0, WIFI_D2,GPC1_1 */
struct timeval tv_begin, tv_end;
static int interval = ;
struct semaphore sem; static irqreturn_t qint8_interrupt(int irq, void *dev_id)
{
int ret;
ret = gpio_get_value(GPIO_CHG_FLT);
if(ret == ) {
do_gettimeofday(&tv_end);
if(tv_end.tv_usec - tv_begin.tv_usec > ) {
down(&sem);
interval = tv_end.tv_usec - tv_begin.tv_usec;
up(&sem);
}
// if(printk_ratelimit()) {
// printk("tv_end.usec:%d - tv_begin.usec:%d =\n%d\n", tv_end.usec,
// tv_begin.usec, tv_end.usec - tv_begin.usec);
// }
} else if(ret == ) {
do_gettimeofday(&tv_begin);
}
return IRQ_HANDLED;
} static int read_pwm_open(struct inode *inode, struct file *file)
{
printk(KERN_EMERG "read pwm open\n");
return ;
} static int read_pwm_release(struct inode *inode, struct file *file)
{
printk(KERN_EMERG "read pwm release\n");
return ;
} static ssize_t read_pwm_read(struct file *filp, char __user *buff, size_t size, loff_t *ppos)
{
unsigned int key_value = ;
char temp[];
int ret;
// printk(KERN_EMERG "sizeof(key_value) is %d\n", sizeof(key_value));
if(size != sizeof(temp)) {
return -;
}
down(&sem);
key_value = interval;
up(&sem); temp[] = ((key_value)&0xff);
temp[] = ((key_value>>)&0xff); ret = copy_to_user(buff, temp, sizeof(temp)); return ret;
} static struct file_operations read_pwm_ops = {
.owner = THIS_MODULE,
.open = read_pwm_open,
.release = read_pwm_release,
.read = read_pwm_read,
}; static struct miscdevice read_pwm_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &read_pwm_ops,
}; static int read_pwm_probe(struct platform_device *pdv)
{
int ret;
printk(KERN_EMERG "\tread pwm start initialized\n");
/* set up gpio */
// ret = gpio_request(GPIO_CHG_FLT, "GPX1_0");
// if(ret < 0) {
// printk(KERN_EMERG "request GPIO %d for read pwm failed\n", GPIO_CHG_FLT);
// return ret;
// } // s3c_gpio_cfgpin(GPIO_CHG_FLT, S3C_GPIO_INPUT);
// s3c_gpio_setpull(GPIO_CHG_FLT, S3C_GPIO_PULL_NONE);
ret = request_irq(IRQ_EINT(), qint8_interrupt, IRQ_TYPE_EDGE_BOTH, "my_eint8", pdv);
if(ret < ) {
printk(KERN_EMERG "request irq 8 failed.\n");
return ;
}
up_flag = ;
dev_int = pdv;
sema_init(&sem, );
/* register */
ret = misc_register(&read_pwm_dev);
if(ret < ) {
gpio_free(GPIO_CHG_FLT);
misc_deregister(&read_pwm_dev);
return -EINVAL;
} return ;
} static int read_pwm_remove(struct platform_device *pdv)
{
printk(KERN_EMERG "\tread pwm remove\n"); // gpio_free(GPIO_CHG_FLT);
free_irq(IRQ_EINT(), pdv);
misc_deregister(&read_pwm_dev);
return ;
} static void read_pwm_shutdown(struct platform_device *pdv)
{ } static int read_pwm_suspend(struct platform_device *pdv, pm_message_t pmt)
{
return ;
} static int read_pwm_resume(struct platform_device *pdv)
{
return ;
} struct platform_driver read_pwm_driver = {
.probe = read_pwm_probe,
.remove = read_pwm_remove,
.shutdown = read_pwm_shutdown,
.suspend = read_pwm_suspend,
.resume = read_pwm_resume,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
}
}; static int read_pwm_init(void)
{
int DriverState; printk(KERN_EMERG "Read pwm init enter!\n");
DriverState = platform_driver_register(&read_pwm_driver); printk(KERN_EMERG "\tDriverState is %d\n", DriverState);
return ;
} static void read_pwm_exit(void)
{
printk(KERN_EMERG "Read pwm exit!\n");
platform_driver_unregister(&read_pwm_driver);
} module_init(read_pwm_init);
module_exit(read_pwm_exit);

read_pwm.c

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

app源码:

#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h> #define READ_PWM "/dev/read_pwm" int main()
{
long value = ;
int fd;
char buff[];
int ret; fd = open(READ_PWM, O_RDWR|O_NDELAY);
if(fd < ) {
perror("open");
} while(ret = read(fd, buff, sizeof(buff)) >= ) {
printf("value is %d\n", buff[]|buff[]<<);
usleep();
}
printf("sizeof(value) is %d\n", sizeof(buff));
printf("read return is %d\n", ret);
return ;
}

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. JS 创建动态表格练习

    创建动态表格 1.1 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...

  2. Vue混入:全局混入

    一 项目结构 二 main.js import Vue from "vue"; import App from "./App.vue"; Vue.config. ...

  3. 【FICO系列】SAP FICO模块-固定资产月结的注意点

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[FICO系列]SAP FICO模块-固定资产月 ...

  4. 排序算法四:快速排序(Quicksort)

    快速排序(Quicksort),因其排序之快而得名,虽然Ta的平均时间复杂度也是O(nlgn),但是从后续仿真结果看,TA要比归并排序和堆排序都要快. 快速排序也用到了分治思想. (一)算法实现 pr ...

  5. Ubuntu下面怎么连接drcom校园网?(重庆大学实测可行)

    之前因为ubuntu下面不能连drcom接校园头疼了半天,我们学校自带的客户端成功运行了,但是还是不能上网.\ 于是我百度了半天,搜了一堆教程...因为技术太渣好多教程里面不会修改参数,然后都不能成功 ...

  6. mysql高级知识

    2 数据约束 2.1什么数据约束 ​ 对用户操作表的数据进行约束 2.2 默认值 作用: 当用户对使用默认值的字段不插入值的时候,就使用默认值. 注意: 1)对默认值字段插入null是可以的. 2)对 ...

  7. [Codeforces600E] Lomsat gelral(树上启发式合并)

    [Codeforces600E] Lomsat gelral(树上启发式合并) 题面 给出一棵N个点的树,求其所有子树内出现次数最多的颜色编号和.如果多种颜色出现次数相同,那么编号都要算进答案 N≤1 ...

  8. 小B的询问(题解)(莫队)

    小B的询问(题解)(莫队) Junlier良心莫队 题目 luoguP2709 小B的询问 code #include<bits/stdc++.h> #define lst long lo ...

  9. <转载>面试官,不要再问我三次握手和四次挥手

    版权声明:本文为CSDN博主「夏雪冬日」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csdn.net/hyg0811/a ...

  10. Codeforces - 1191B - Tokitsukaze and Mahjong - 模拟

    https://codeforces.com/contest/1191/problem/B 小心坎张听的情况. #include<bits/stdc++.h> using namespac ...