Linux驱动开发-编写DS18B20驱动

2023-07-11

linux(2.4内核)ds18b20驱动程序

***************************************************************

ds18b20.h

***************************************************************

#ifndef ds18b20
#define ds18b20
void delay_1us(void);
void delay_nus(unsigned int n);
void delay_1ms(void);
void delay_nms(unsigned int n);
void tempconvert(unsigned char temH,unsigned char temL);
unsigned char InitDs18b20(void);
void ConfigDs18b20(void);
void DS18B20_WriteOneBit_0(void);
void DS18B20_WriteOneBit_1(void);
unsigned char DS18B20_ReadOneBit_1(void);
unsigned char ReadOneByte(void);
void WriteOneByte(unsigned char dat);
float ReadTemperature(void);
#endif

***************************************************************

ds18b20.c

***************************************************************

#include<stdio.h>
#include<unistd.h>
//#include"44B.H"
#include"hardware.h"

void delay_1us(void)//1us延时函数

{
asm("nop");
}

void delay_nus(unsigned int n)//N us延时函数

{

unsigned int i=0;

for (i=0;i<n;i++)

delay_1us();

}

void delay_1ms(void)//1ms延时函数

{

unsigned int i;

for (i=0;i<1140;i++);

}

void delay_nms(unsigned int n)//灶凳N ms延时函数

{

unsigned int i=0;

for (i=0;i<n;i++)

delay_1ms();

}
void tempconvert(unsigned char temH,unsigned char temL)
{
unsigned char L,H;
H=(temL >> 4)+(temH<<隐袜旅4); //温度整数部分
L=(temL & 0x0F)? 5:0; //温度小数部分.

}

unsigned char InitDs18b20(void) //复位函数定义
{
unsigned char RX=1; //函数返回值设置
//rPCONF=0x01; //PF0输出口
rPCONF=0x1255;
rPDATF=0x01;
delay_nus(5);
rPDATF=0x0; //PF0输出0,拉低
delay_nus(500);
delay_1us();
rPDATF=0x01; //低脉冲时间500us已过,PF0置高
// delay_nus(100);
rPCONF=0x0000; //改为输入口,进行读值
delay_nus(100);
if((rPDATF & 0x01)==0) //读到PF0口为低时说明存在脉冲收到
{
RX=0;//success!
}
else
RX=1;//fail!
delay_nus(480);
//好配 rPCONF=0x01;//output
rPCONF=0x1255;
rPDATF=0x01;
return RX; //函数返回RX值,在收到存在脉冲时RX为零
}

unsigned char DS18B20_ReadOneBit_1()
{
unsigned char bReturnValue=0;
//rPCONF=0x01;
rPCONF=0x1255;
rPDATF=0x01;
//delay_1us();
rPDATF=0x0;
delay_1us();
rPDATF=0x01;//a sign read
rPCONF=0x0000;
delay_nus(15);
if(rPDATF&0x01)
{
bReturnValue=1;
}
delay_nus(50);
return bReturnValue;
}
unsigned char DS18B20_ReadOneBit_0()
{
unsigned char bReturnValue=1;
rPCONF=0x1255;
rPDATF=0x01;
rPDATF=0x0;
delay_1us();
rPCONF=0x0000;
delay_nus(15);
if((rPDATF&0x01)==0)
bReturnValue=0;
rPCONF=0x1255;
rPDATF=0x01;
delay_nus(50);
return bReturnValue;
}
unsigned char ReadOneByte(void)
{
unsigned char uci;
unsigned char ucReadData;
unsigned char ucMaskCode;
ucReadData = 0;
ucMaskCode = 0x01;
for(uci=0; uci<8; uci++)
{
if(DS18B20_ReadOneBit_1()==1)
{
ucReadData |= ucMaskCode;
}
ucMaskCode <<= 1 ;
}
return ucReadData;
}
void DS18B20_WriteOneBit_0()
{
rPCONF=0x1255;
//rPCONF=0x01;
rPDATF=0x01;
// delay_1us();
rPDATF=0x0;
delay_nus(15);

delay_nus(15);
delay_nus(30);
rPDATF=0x01;
}
void DS18B20_WriteOneBit_1()
{
//rPCONF=0x01;
rPCONF=0x1255;
rPDATF=0x01;
// delay_1us();
rPDATF=0x0;
delay_nus(15);
rPDATF=0x01;
delay_nus(15);
delay_nus(30);
}

