开发环境:
主机:Ubuntu12.04
开发板:RT5350
Openwrt:Openwrt15.05
下图是我们温度传感器的接入引脚,3.3V 供电,io 口接 P07的 GP0( GPIO0 的简称 )。
DS18B20 数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有 LTM8877,LTM8874 等等。主要根据应用场合的不同而改变其外观。封装后的 DS18B20 可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。
目前常用的微机与外设之间进行数据传输的串行总线主要有 I2C 总线、 SPI 总线和 SCI总线。其中 I2C 总线以同步串行 2 线方式进行通信(一条时钟线,一条数据线) ,SPI 总线则以同步串行 3 线方式进行通信(一条时钟线,一条数据输入线,一条数据输出线),而 SCI 总线是以异步方式进行通信(一条数据输入线,一条数据输出线) 。这些总线至少需要两条或两条以上的信号线。
1-wire , 即 单 线 总 线 , 又 叫 单 总 线 。 近 年 来 , 美 国 的 达 拉 斯 半 导 体 公 司(DALLASSEMICONDUCTOR) 推出了一项特有的单总线(1-Wire Bus)技术。该技术与上述总线不同,它采用单根信号线,既可传输时钟,又能传输数据,而且数据传输是双向的,因而这种单总线技术具有线路简单,硬件开销少,成本低廉,便于总线扩展和维护等优点。
(1) 先将数据线置高电平“ 1” 。
(2) 延时(该时间要求的不是很严格,但是尽可能的短一点)
(3) 数据线拉到低电平“ 0” 。
(4) 延时 750 微秒(该时间的时间范围可以从 480 到 960 微秒) 。
(5) 数据线拉到高电平“ 1” 。
(6) 延时等待(如果初始化成功则在 15 到 60 微秒时间之内产生一个由 DS18B20 所
返回的低电平“ 0” 。据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制) 。
(7) 若 CPU 读到了数据线上的低电平“ 0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要 480 微秒。
(8) 将数据线再次拉高到高电平“ 1”后结束。
(1) 数据线先置低电平“ 0” 。
(2) 延时确定的时间为 15 微秒。
(3) 按从低位到高位的顺序发送字节(一次只发送一位) 。
(4) 延时时间为 45 微秒。
(5) 将数据线拉到高电平。
(6) 重复上(1)到(6)的操作直到所有的字节全部发送完为止。
(7) 最后将数据线拉高。
(1)将数据线拉高“ 1” 。
(2)延时 2 微秒。
(3)将数据线拉低“ 0” 。
(4)延时 3 微秒。
(5)将数据线拉高“ 1” 。
(6)延时 5 微秒。
(7)读数据线的状态得到 1 个状态位,并进行数据处理。
(8)延时 60 微秒。
关于字符设备驱动程序的使用,我们可以参照点亮 led 灯的那个实验,这里只给出跟ds18b20 密切相关的驱动程序,详细的程序请查看我们的驱动文件!
//配置连接温度传感器的引脚#define DS18B20_L*GPIO21_0_DATA &= ~(1< < 0) //低电平#define DS18B20_H*GPIO21_0_DATA |= (1< < 0) //高电平#define DS18B20_OUT *GPIO21_0_DIR |= (1< < 0) //输出#define DS18B20_IN*GPIO21_0_DIR &= ~(1< < 0) //输入#define DS18B20_STA*GPIO21_0_DATA & 0x01//寄存器定义volatile unsigned long *GPIO21_0_DIR;volatile unsigned long *GPIO21_0_DATA;//初始化函数必要资源定义//用于初始化函数当中//device number;dev_t dev_num;//struct devstruct cdev ds18b20_cdev;//auto "mknode /dev/ds18b20 c dev_num minor_num"struct class *ds18b20_class = NULL;struct device *ds18b20_device = NULL;//复位ds18b20传感器static unsigned char ds18b20_reset(void){unsigned char ret = 0;unsigned char count = 0;DS18B20_OUT;DS18B20_H;udelay(100);DS18B20_L;udelay(600);DS18B20_H;udelay(45);DS18B20_IN;do{ret = DS18B20_STA;udelay(1);count++;}while(ret != 0 && count< 50);DS18B20_OUT;udelay(400);DS18B20_H;return ret;}//从ds18b20读取一个字节static unsigned char read_byte(void){unsigned char i,byte=0;DS18B20_OUT;DS18B20_H;udelay(100);for(i = 0; i< 8; i++){byte > >= 1;DS18B20_L;udelay(4);DS18B20_H;udelay(2);if(DS18B20_STA == 1)byte |= 0x80;udelay(10);}return byte;}//向ds18b20写入一个字节static unsigned char write_byte(unsigned char byte){unsigned char i;DS18B20_OUT;DS18B20_H;udelay(100);for(i = 0; i< 8; i++){DS18B20_L;if( byte & 0x01 )DS18B20_H;elseDS18B20_L;udelay(40);DS18B20_H;byte > >= 1;}udelay(10);}//从ds18b20中读出温度数据static unsigned int read_temp(void){unsigned int t = 0 , l = 0;if(ds18b20_reset()){printk("step1,reset_ds18b20 error!n");return 0;}write_byte(0xcc);write_byte(0x44);udelay(4);if(ds18b20_reset()){printk("step2,reset_ds18b20 error!n");return 0;}write_byte(0xcc);write_byte(0xbe);l = read_byte();t = read_byte();t < <= 8;t += l;return t;}//openstatic int ds18b20_open(struct inode *inode, struct file *file){printk("ds18b20 drive open...n");DS18B20_OUT; //初始化该引脚为输出;return 0;}//closestatic int ds18b20_close(struct inode *inode , struct file *file){return 0;}//readstatic ssize_t ds18b20_read(struct file *file, char __user *buffer,size_t len, loff_t *pos){unsigned int temp;printk("ds18b20 drive read...n");temp = read_temp();copy_to_user(buffer, &temp, 4);return 4;}//structstatic const struct file_operations ds18b20_fops = {.owner = THIS_Module,.open = ds18b20_open,.release = ds18b20_close,.read = ds18b20_read,};//条件值变量,用于指示资源是否正常使用unsigned char init_flag = 0;unsigned char add_code_flag = 0;//initstatic __init int ds18b20_init(void){int ret_v = 0;printk("ds18b20 drive init...n");//函数alloc_chrdev_region主要参数说明://参数2: 次设备号//参数3: 创建多少个设备if( ( ret_v = alloc_chrdev_region(&dev_num,0,1,"ds18b20") ) < 0 ){goto dev_reg_error;}init_flag = 1; //标示设备创建成功;printk("The drive info of ds18b20:nmajor: %dnminor: %dn",MAJOR(dev_num),MINOR(dev_num));cdev_init(&ds18b20_cdev,&ds18b20_fops);if( (ret_v = cdev_add(&ds18b20_cdev,dev_num,