单总线协议(ds18b20)读写详解
2、51c代码
3、总结
1、时序图
1、初始化
2、 写
3、 读
2、代码
#includesbit DQ = P2^0; //定义总线的I/O管脚
void SendByte(unsigned char dat);
void Delay4us() //延时4us
{
;
}
void Delay(unsigned char j) //一个循环15us
{
unsigned char i;
while(j--)
{
i = 5;
while (--i);
}
}
bit d18b20_qs() //18b20 起始
{
bit dat;
DQ = 1; //DQ复位
Delay4us();
DQ = 0; //拉低总线
Delay(35); //这里延时大概 525us
DQ = 1; //拉高总线
Delay(2); //这里延时大概 30us
dat = DQ; //读取返回值(0:有18b20存在 1:是没有)
Delay(2);
return dat; //返回数值
}
void d18b20_x(unsigned char dat) //写 8 位 数 据
{
unsigned char i;
for(i=0;i<8;i++) //8位计数器
{
DQ = 0; //拉低总线
DQ = dat & 0x01; //取最低位赋值给总线
Delay(3); //延时45us
DQ = 1; //拉过总线准备写下一个数据(或者总线复位)
dat >>= 1; //数据右移一位
}
}
unsigned char d18b20_d() //读 8 位 数 据
{
unsigned char i,dat=0;
for(i=0;i<8;i++) //8位计数器
{
DQ = 0; //拉低总线
dat >>= 1; //数据右移一位
DQ = 1; //拉过总线(准备读取数据)
if(DQ) //判断是否是 1 如果是就把数据赋值给变量的高位
dat |= 0x80;
Delay(4);
}
return dat; //返回读取到数据数据
}
unsigned int wd() //读取温度函数
{
unsigned char i = 0; //低8位数据
unsigned char j = 0; //高8位数据
unsigned int k = 0; //无符号16整形用来存储读回来的 16位温度数据(j和i组合后的数据)
d18b20_qs(); //初始化
d18b20_x(0xCC); //跳过序列号的操作(因为18b20在总线上可以挂很多个,这个序列号和网卡MAC地址类似)
d18b20_x(0x44); //开启温度转换
Delay(200); //开启温度转换需要时间这里延时一下
d18b20_qs(); //初始化
d18b20_x(0xCC); //跳过序列号的操作(因为18b20在总线上可以挂很多个,这个序列号和网卡MAC地址类似)
d18b20_x(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
i = d18b20_d(); //读取低8位
j = d18b20_d(); //读取高8位
k = j;
k <= 8;
k = k + i;
return k; //返回读取到的16位数据
}
void CSH (void) //初始化串口
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率晶振11.0592MHz
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
//ES = 1; //打开串口中断
}
void SendByte(unsigned char dat) //发送一个字符
{
SBUF = dat; //SBUF 串行数据缓冲器
while(!TI); //TI发送中断标志位 (当数据发送完毕后由硬件置 1 否则等待硬件置 1)
TI = 0;
}
void main()
{
unsigned char i,j;
unsigned int w;
CSH();
while(1)
{
w = wd();
i= w & 0xff; //取低8位
j= (w >> 8)&0xff; //取高8位
SendByte(j); //通过串口把高8位数据返回给上位机
SendByte(i); //通过串口把低8位数据返回给上位机
P1 = j; //使用8个LED 输出高8位数据
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
P1 = i; //使用8个LED输出低8位数据
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
Delay(200); //延时3毫秒
}
}
3、总结
1)使用的是11.0592的晶振
2)使用下面的公式可以计算出摄氏度的温度
wd :读取到的16位数据
摄氏度 = wd x 0.0625
单总线协议ds18b20读写详 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)