ds18b20的时序图如下:
复位时序:
读写时序:
以下是程序代码:
#include <linux/module.h> #include <linux/init.h> #include <linux/miscdevice.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/fs.h> #include <linux/slab.h> #include <asm/irq.h> #include <linux/random.h> #include <linux/uaccess.h> #include <linux/device.h> #include <linux/delay.h> #include <mach/gpio.h> #include <linux/mutex.h> #define GPH3_0CON 0xE0200C60 #define GPH3_0DAT 0xE0200C64 #define GPH3_0PUD 0xE0200C68 unsigned int *gpio_config; unsigned char *gpio_data; unsigned int *gpio_pud; static struct class *fog_class; //´´½¨Àà static struct class_device *fog_class_devs; //´´½¨Àà¶ÔÓ¦µÄÉ豸 int major; struct mutex res_mutex; void Ds18b20_Pin_Init(void) { unsigned int pin_val; gpio_request(S5PV210_GPH3(0),"my_ds1802"); gpio_config = ioremap(GPH3_0CON,4); gpio_data = ioremap(GPH3_0DAT,1); gpio_pud = ioremap(GPH3_0PUD,2); pin_val = readl(gpio_pud); pin_val &=~(0x0003); pin_val |= 0x2; writel(pin_val,gpio_pud); pin_val = readl(gpio_data); writel(pin_val|0x1,gpio_data); } void DS18B20_OUT( unsigned char value) { if( value == 1) { gpio_direction_output( S5PV210_GPH3(0), 1); } else { gpio_direction_output( S5PV210_GPH3(0), 0); } } unsigned char DS18B20_IN( void ) { unsigned int pin_val; gpio_direction_input( S5PV210_GPH3(0)); pin_val = readl(gpio_data); return pin_val&0x1; } static void Init_DS18B20(void) { gpio_direction_output( S5PV210_GPH3(0), 1); udelay(200); gpio_direction_output( S5PV210_GPH3(0), 0); udelay(600); gpio_direction_output( S5PV210_GPH3(0), 1); udelay(480); } static void WriteCode(unsigned char dat) { unsigned char temp,i; for(i=0;i<8;i++) { temp = dat&0x01; gpio_direction_output( S5PV210_GPH3(0), 1); udelay(2); gpio_direction_output( S5PV210_GPH3(0), 0); if(temp == 0x01) { udelay(2); gpio_direction_output( S5PV210_GPH3(0), 1); udelay(100); }else{ udelay(100); gpio_direction_output( S5PV210_GPH3(0), 1); udelay(3); } dat = dat>>1; } } static void Reset_DS18B20( void ) { gpio_direction_output( S5PV210_GPH3(0), 0); udelay(500); gpio_direction_output( S5PV210_GPH3(0), 1); udelay(480); } static unsigned int ReadData(void) { unsigned int rec,data,i; data = 0; for(i=0;i<16;i++) { gpio_direction_output( S5PV210_GPH3(0), 0); udelay(5); udelay(3); rec = DS18B20_IN(); udelay(20); if(rec){ data |= 0x8000; }else{ data &= 0x7fff; } if(i<15) data >>=1; udelay(20); gpio_direction_output( S5PV210_GPH3(0), 1); udelay(5); } return (data); } int ds18b20_open(struct inode *node, struct file *filp) { return 0; } static int ds18b20_read(struct file * file, char * buffer, size_t count, loff_t *ppos) { int tem; int ds_value; mutex_lock_interruptible(&res_mutex); Ds18b20_Pin_Init(); Init_DS18B20(); WriteCode(0xcc); WriteCode(0x44); gpio_direction_input( S5PV210_GPH3(0)); udelay(100); tem = DS18B20_IN(); if(tem) { gpio_direction_output( S5PV210_GPH3(0), 1); Reset_DS18B20(); WriteCode(0xcc); WriteCode(0xbe); ds_value = ReadData(); }else{ udelay(50); ds_value = 0xaaaa; } mutex_unlock(&res_mutex); copy_to_user(buffer, &ds_value, 4); return sizeof ds_value; } static struct file_operations ds18b20_fops = { .open = ds18b20_open, .read = ds18b20_read, }; static int Ds18b20_init(void) { major = register_chrdev( 0,"ds18b20_drv", &ds18b20_fops ); fog_class = class_create(THIS_MODULE,"ds18b20_class"); fog_class_devs = device_create(fog_class,NULL,MKDEV(major,0),NULL,"my_ds1802"); mutex_init(&res_mutex); printk("install module successed "); return 0; } void Ds18b20_exit(void) { unregister_chrdev( major, "ds18b20_drv" ); device_unregister(fog_class_devs); class_destroy(fog_class); } module_init(Ds18b20_init); module_exit(Ds18b20_exit); MODULE_LICENSE("GPL");