zoukankan      html  css  js  c++  java
  • IMX6输出可控PWM

    驱动部分

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/moduleparam.h>
    #include <linux/errno.h>
    #include <linux/miscdevice.h>
    #include <linux/types.h>
    #include <linux/io.h>
    #include <linux/pwm.h>
    #include <linux/fs.h>  
    
    /************硬件相关***************/
    #include <mach/iomux-mx6q.h>
    
    #define PWM_FREQENCY 1
    #define DEV_NAME    "mypwm"
    #define PWM_DEBUG 1   
    /*pwm for this my_pwm*/
    struct pwm_device *pwm = NULL;
    
    static int my_pwm_open(struct inode *inode, struct file *filp)
    {
    
       if(pwm != NULL)
    	   return -EBUSY;
    
       /**
    	* my_pwm正好挂载在I.MX6的pwm4上,所以这里申请3号(从零开始算)PWM
    	*/
       pwm = pwm_request(3, "my_pwm");
       if ( pwm == NULL ) {
    	   printk(KERN_ALERT"my_pwm open error.
    ");
       }
    	#ifdef PWM_DEBUG
    	printk(KERN_ALERT"my_pwm opened
    ");
    	#endif
       return 0;
    }
    
    static int my_pwm_release(struct inode *inode, struct file *filp)
    {
       pwm_disable(pwm);			   // 关闭pwm
       pwm_free(pwm);				   // 释放pwm
       pwm = NULL;
    	#ifdef PWM_DEBUG
    		printk(KERN_ALERT"my_pwm closed
    ");
        #endif
       return 0;
    }
    
    static long my_pwm_ioctl(struct file *filp,
    					   unsigned int cmd, unsigned long arg)
    {
       if(pwm == NULL)
    	   return -EINVAL;
    
       if(arg < 0)
    	   return -EINVAL;
    
       switch (cmd) {
       case PWM_FREQENCY:
    	   if(arg==0)
    	   	{
    		   pwm_disable(pwm);
    		   #ifdef PWM_DEBUG
    		   	printk(KERN_ALERT"my_pwm off
    ");
    		   #endif
    	   	}
    	   else
    	   {
    		   pwm_config(pwm, 1000000000/arg/2, 1000000000/arg);
    		   pwm_enable(pwm);
    		   #ifdef PWM_DEBUG
    		   	printk(KERN_ALERT"my_pwm on
    ");
    		   #endif
    	   }
    	   break;
       default:
    	   break;
       }
    
       return 0;
    }
    
    static struct file_operations my_pwm_fops = {
       .owner			   = THIS_MODULE,
       .unlocked_ioctl	   = my_pwm_ioctl,
       .open			   = my_pwm_open,
       .release 		   = my_pwm_release,
    };
    
    static struct miscdevice my_pwm_miscdev =
    {
    	.minor	= MISC_DYNAMIC_MINOR,
    	.name	= DEV_NAME,
    	.fops	= &my_pwm_fops,
    };
    
    static int __init my_pwm_init(void)
    {
      	 //printk(KERN_ALERT"check my_pwm init.
    ");
       	misc_register(&my_pwm_miscdev);//misc杂项设备是主设备号为10的驱动设备,自动创建节点
    	mxc_iomux_v3_setup_pad(MX6Q_PAD_SD1_CMD__PWM4_PWMO);
    	#ifdef PWM_DEBUG
    		printk(KERN_ALERT"my_pwm init
    ");
    	#endif
       	return 0;
    }
    
    static void __exit my_pwm_exit(void)
    {
      misc_deregister(&my_pwm_miscdev);
      #ifdef PWM_DEBUG
    		printk(KERN_ALERT"my_pwm removed
    ");
      #endif
    }
    
    module_init(my_pwm_init);
    module_exit(my_pwm_exit);
    
    MODULE_DESCRIPTION("pwm_my_pwm driver");
    MODULE_LICENSE("GPL");
    

      测试程序

    #include<stdio.h>
    #include<stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>
    #include <poll.h>
    #include <signal.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    #define PWM_SET_FREQ 1
    #define PWM_STOP     0
    
    
    int fd;
    int main(int argc, char **argv)//dev state freq
    {
    	char* filename;
    	long int freq;
    
    	filename=argv[1];
    	if (argc != 4)
    	    {
    		  printf("parm limited!
    ");
    		  return 0;
    		}
    	printf("open %s 
    ",filename);
    	fd=open(filename,O_RDWR);
    	if(fd<0)
    	{
    		printf("can't open
    ");
    		return 0;
    	}
    	if(!strcmp("on",argv[2]))
    	{
    		printf("PWM ON!
    ");
    		freq=atol(argv[3]);
    		ioctl(fd,PWM_SET_FREQ,freq);
    		printf("PWM FREQ set:%d Hz 
    ",freq);
    	}
    	else if(!strcmp("off",argv[2]))
    	{
    		ioctl(fd,PWM_STOP);
    		printf("PWM stop!
    ");
    	}
    	else
    		printf("error:param wrong!
    ");
    		while(1)
    		{
    			sleep(1000);
    		}
    	close(fd);
    	return 0;
    }
    

      

    转载请注明出处:http://www.cnblogs.com/tla001/ 一起学习,一起进步
  • 相关阅读:
    hdu 2050 折线分割平面 递推
    hdu 2044 一只小蜜蜂 斐波那契数列 递推
    hdu 2018 母牛的故事 递推
    hdu 2084 数塔 dp 动态规划
    Linux 常用协议结构体及详解
    【ArcEngine入门与提高】Element(元素)、Annotation(注记)旋转
    AO总结10:MapControl控件
    esriControlsMousePointer 控制鼠标指针
    图解VS2010打包全过程(转)
    ArcEngine中打开各种数据源(WorkSpace)的连接(转)
  • 原文地址:https://www.cnblogs.com/tla001/p/5541524.html
Copyright © 2011-2022 走看看