ds18b20的单总线协议就不叙述了,就是一种规定,哪种信号表示一,哪种信号表示零,整个过程需要按怎样的步骤来,数据手册上一般都会说明,怎样去读写,这些都是规定死的东西 ,下面是我按照正点原子的例子修改过来的
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/poll.h>
#define DQ_PIN 0
static struct class *cls;
int major;
volatile unsigned long *gpjcon;
volatile unsigned long *gpjdat;
volatile unsigned long *gpjup;
void DS18B20_IO_OUT(void)
{
*gpjcon &= ~(3<<DQ_PIN);
*gpjcon |= (1<<DQ_PIN);
}
void DS18B20_DQ_OUT(int val)
{
if(val)
*gpjdat |= (1<<(DQ_PIN/2));
else
*gpjdat &= ~(1<<(DQ_PIN/2));
}
void DS18B20_IO_IN(void)
{
*gpjcon &= ~(3<<DQ_PIN);
}
int DS18B20_DQ_IN(void)
{
int ret;
if((*gpjdat)&(1<<(DQ_PIN/2)))
ret = 1;
else
ret = 0;
return ret;
}
void DS18B20_Rst(void)
{
DS18B20_IO_OUT();
DS18B20_DQ_OUT(0);
udelay(750);
DS18B20_DQ_OUT(1);
udelay(15);
}
unsigned char DS18B20_Check(void)
{
unsigned char retry=0;
DS18B20_IO_IN();
while (DS18B20_DQ_IN()&&retry<200)
{
retry++;
udelay(1);
};
if(retry>=200)return 1;
else retry=0;
while (!DS18B20_DQ_IN()&&retry<240)
{
retry++;
udelay(1);
};
if(retry>=240)return 1;
return 0;
}
unsigned char DS18B20_Read_Bit(void)
{
unsigned char data;
DS18B20_IO_OUT();
DS18B20_DQ_OUT(0);
udelay(2);
DS18B20_DQ_OUT(1);
DS18B20_IO_IN();
udelay(12);
if(DS18B20_DQ_IN())data=1;
else data=0;
udelay(50);
return data;
}
unsigned char DS18B20_Read_Byte(void)
{
unsigned char i,j,dat;
dat=0;
for (i=1;i<=8;i++)
{
j=DS18B20_Read_Bit();
dat=(j<<7)|(dat>>1);
}
return dat;
}
void DS18B20_Write_Byte(unsigned char dat)
{
unsigned char j;
unsigned char testb;
DS18B20_IO_OUT();
for (j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if (testb)
{
DS18B20_DQ_OUT(0); // Write 1
udelay(2);
DS18B20_DQ_OUT(1);
udelay(60);
}
else
{
DS18B20_DQ_OUT(0); // Write 0
udelay(60);
DS18B20_DQ_OUT(1);
udelay(2);
}
}
}
void DS18B20_Start(void)
{
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc); // skip rom
DS18B20_Write_Byte(0x44); // convert
}
unsigned char DS18B20_Init(void)
{
DS18B20_IO_OUT();
DS18B20_DQ_OUT(1);
DS18B20_Rst();
return DS18B20_Check();
}
static int ds18b20_open(struct inode *inode, struct file *filp)
{
if(DS18B20_Init()){
printk("ds18b20 init failed\n\r");
return -1;
}
printk("open ds18b20 successful\n");
return 0;
}
static ssize_t ds18b20_read(struct file *filp, char __user * buf, size_t count, loff_t * f_pos)
{
unsigned long err;
unsigned char result[2] = { 0x00, 0x00 };
DS18B20_Start (); // ds1820 start convert
DS18B20_Rst();
DS18B20_Check();
DS18B20_Write_Byte(0xcc); // skip rom
DS18B20_Write_Byte(0xbe); // convert
result[0]=DS18B20_Read_Byte(); // LSB
result[1]=DS18B20_Read_Byte(); // MSB
err = copy_to_user(buf, &result, sizeof(result));
return err ? -EFAULT : min(sizeof(result), count);
}
static struct file_operations ds18b20_dev_fops = {
.owner = THIS_MODULE,
.open = ds18b20_open,
.read = ds18b20_read,
};
static int __init ds18b20_dev_init(void)
{
major = register_chrdev(0, "ds18b20", &ds18b20_dev_fops);
cls = class_create(THIS_MODULE, "ds18b20");
class_device_create(cls, NULL, MKDEV(major, 0), NULL, "ds18b20");
gpjcon = (volatile unsigned long *)ioremap(0x560000d0, 12);
gpjdat = gpjcon + 1;
gpjup = gpjdat + 1;
return 0;
}
static void __exit ds18b20_dev_exit(void)
{
class_device_destroy(cls, MKDEV(major, 0));
class_destroy(cls);
unregister_chrdev(major, "ds18b20");
iounmap(gpjcon);
}
module_init(ds18b20_dev_init);
module_exit(ds18b20_dev_exit);
MODULE_LICENSE("Dual BSD/GPL");