void WriteOneByte(unsigned char ucWriteData)
{
unsigned char uci;
unsigned char ucTemp;
ucTemp = ucWriteData;
for(uci=0; uci<8; uci++)
{
if(ucTemp & 0x01)
{
DS18B20_WriteOneBit_1();
}
else
{
DS18B20_WriteOneBit_0();
}
ucTemp >>= 1 ;
}
}

void ConfigDs18b20 (void)
{
InitDs18b20();
printf("I am writing!\n");
WriteOneByte(0xcc); //skip rom
WriteOneByte(0x4e); //write scratchpad
WriteOneByte(0x19); //温度上下限
WriteOneByte(0x1a);
WriteOneByte(0x7f); //set 11 bit (0.0625)
InitDs18b20();
WriteOneByte(0xcc); //skip rom
WriteOneByte(0x48); //保存设定值
InitDs18b20();
WriteOneByte(0xcc); //skip rom
WriteOneByte(0xb8); //回调设定值
}

float ReadTemperature(void)
{
unsigned char tempL=0; //临时变量低位
unsigned char tempH=0; //临时变量高位
unsigned char TH=0;//上限
unsigned char TL=0;//下限
unsigned char con=0;
float temperature; //温度值
unsigned char ucTempDataBuff[9]; //用于映像DS18B20内容字节内容的缓冲区

ConfigDs18b20();
if( InitDs18b20()==1)
{
printf("error") ; //初始化
exit(1);
}
WriteOneByte(0xcc); //跳过读序列号的操作
WriteOneByte(0x44); //启动温度转换
// usleep(750000); //转换需要一点时间,延时
delay_nms(750);
InitDs18b20(); //初始化
WriteOneByte(0xcc); //跳过读序列号的操作
WriteOneByte(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)
// tempL=ReadOneByte(); //读出温度的低位LSB
// tempH=ReadOneByte(); //读出温度的高位MSB
ucTempDataBuff[0] = ReadOneByte();
ucTempDataBuff[1] = ReadOneByte();
ucTempDataBuff[2] = ReadOneByte();
ucTempDataBuff[3] = ReadOneByte();
ucTempDataBuff[4] = ReadOneByte();
ucTempDataBuff[5] = ReadOneByte();
ucTempDataBuff[6] = ReadOneByte();
ucTempDataBuff[7] = ReadOneByte();
ucTempDataBuff[8] = ReadOneByte();
for(con=0;con<9;con++)
printf("%x\n",ucTempDataBuff[con]);
//温度转换,把高低位做相应的运算转化为实际温度
tempL=ucTempDataBuff[0];
tempH=ucTempDataBuff[1];
tempconvert(tempH,tempL);
printf("--------------------------------");
temperature=((tempH*256)+tempL)*0.0625;
//delay(200);
return temperature;
}

DS18B20的程序

//将DQ与Vcc之间接入4.7K上拉电阻
#include "reg52.h"
#include "INTRINS.H"
#include "1602.c"
#define uchar unsigned char
#define uint unsigned int
//#define CLEARSCREEN LCD_en_command(0x01) 1602清屏
sbit DQ="P1"^0;
/*操作命令代码
跳过ROM 0xCC
发送温度转换 0xBE
写EEPROM 0x4E
*/
/////////////低层驱动子程序///////////
void Init18B20(void); //初始化
void Write18B20(uchar ch);//写数据
unsigned char Read18B20(void);//读数据
void Delay15(uchar n);
void Delay10ms(uint delay_num);
void Display(void);
/////////////////////////////////////
code uchar decimalH[]={00,06,12,18,25,31,37,43,50,56,62,68,75,81,87,93};
code uchar decimalL[]={00,25,50,75,00,25,50,75,00,25,50,75,00,25,50,75};

