⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tlc2543_ad_driver.c

📁 这个程序实现了s3c2410的GPIO口对TLC2543AD芯片的驱动。linux环境下用交叉编译环境编译之后
💻 C
字号:
#include <linux/config.h>//配置头文件
#include <linux/kernel.h>//内核头文件
#include <linux/sched.h>
#include <linux/timer.h>//时钟头文件
#include <linux/init.h>//用户定义模块初始化函数名需引用的头文件
#include <linux/module.h>//模块加载的头文件
#include <asm/hardware.h>
#include <asm/delay.h>
#include <asm/uaccess.h>

#define CMD_CS_LOW		0
#define CMD_CS_HIGH		1

#define ADC_CS_LOW	write_gpio_bit(GPIO_F0,0)
#define ADC_CS_HIGH	write_gpio_bit(GPIO_F0,1)
#define ADC_SCK_LOW	write_gpio_bit(GPIO_F2,0)
#define ADC_SCK_HIGH	write_gpio_bit(GPIO_F2,1)
#define ADC_DIN_LOW	write_gpio_bit(GPIO_G3,0)
#define ADC_DIN_HIGH	write_gpio_bit(GPIO_G3,1)

//定义设备号
#define DEV_MAJOR	97
//定义设备名
#define DEV_NAME	"ADC" 

//驱动程序实现的方法
ssize_t ADC_open (struct inode * inode ,struct file * file);
ssize_t ADC_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops);
ssize_t ADC_read (struct file * file ,char * buf, size_t count);
ssize_t ADC_release (struct inode  * inode ,struct file * file);
ssize_t ADC_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, long data);

// -------------------------------------------------
struct file_operations ADC_ctl_ops ={
	
	owner:		THIS_MODULE,
	open:		ADC_open,
	write:		ADC_write,
	read:		ADC_read,
	release:	ADC_release,
	ioctl:		ADC_ioctl,
};

// ------------------- READ ------------------------
ssize_t ADC_read (struct file * file ,char * buf, size_t count)
{
	unsigned int Chel_Bits=0x24;	//选用芯片的十一路通道中的通道2,输出数据的长度为8位
	int i,j;	
	unsigned char buf_tmp=0;

	//使能TLC2543
	ADC_CS_HIGH;
	udelay(10); //CS的转换时间最少为10us
	ADC_CS_LOW;

	for(j=0;j<count;j++){
		for(i=7;i>=0;i--){
			if(Chel_Bits & (0x01<<i) ){			//write Din pin
				write_gpio_bit(GPIO_G3,1);
			}else{
				write_gpio_bit(GPIO_G3,0);
			}
			//保证CS 的建立时间t(cs)最小为1.425us和Dout从高阻态到第一位有效数据的时间tPZH/tPZL为0.7us
			udelay(10); //其实不一定要,因为后面还有延时。
			if( read_gpio_bit(GPIO_G11) ){	//read the Din pin
				//printk("%x\n",Read_Bit);
				buf_tmp |= 0x01<<i;
			}else{
				//printk("%x\n",Read_Bit);
				buf_tmp &= ~(0x01<<i);
			}
			ADC_SCK_LOW;//可以不要
			udelay(10);	//保证Din 的建立时间 最少为100ns和Din的电平转换过度时间最大为10us
			ADC_SCK_HIGH;
			udelay(40);			//时钟高电平持续时间最少150ns
			ADC_SCK_LOW;
			udelay(20);			//时钟低电平持续时间最少150ns,
		}
	udelay(20);	//补偿第一字节最好一个数据位的时钟低电平时间,同时保证CS的保持时间
	count=j+1;
	}
	copy_to_user((void *)buf,(void *)&buf_tmp,sizeof(buf_tmp));
	ADC_DIN_HIGH;		//恢复初始状态,SCK在这之前为低,所以这里不用恢复
	ADC_CS_HIGH;		//关闭AD
		
	return count;
}

// ------------------- WRITE -----------------------
ssize_t ADC_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops)
{
	return count;
}
	
// ------------------- OPEN ------------------------
ssize_t ADC_open (struct inode * inode ,struct file * file)
{
	MOD_INC_USE_COUNT;

	return 0;
}	

// ------------------- IOCTL -----------------------
ssize_t ADC_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, long data)
{
	switch (cmd)
        {
		case CMD_CS_HIGH : { 
				write_gpio_bit(GPIO_F0,1);break; 
		}
		case CMD_CS_LOW  : { 
				write_gpio_bit(GPIO_F0,0);break; 
				}
                default :{printk ("lcd control : no cmd run  [ --kernel-- ]\n"); return (-EINVAL);}
        }
	return 0;
	
}

// ------------------- RELEASE/CLOSE ---------------
ssize_t ADC_release (struct inode  * inode ,struct file * file)
{
	MOD_DEC_USE_COUNT;

	return 0;
}

// ------------------- INIT ------------------------
static devfs_handle_t devfs_handle;

static int ADC_CTL_init(void)
{
	int ret = -ENODEV;
	
	printk("--------------------------------------------------------------------------------\n");
	//初始化S3C2410与TLC2543相连的管脚
	set_gpio_ctrl (GPIO_F0  | GPIO_PULLUP_EN | GPIO_MODE_OUT);	//EINT0-------CS
	set_gpio_ctrl (GPIO_F2  | GPIO_PULLUP_EN | GPIO_MODE_OUT);	//EINT2-------SCK
	set_gpio_ctrl (GPIO_G3  | GPIO_PULLUP_EN | GPIO_MODE_OUT);	//ENIT11------Din
	set_gpio_ctrl (GPIO_G11 | GPIO_PULLUP_EN | GPIO_MODE_IN);	//EINT19------Dout

	//初始引脚的电平	
	write_gpio_bit(GPIO_F0,1);		//CS为高电平
	write_gpio_bit(GPIO_F2,0);		//SCK为低电平
	write_gpio_bit(GPIO_G3,1);		//Din为高电平
	//这里Dout为输入管脚,不用初始化电平
	ret = register_chrdev(DEV_MAJOR, DEV_NAME, &ADC_ctl_ops);

	if( ret < 0 ){
		printk (" S3C2410: init_module failed with %d\n", ret);	
		return ret;
	}else{
		printk("S3C2410 gpio_led_driver register success!!! \n");
	}

	devfs_handle = devfs_register(NULL, DEV_NAME, DEVFS_FL_DEFAULT,
				DEV_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR, &ADC_ctl_ops, NULL);	

	return ret;
}

//---------------驱动程序初始化函数----------------------
static int __init TLC2543_ADC_init(void) 
{
	int ret = -ENODEV;
     	
    	ret = ADC_CTL_init();
    	if (ret)
      		return ret;
    	return 0;
}

//---------------驱动程序清楚函数------------------------
static void __exit TLC2543_ADC_Clr(void)
{ 
	unregister_chrdev (DEV_MAJOR, DEV_NAME );	
}

//----------------------------------------------------------
module_init(TLC2543_ADC_init);
module_exit(TLC2543_ADC_Clr);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -