历史上的今天
返回首页

历史上的今天

今天是:2024年12月30日(星期一)

正在发生

2021年12月30日 | 4412 gpio读取pwm

2021-12-30 来源:eefocus

一、可以使用的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 ( [=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  ---> 

led_gpios数组

static int led_gpios[] = {

    EXYNOS4_GPL2(0), EXYNOS4_GPK(1),    /* Led IO 2个 */

    EXYNOS4_GPD0(0),              /* BUZZER IO 1个 */


    EXYNOS4_GPX1(0), EXYNOS4_GPX1(3),EXYNOS4_GPX1(5),EXYNOS4_GPX1(6),    /* 矩阵健盘8个 */

    EXYNOS4_GPX3(0),EXYNOS4_GPX2(6),EXYNOS4_GPX2(7),EXYNOS4_GPX3(5),


    EXYNOS4212_GPJ1(3),EXYNOS4_GPL0(1),EXYNOS4_GPL0(3),EXYNOS4212_GPJ1(0),      /* 摄像头14个 */

    EXYNOS4212_GPJ1(2),EXYNOS4212_GPJ1(1),EXYNOS4212_GPJ0(7),EXYNOS4212_GPJ0(6),

    EXYNOS4212_GPJ0(5),EXYNOS4212_GPJ0(4),EXYNOS4212_GPJ0(0),EXYNOS4212_GPJ0(3),

   EXYNOS4212_GPJ0(1),EXYNOS4212_GPJ0(2),


    EXYNOS4_GPK3(6),EXYNOS4_GPK3(1),EXYNOS4_GPK3(4),EXYNOS4_GPK3(0),      /* WIFI 7个 */

    EXYNOS4_GPK3(3),EXYNOS4_GPK3(5),EXYNOS4_GPC1(1),

};


二、设计思路

  • 通过外部中断来处理电路上升沿和下降沿的跳变处理

  • 通过读取IO管脚,来判断是上升沿触发还是下降沿触发

  • 使用do_gettimeofday来获取时间戳,从而计算高电平时间

下面是我的源码:

read_pwm.c

#include

#include


/* */

#include

#include

#include


#include

#include

#include

#include


#include

#include

#include


#include


#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 = 0;

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 = 0;

struct semaphore sem;


static irqreturn_t qint8_interrupt(int irq, void *dev_id)

{

    int ret;

    ret = gpio_get_value(GPIO_CHG_FLT);

    if(ret == 0) {

        do_gettimeofday(&tv_end);

        if(tv_end.tv_usec - tv_begin.tv_usec > 0) {

            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%dn", tv_end.usec,

        //         tv_begin.usec, tv_end.usec - tv_begin.usec);

        // }

    } else if(ret == 1) {

        do_gettimeofday(&tv_begin);

    }

    return IRQ_HANDLED;

}


static int read_pwm_open(struct inode *inode, struct file *file)

{

    printk(KERN_EMERG "read pwm openn");

    return 0;

}


static int read_pwm_release(struct inode *inode, struct file *file)

{

    printk(KERN_EMERG "read pwm releasen");

    return 0;

}


static ssize_t read_pwm_read(struct file *filp, char __user *buff, size_t size, loff_t *ppos)

{

    unsigned int key_value = 0;

    char temp[2];

    int ret;

    // printk(KERN_EMERG "sizeof(key_value) is %dn", sizeof(key_value));

    if(size != sizeof(temp)) {

        return -1;

    }

    down(&sem);

    key_value = interval;

    up(&sem);


    temp[0] = ((key_value)&0xff);

    temp[1] = ((key_value>>8)&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 initializedn");

    /* set up gpio */

    // ret = gpio_request(GPIO_CHG_FLT, "GPX1_0");

    // if(ret < 0) {

    //     printk(KERN_EMERG "request GPIO %d for read pwm failedn", 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(8), qint8_interrupt, IRQ_TYPE_EDGE_BOTH, "my_eint8", pdv);

    if(ret < 0) {

        printk(KERN_EMERG "request irq 8 failed.n");

        return 0;

    }

    up_flag = 1;

    dev_int = pdv;

    sema_init(&sem, 1);

    /* register */

    ret = misc_register(&read_pwm_dev);

    if(ret < 0) {

        gpio_free(GPIO_CHG_FLT);

        misc_deregister(&read_pwm_dev);

        return -EINVAL;

    }


    return 0;

}


static int read_pwm_remove(struct platform_device *pdv)

{

    printk(KERN_EMERG "tread pwm removen");


    // gpio_free(GPIO_CHG_FLT);

    free_irq(IRQ_EINT(8), pdv);

    misc_deregister(&read_pwm_dev);

    return 0;

}


static void read_pwm_shutdown(struct platform_device *pdv)

{


}


static int read_pwm_suspend(struct platform_device *pdv, pm_message_t pmt)

{

    return 0;

}


static int read_pwm_resume(struct platform_device *pdv)

{

    return 0;

}


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 %dn", DriverState);

    return 0;

}


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);


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

app源码:

read_pwm_app

#include

#include

#include

#include

#include



#define READ_PWM "/dev/read_pwm"


int main()

{

    long value = 0;

    int fd;

    char buff[2];

    int ret;


    fd = open(READ_PWM, O_RDWR|O_NDELAY);

    if(fd < 0) {

        perror("open");

    }


    while(ret = read(fd, buff, sizeof(buff)) >= 0) {

        printf("value is %dn", buff[0]|buff[1]<<8);

        usleep(100000);

    }

    printf("sizeof(value) is %dn", sizeof(buff));

    printf("read return is %dn", ret);

    return 0;

}


推荐阅读

史海拾趣

酷宅(Coolkit)公司的发展小趣事

酷宅科技在智能家居市场的发展中,选择了电子电工和照明类市场作为切入点。这个市场具有巨大的智能化需求,但生产厂家众多,垄断程度低,利润率也相对较低。酷宅凭借其在物联网技术方面的优势,迅速满足了这一市场的迫切需求,并获得了巨大的出货量。随着市场的不断扩大,酷宅科技又进一步进入小家电市场,瞄准了加湿器、香薰机等长尾品类,继续扩大其市场份额。

Goodwork Semiconductor ( GW )公司的发展小趣事
选择知名品牌和高质量的产品,以确保产品的性能和稳定性。
安谱隆(Ampleon)公司的发展小趣事

在独立发展后,安谱隆不断推出创新产品,巩固其在射频市场的地位。2015年12月,安谱隆推出了基于0.5μm工艺、额定功率为10至200W的GaN on SiC射频功率晶体管。这一产品的推出不仅展示了安谱隆在射频技术方面的领先实力,也为其在移动通信、广播电视等领域的应用提供了强有力的支持。

Control Sciences Inc公司的发展小趣事

为了确保产品质量的稳定和可靠,Control Sciences Inc建立了一套完善的质量管理体系。公司从原材料采购、生产过程到产品出厂,都实行了严格的质量控制。同时,公司还引入了先进的质量检测设备和方法,确保每一台产品都符合客户的要求。这一举措使得Control Sciences Inc的产品在市场上赢得了良好的声誉。

C.K Magma公司的发展小趣事

C.K Magma公司最初由一群热衷于电子技术的工程师创立。他们通过深入研究,成功开发出一种新型半导体材料,这种材料在性能和稳定性上均优于当时市场上的同类产品。这一技术突破为公司赢得了业界的关注,并吸引了第一批投资。随着资金的注入,C.K Magma公司得以扩大研发团队,进一步巩固了其在半导体领域的技术领先地位。

HiRel Connectors Inc公司的发展小趣事
对于独立供电的摄像头,检查电源适配器是否工作正常,输出电压和电流是否符合要求。

问答坊 | AI 解惑

再议Linux与WinCE

Linux是单体内核,即将图形、驱动及文件系统等功能全在操作系统内核中实现,运行在内核状态和同一地址空间,其优点是减少了进程间通信和状态切换的系统开销,获得较高的运行效率;缺点是内核比较庞大! WinCE是微内核,即在内核中实现基本功能, ...…

查看全部问答>

关于液晶显示的问题?

大侠们:            我们用了一个122*32的液晶显 用在跷跷板小车上,用来显示里程 速度等!现在面临的问题是,关于液晶的编程,不会编,用C语言来编。大家有没好的例子 或者什么建议!!!希望大虾们 施 ...…

查看全部问答>

一种基于DDS技术的通信信号的调制方法与设计

一种基于DDS技术的通信信号的调制方法与设计.pdf 论文…

查看全部问答>

瞬态过压问题的本源

关于瞬态过压的保护问题,这里给大家推荐看看瞬态过压的本源,也好让大家设计保护电路。…

查看全部问答>

跳频技术 (FHSS) 及直接序列 (DSSS) 展频技术

2.4G 遥控设备的优势 2.4G的优势就来自于它的带宽。所以下面又引出了个新的概念扩频(spread Specturm)。好了回到刚才的比喻,我们需要在两个城市间快递一份包裹(就是我们的遥控指令)如果走50条车道的公路你只能守法的走其中一条,中途不能变 ...…

查看全部问答>

为什么我的封装放在二层板里会出现这样的情况

为什么我的封装放在二层板里会出现这样的情况,请高手指点不知是否是软件设置上有问题?…

查看全部问答>

关于ATmega8l的计数器问题

请问一下,在ATmega8中,当我的计数器2工作在快速PWM模式后,当计数器2和OCR2匹配时,是只控制OCF2(匹配中断控制位)还是控制OC2(匹配输出引脚),还是两者都控制啊,谢谢啦~~~…

查看全部问答>

如何采集uart格式数据?

大家好,我现在有一个输出格式为uart的图像设备,我要获得它输出的图像数据,请教应该用什么方式?…

查看全部问答>

请问要选择什么入门书, 要实践类的

   如题,我对linux内核有一些了解也有编写小型操作系统的经验,想学习arm嵌入式,请问下选择什么书入门好,我希望要那些实践类的不是那种理论类的, 谢谢…

查看全部问答>

07电子设计大赛获奖论文

本帖最后由 paulhyde 于 2014-9-15 03:59 编辑 07电子设计大赛获奖论文 [ 本帖最后由 laboy 于 2010-8-14 18:22 编辑 ]  …

查看全部问答>