基于Linux3.0.8+smart210的DS18B20驱动移植
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了基于Linux3.0.8+smart210的DS18B20驱动移植,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7178字,纯文字阅读大概需要11分钟。
内容图文
![基于Linux3.0.8+smart210的DS18B20驱动移植](/upload/InfoBanner/zyjiaocheng/1298/35e6c9f20a4a4079bc78d5d15580da19.jpg)
Linux内核:Linux3.0.8
硬件:友善之臂smart210开发板,A8内核
编译器:arm-linux-gcc 4.5.1
DS18B20是常用的温度传感器,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。工作电压 3.0~5.5V/DC
超低功耗静态功耗<3uA,测温范围 -55℃~+125℃,
测量结果以9~12位数字量方式串行传送。
面对着扁平的那一面,左负右正,一旦接反就会立刻发热,有可能烧毁!同时,接反也是导致该传感器总是显示85℃的原因。
DS18B20实物图
DS18B20电路如图如下
驱动代码如下
DS18B20_driver.c
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <asm/uaccess.h> //其中copy_to*在其中
#include <mach/gpio.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
/*基于友善之臂smart210开发板,DS18B20数据引脚GPH2(0),位于开发板左上角GPIO,第二排排针倒数第五引脚*/
spinlock_t lock; //不用也行unsignedint tmp_wendu ;
#define DEVICE_NAME "DS18B20"#define NODE_NAME "DS18B20"//********************************//功能:设置引脚为输入功能//********************************void set_con_in(void)
{
s3c_gpio_cfgpin(S5PV210_GPH2(0), S3C_GPIO_INPUT);
//gpio_set_value(S5PV210_GPH2(0), 1);
}
//********************************//功能:设置引脚为输出功能//********************************void set_con_out(void)
{
s3c_gpio_cfgpin(S5PV210_GPH2(0), S3C_GPIO_OUTPUT);
}
//********************************//功能:引脚输出高或低电平功能,i=1(高)//********************************void set_output_data(int i)
{
if (i == 0) {
gpio_set_value(S5PV210_GPH2(0), 0);
} elseif(i == 1) {
gpio_set_value(S5PV210_GPH2(0), 1);
}
}
//********************************//功能:ds18b20复位//********************************int init_DS18B20(void)
{
int result = 10;
set_con_out();
__udelay(3); //短时间延迟
set_output_data(1);
__udelay(3); //短时间延迟
set_output_data(0);
__udelay(550); //480-960us
set_output_data(1);
__udelay(20); //15-60us,最好大于15us
set_con_in();
__udelay(100); //60-240us, ds18b20回应值保持时间
result = gpio_get_value(S5PV210_GPH2(0));
printk("init_DS18B20--result:%d\n", result);
set_con_out();
__udelay(3);
set_output_data(1);
//__udelay(300);return result;
}
//*************************************//功能:从ds18b20读一个字节的数据//*************************************unsignedchar read_one_char(void)
{
unsignedchar i = 0;
unsignedchar dat = 0;
unsignedchar temp = 0;
spin_lock(&lock);
for(i=0; i<8; i++) {
set_con_out();
__udelay(3);
set_output_data(1);
dat >>= 1;
set_output_data(0); //该行与下行等效该行上面的4行
__udelay(18); //按时序来延时,不能太小或太大
set_con_in();
__udelay(1);
temp = gpio_get_value(S5PV210_GPH2(0)) & 0x01;
if (temp)
dat |= 0x80;
else
dat |= 0x00;
printk("read_one_char--temp: %d\n", temp);
__udelay(65);
}
spin_unlock(&lock);
printk("read_one_char--dat: %d\n", dat);
return dat;
}
//*************************************//功能:向ds18b20写一个字节的数据//*************************************void write_one_char(unsignedchar dat)
{
//printk("write_one_char--dat: %d\n", dat);unsignedchar i = 0;
spin_lock(&lock);
set_con_out();
for(i=0; i<8; i++) {
set_output_data(1);
__udelay(1);
set_output_data(0);
__udelay(5);
set_output_data(dat & 0x01);
__udelay(55);
set_output_data(1);
__udelay(2);
dat >>= 1;
}
spin_unlock(&lock);
__udelay(30);
}
//********************************//功能:读取ds18b20的温度//********************************unsignedint read_wendu(void)
{
unsignedchar dat_L = 0, dat_H = 0;
unsignedint wendu_value;
int ds18b20_back_value;
ds18b20_back_value = init_DS18B20();
if (ds18b20_back_value)
printk("ds18b20 init error!!!\n");
else
printk("ds18b20_back_value %d\n", ds18b20_back_value);
write_one_char(0xCC);
write_one_char(0x44);
if (init_DS18B20())
printk("ds18b20 init error!!!\n");
else
printk("ds18b20 init ok \n");
write_one_char(0xcc);
write_one_char(0xBE);
dat_L = read_one_char();
dat_H = read_one_char();
if((dat_H & 0xf8) != 0x00) {
dat_L = (~dat_L) + 1;
if (dat_L > 255)
dat_H = (~dat_H) + 1;
}
wendu_value = (dat_H * 16 + dat_L/16) * 10 +((dat_L%16)*10/16);
printk("read_wendu--dat_L: %d dat_H: %d wendu: %d.%d\n",dat_L, dat_H, wendu_value/10, wendu_value%10);
return(wendu_value);
}
staticint ds18b20_open(struct inode *inode, struct file *filp)
{
printk (KERN_INFO "Device opened\n");
spin_lock_init(&lock);
return0;
}
/*读取数据*/staticint ds18b20_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
{
unsignedint wendu_value = 0;
int res = 0;
wendu_value = read_wendu();
if (wendu_value>2000)
{
wendu_value = tmp_wendu;
}
tmp_wendu = wendu_value;
printk("wendu_valu is %d\n", wendu_value);
res=copy_to_user(buffer, &wendu_value, sizeof(wendu_value));
if (res < 0)
{
printk("copy_to_user error! ");
}
printk("copy_to_user len! %d\n ", res);
return0;
}
/*写命令,在此置空*/staticint ds18b20_write(struct file *file, constchar *buffer, size_t count, loff_t * ppos)
{
return0;
}
staticint ds18b20_release(struct inode *inode,struct file *filp)
{
printk (KERN_INFO "device closed\n");
return0;
}
staticlong ds18b20_ioctl(struct file *filp, unsignedint cmd,
unsignedlong arg)
{
return0;
}
staticstruct file_operations ds18b20_fops = {
.owner = THIS_MODULE,
.open = ds18b20_open,
.read = ds18b20_read,
.write = ds18b20_write,
.unlocked_ioctl = ds18b20_ioctl,
.release = ds18b20_release,
};
staticstruct miscdevice ds18b20_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.nodename = NODE_NAME,
.fops = &ds18b20_fops,
};
staticint __init ds18b20_dev_init(void) {
int ret;
ret = gpio_request(S5PV210_GPH2(0), "DS18B20");
if (ret) {
printk("%s: request GPIO %d for GPE0 failed, ret = %d\n", DEVICE_NAME,
S5PV210_GPH2(0), ret);
return ret;
s3c_gpio_cfgpin(S5PV210_GPH2(0), S3C_GPIO_OUTPUT);
gpio_set_value(S5PV210_GPH2(0), 1);
}
ret = misc_register(&ds18b20_dev);//注册杂设备驱动
printk(DEVICE_NAME"\tinitialized\n");
return ret;
}
staticvoid __exit ds18b20_dev_exit(void) {
int i;
for (i = 0; i < 1; i++) {
gpio_free(S5PV210_GPH2(0));
}
misc_deregister(&ds18b20_dev);
}
module_init(ds18b20_dev_init);
module_exit(ds18b20_dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("GaoZhe.");
Makefile
ifneq ($(KERNELRELEASE),)
obj-m := DS18B20_driver.o
else
PWD := $(shell pwd)
KDIR:= /home/bishe/kernel/linux-3.0.8all:
make -C $(KDIR) M=$(PWD)
clean:
rm -rf *.o *.order *.ko *.mod.c *.symvers *.c~ *~
endif
应用程序如下
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/select.h>
int main(int argc, char *argv[])
{
int fd, i;
char *buf;
unsigned int a=0;
fd = open("/dev/DS18B20", O_RDWR);
if(-1 == fd)
{
perror("open file error\r\n");
exit(-1);
}
printf("open /dev/DS18B20 success!\n");
while(1)
{
int i=read(fd,&a,5);
if(i<0)
{
printf("read tempture is error!\n");
}
printf("test_temptureis:%d.%d\n",a/10,a%10);
sleep(1);
}
close(fd);
return0;
}
在这里用的是misc杂项设备的,#make之后,会生成DS18B20_driver.ko,然后#insmod DS18B20_driver.ko加载模块,执行#cat /proc/devices 发现并没有DS18B20这个驱动模块啊,而多了一个主设备号为10的misc,同时,#ls /dev 会发现自动生成了DS18B20设备文件,为什么呢?因为misc杂项设备驱动共用一个主设备号,区分不同设备的依据是次设备号,这里共用的是主设备号是10,次设备号是系统自动分配的。当#insmod后,系统会自动在/dev目录下创建设备文件,不需要手动mknod创建。
原文:http://blog.csdn.net/gz_go/article/details/45952879
内容总结
以上是互联网集市为您收集整理的基于Linux3.0.8+smart210的DS18B20驱动移植全部内容,希望文章能够帮你解决基于Linux3.0.8+smart210的DS18B20驱动移植所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。