mini2440 ADC可调电阻驱动程序开发源代码(杂项设备(2)


/*字符设备的相关操作实现*/
static struct file_operations adc_fops =
{
 .owner    = THIS_MODULE,
 .open    = adc_open,
 .read    = adc_read,   
 .release  = adc_release,
};

/*misc设备结构体实现*/
static struct miscdevice adc_miscdev =
{
 .minor  = MISC_DYNAMIC_MINOR, /*次设备号,定义在 miscdevice.h中,为255*/
 .name    = DEVICE_NAME,        /* 设备名称*/
 .fops    = &adc_fops,          /*对ADC设备文件操作*/
};


static int __init adc_init(void)
{
    int ret; 
 /*从平台时钟队列中获取ADC的时钟,这里为什么要取得这个时钟,因为ADC的转换频率跟时钟有关。
 系统的一些时钟定义在arch/arm/plat-s3c24xx /s3c2410-clock.c中*/
    adc_clk = clk_get(NULL, "adc");
 if (!adc_clk)
 {
  /*错误处理*/
  printk(KERN_ERR "failed to find adc clock source\n");
  return -ENOENT;
 }

/*时钟获取后要使能后才可以使用,clk_enable定义在arch/arm/plat-s3c/clock.c中*/
 clk_enable(adc_clk);

/*将ADC的IO端口占用的这段 IO空间映射到内存的虚拟地址,ioremap定义在io.h中。
 注意:IO空间要映射后才能使用,以后对虚拟地址的操作就是对IO空间的操作, S3C2410_PA_ADC
 是ADC控制器的基地址,定义在mach-s3c2410/include/mach/map.h中,0x20是虚拟地址长度大小*/
  adc_base = ioremap(S3C2410_PA_ADC, 0x20);
 if (adc_base == NULL)
 {

printk(KERN_ERR "Failed to remap register block\n"); /*错误处理*/
    ret = -EINVAL;
    goto err_noclk;
 }
 
 /*把看ADC注册成为misc设备,misc_register定义在miscdevice.h中adc_miscdev结构体定义
 及内部接口函数在第②步中讲,MISC_DYNAMIC_MINOR是次设备号,定义在miscdevice.h中*/
    ret = misc_register(&adc_miscdev);
 if (ret)
 {
  /*错误处理*/
  printk(KERN_ERR "cannot register miscdev on minor=%d (%d)\n",
  MISC_DYNAMIC_MINOR, ret);
  goto err_nomap;
 }

printk(DEVICE_NAME " initialized!\n");

return 0;
 //以下是上面错误处理的跳转点
err_noclk:
  clk_disable(adc_clk);
    clk_put(adc_clk);
 
err_nomap:
    iounmap(adc_base);
 
    return ret;
}
 
static void __exit adc_exit(void)
{
    free_irq(IRQ_ADC, 1);/*释放中断*/
    iounmap(adc_base);/*释放虚拟地址映射空间*/
 
 if (adc_clk)/*屏蔽和销毁时钟*/
 {
    clk_disable(adc_clk);   
    clk_put(adc_clk);
    adc_clk = NULL;
 }
 
  misc_deregister(&adc_miscdev);/*注销misc设备*/
}
 
/*导出信号量ADC_LOCK在触摸屏驱动中使用,因为触摸屏驱动和ADC驱动公用
93.相关的寄存器,为了不产生资源竞态,就用信号量来保证资源的互斥访问*/
//EXPORT_SYMBOL(ADC_LOCK);
module_init(adc_init);
module_exit(adc_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("youshaohui 2012.10.31 in ruanjianyuan");
MODULE_DESCRIPTION("s3c2440 ADC Driver");

//=======================================================================

应用程序测试代码开发如下:

//=======================================================================


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MYADC "/dev/adc_driver"

void Delay_MS( unsigned int time)  //50 ns
{
 unsigned int i,j;
 
 for ( i=0; i<time; i++)
 {
    for(j=0;j<30000;j++)
    {
   
    }
  }
}
//adc可调电阻
int main(void)
{
 int fd;
 int i=0;
 unsigned int value = -1;
 char buf[30]={0};

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/51525ba340b2bd84b0d118db5a4761af.html