今天在各位前辈已有成就的基础上花了两天时间终于把这个驱动给搞定了,从开始编译成模块看效果,进行调试,再到编译进内核,最后又编译了一个界面出来,虽说大多数的程序代码是用各位前辈的成果,但坐下来自己收获也不小,现在写下来,以供以后参考,也和各位爱好者交流一下,呵呵!
一.编译成模块
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <asm/uaccess.h>
#include <linux/miscdevice.h> /**内核版本2.6.32加以下头文件***/
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#define DEVICE_NAME "DS18B20"
#define DS18B20_MAJOR 250
#define DS_PIN S3C2410_GPB1
#define OUT S3C2410_GPB1_OUTP
#define IN S3C2410_GPB1_INP
#define DIS_UP 1
#define EN_UP 0
//#define Search 0x00F0
#define Read_ROM 0x0033 //just for one
#define Skip_ROM 0x00CC //ds18b20的固定时序, 跳过读序号列号的操作
#define Convert 0x0044 //ds18b20的固定时序,管脚识别到该信号是开始对测到的温度进行转换
#define Write 0x004E //TH---TL---Config
#define Read 0x00BE //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
//#define bit_9 0x001F
//#define bit_10 0x003F
//#define bit_11 0x005F
#define bit_12 0x007F
#define uint16 unsigned int
//unsigned int ROM_DATA[8];
void usdelay(unsigned int i)
{
unsigned int j;
for(i=i;i>0;i--)
for(j=90;j>0;j--);
}
void msdelay(unsigned int i) //延时 i ms
{
for(i=i;i>0;i--)
usdelay(1000);
}
void SetL(void)
{
s3c2410_gpio_cfgpin(DS_PIN,OUT);
s3c2410_gpio_setpin(DS_PIN,0);
}
void SetH(void)
{
s3c2410_gpio_cfgpin(DS_PIN,OUT);
s3c2410_gpio_setpin(DS_PIN,1);
}
unsigned int Read_DS(void)
{
unsigned int i;
s3c2410_gpio_cfgpin(DS_PIN,IN);
s3c2410_gpio_pullup(DS_PIN,EN_UP);
__asm("nop");
__asm("nop");
__asm("nop");
i=s3c2410_gpio_getpin(DS_PIN);
if(i!=0)
i=1;
return i;
}
unsigned int ds_start(void) //初始化ds18b20
{
unsigned int flag=1;
int err=0;
SetH();
udelay(2);
SetL();
udelay(600); //560延时要大于480u
SetH();
udelay(60); //稍作延时
while(Read_DS()!=0) //ds18B20初始化成功会返回一个低电平,此时跳出循环,执行下面的操作
{
printk(DEVICE_NAME "Wait..../n");
udelay(5);
err++; //初始化的最多次数吧,超过规定的次数,说明初始化失败
if(err==20)
{
printk(DEVICE_NAME "start fail/n");
return -1;
}
}
//printk(DEVICE_NAME "start sucess/n");
flag=0;
SetH();//初始化成功后赋为高电平准备从外界读入温度
udelay(400);
return flag;
}
void ds_send(unsigned int uidata) //向18b20写入一个字节的数据
{
//printk("the send data is %d/n",uidata);
int i;
for(i=0;i<8;i++)
{
SetL();
udelay(1);
if((uidata&1)!=0)
{
SetH();
udelay(80); //等待18b20进行数据采集
}
else
{
udelay(80); //等待18b20进行数据采集
SetH();
}
uidata>>=1;
}
}
unsigned int ds_read(void) //从18b20读一个字节的数据
{
unsigned int uidata=0;unsigned int i;
for(i=0;i<8;i++)
{
uidata>>=1;
SetL();
udelay(1);
s3c2410_gpio_setpin(DS_PIN,1);
s3c2410_gpio_cfgpin(DS_PIN,IN);
udelay(10);
if(s3c2410_gpio_getpin(DS_PIN))
uidata=(uidata|0x80);
udelay(65);
SetH();
}
// printk("ds_read success/n");
return uidata;
}
unsigned int read_tem(void)
{
unsigned int th,tl;
//int err=0;
//ds_init(100,0,bit_12);
th=tl=0;
ds_start();
ds_send(Skip_ROM); //跳过读序号列号的操作
ds_send(Convert); //启动温度转换
mdelay(50);
ds_start();
ds_send(Skip_ROM); //跳过读