ADC驅動例項(簡單)

2021-05-26 15:17:33 字數 3992 閱讀 1889

adc驅動(僅一路輸入)

/********s3c2410-adc.h********/

#ifndef _s3c2410_adc_h_

#define _s3c2410_adc_h_

#define adc_write(ch, prescale) ((ch)<<16|(prescale)) //將頻道和預分頻合併為乙個資料,這樣可以作為乙個引數傳入

#define adc_write_getch(data) (((data)>>16)&0x7) //得到轉換器是哪一路的,使用時要<<3

#define adc_write_getpre(data) ((data)&0xff)  //得到預分頻的值

#endif /* _s3c2410_adc_h_ */

/*************************s3c2410-adc.c****************************/

#include

#include

#include

#include

#include

#include

#include

#include

#include /* printk() */

#include /* kmalloc() */

#include /* everything... */

#include /* error codes */

#include /* size_t */

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "s3c2410-adc.h"

#include

#define device_name  "adc"

#define adcraw_minor 0

#define adc_input(x) ((x)<<3)

#define prscvl(x)   ((x)<<6)

static void *adctsc;

static void *adccon;

static void *adcdata0;

static void *clkcon;

static int adc_major = 252;

typedef struct adc_dev;

static adc_dev adcdev;

/**中斷處理函式

*/static irqreturn_t adcdone_int_handler(int irq,void *dev_id,struct pt_regs *regs)

/**對裝置進行寫操作,buffer一定是使用者空間的

*/static ssize_t s3c2410_adc_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)

copy_from_user(&data, buffer, count); //從使用者空間拷貝資料到核心空間

adcdev.channel=adc_write_getch(data); //得到哪一路ad轉換器

adcdev.prescale=adc_write_getpre(data); //得到預分頻值

//printk(kern_info"set adc channel=%d, prescale=0x%x\n", adcdev.channel, adcdev.prescale);

return count;}/*

*對裝置進行讀操作,buffer一定是使用者空間的

*/static ssize_t s3c2410_adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)

/**開啟裝置

*/static int s3c2410_adc_open(struct inode *inode, struct file *filp)

init_mutex(&adcdev.lock);   //初始化乙個互斥的訊號量,並設定為1

init_waitqueue_head(&(adcdev.wait));//初始化等待佇列

adcdev.channel=0;

adcdev.prescale=0xff;

printk(kern_info"adc opened\n");

return 0;}/*

*關閉裝置

*/static int s3c2410_adc_release(struct inode *inode, struct file *filp)

/**初始化並新增結構提struct cdev到系統之中

*/static void adc_setup_cdev( struct cdev *dev, int minor,

struct file_operations *fops)

static struct cdev adcdevs;

/**定義乙個file_operations結構體,來實現對裝置的具體操作的功能

*/static struct file_operations adc_remap_ops = ;

/**初始化裝置驅動模組,主要完成對字元裝置結構體的初始化和新增到系統中,並得到乙個裝置的裝置號

*/static int  adc_init(void)

if (result < 0)

if (adc_major == 0)                         

adc_major = result;//如果靜態分配失敗。把動態非配的裝置號給裝置驅動程式

adc_setup_cdev(&adcdevs, 0, &adc_remap_ops);//初始化和新增結構體struct cdev到系統之中

printk(kern_info"adc device installed, with major %d\n", adc_major);

return 0;}/*

*解除安裝驅動模組

*/static void adc_cleanup(void)

module_init(adc_init);//初始化裝置驅動程式的入口

module_exit(adc_cleanup);//解除安裝裝置驅動程式的入口

module_license("dual bsd/gpl"); //模組應該指定**所使用的許可證

/******************main-adc.c*****************/

#include

#include

#include

#include

#include

#include

#include

#include "s3c2410-adc.h"

#define adc_dev  "/dev/adc"

static int adc_fd = -1;

static int init_addevice(void)

}static int getadresult(int channel)

int main(void)

close(adc_fd);//關閉裝置

return 0;

}//備註:此驅動程式使用了等待佇列,訊號量,中斷註冊。另外要特別留意write函式被實現為從使用者空間傳入數模轉換通道號(頻道)和分頻的值(預分頻),read函式則傳出轉換好的資料。對於預分頻傳入和讀取,本驅動程式並未使用到,當多路轉換時,這個值則要充分利用,並且需要一種多路轉換的實現方法了。

全志 ADC驅動

adc 驅動 1 include 2 include 3 include 4 include 5 include 6 include 7 include 8 include 9 include 10 include 11 include 12 include 13 include 14 includ...

Linux驅動修煉之道 ADC驅動

對於s3c2440 來說,實現a d 轉換比較簡單,主要應用的是adc 控制暫存器adccon 和adc 轉換資料暫存器adcdat0 暫存器adcdat0 的低10 位用於儲存a d 轉換後的資料。暫存器adccon 的第15 位用於標識a d 轉換是否結束。第14 位用於使能是否進行預分頻,而第...

Linux驅動修煉之道 ADC驅動

對於s3c2440 來說,實現a d 轉換比較簡單,主要應用的是adc 控制暫存器adccon 和adc 轉換資料暫存器adcdat0 暫存器adcdat0 的低10 位用於儲存a d 轉換後的資料。暫存器adccon 的第15 位用於標識a d 轉換是否結束。第14 位用於使能是否進行預分頻,而第...