uint ResultTemperatureH ,ResultTemperatureLH,ResultTemperatureLL;//整数,小数高位,小数低位
uint ResultSignal;//符号位

main()
{ uint TemH,TemL,delay,k=0;
for(; ; )
{
Init18B20();
Write18B20(0xCC);//跳过ROM
_nop_();
//Write18B20(0x4E);//写EEPROM
// Write18B20(0x00);//Th
//Write18B20(0x00);//Tl
Write18B20(0x7f);//12 bits温度分辨率
Init18B20();
Write18B20(0xCC);//跳过ROM
_nop_();

Write18B20(0x44);//发送温度转换指令
Delay10ms(25);
Delay10ms(25);
Delay10ms(25);
Delay10ms(25);//等待1s转换
Init18B20();
Write18B20(0xCC);//跳过ROM
Write18B20(0xBE);//发送温度转换指令
TemL="Read18B20"(); //读低位温度值
TemH="Read18B20"(); //读高位温度值
Delay10ms(2);

TemH=(TemH<<4)|(TemL>>4);
TemL="TemL"&0x0f; //取低4位
if(TemH&0x80)
{ TemH=~TemH;
TemL=~TemL+1;
ResultSignal="1"; //负
}
else ResultSignal="0"; //正
ResultTemperatureLH="decimalH"[TemL];
ResultTemperatureLL="decimalL"[TemL];
ResultTemperatureH="TemH";
Display();
for(delay=0;delay<60000;delay++);
for(delay=0;delay<20000;delay++);

}
}

void Display(void)
{ uint i,j,q;
LCD_init();
CLEARSCREEN;
LCD_en_command(0x01);
delay_nms(2);

q="ResultTemperatureH/100";
i=(ResultTemperatureH%100)/10;
j="ResultTemperatureH-"(i*10+q*100);
LCD_write_string(0,LINE1," Jaq1217 18B20 ");
if(ResultSignal)
{ LCD_write_string(0,LINE2," T is:- . "); }
else {LCD_write_string(0,LINE2," T is:+ . ");}
LCD_write_char(0x07,LINE2,q|0x30);
LCD_write_char(0x08,LINE2,i|0x30);
LCD_write_char(0x09,LINE2,j|0x30);
LCD_write_char(0x0b,LINE2,(ResultTemperatureLH/10)|0x30);
LCD_write_char(0x0c,LINE2,(ResultTemperatureLH%10)|0x30);
LCD_write_char(0x0d,LINE2,(ResultTemperatureLL/10)|0x30);
LCD_write_char(0x0e,LINE2,(ResultTemperatureLL%10)|0x30);
}
unsigned char Read18B20(void)
{ unsigned char ch;
unsigned char q ;
for(q=0;q<8;q++)
{ch=ch>>1;
DQ="0";
_nop_();
DQ="1";
_nop_();_nop_();_nop_();_nop_();
if(DQ==1)
{ch="ch|0x80";}
else {ch="ch"&0x7f;}
Delay15(3);
DQ="1";

}
return (ch);
}

void Write18B20(uchar ch)
{ uchar i;
for(i=0;i<8;i++)
{ DQ="0";
Delay15(1);
DQ="ch"&0x01;
Delay15(3);
DQ="1";
ch="ch">>1;
_nop_();
}
}
void Init18B20(void)
{ DQ="0";
Delay15(33);//至少延时480us
DQ="1";
Delay15(10);//至少延时100us
/*if(DQ==1) return 0; //初始化失败
else return 1;
DQ=1; Delay15(18); */
}
void Delay15(uchar n)
{ do{ _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_();
n--;

}while(n);
}
void Delay10ms(uint delay_num)
{
uchar i;
while(delay_num--)
{
for(i=0;i<125;i++)
{;}
}
}

说明:如果你只需要温度部分的,那么LCD部分的,你可以不看,只参考18B20的程序段。但愿对你有帮助
满意请采纳。

文章推荐

相关推荐