📄 18b20.c
字号:
#include <AT91SAM7S64.H> // AT91SAM7S64处理器的寄存器头文件
#include "lib_AT91SAM7S64.h"
#include "18B20.h"
#include "Board.h"
void delay_us(int n)
{
unsigned char i;
for(;n>0;n--)
{
for(i=0;i<10;i++)
{;}
}
}
/////////// 复位1-wire总线,并探测是否有温度芯片DS18B20挂在总线上////////////
int ds18b20_reset(void)
{
int sdt;
unsigned char bus_flag; //用来返回的标志位
DQ_TO_0;
AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20);
DQ_1;
delay_us(1);
DQ_0;
delay_us(500); //延时490us
DQ_1;
DQ_TO_1; //设置1-wire总线为输入
AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20);
delay_us(67.5);
// 探测总线上是否有器件
sdt=*AT91C_PIOA_PDSR;
if(sdt&DQ_18B20)
{
bus_flag=0; // 复位单总线但没有发现有器件在线
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,LED0);
}
else
{
bus_flag=1; // 复位单总线并发现有器件在线
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,LED1);
}
delay_us(490-67.5);
DQ_1;
return(bus_flag);
}
/////////// 写命令或数据到温度芯片DS18B20(发送一个字节)///////////
void ds18b20_write(unsigned char dat)
{
unsigned char count;
DQ_TO_0; // 设置1-wire总线为输出
AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20);
// 每个字节共8位,一次发一位
for(count=0; count<8; count++) {
if(dat&0x01)
{
delay_us(1);
DQ_0;
delay_us(6);
DQ_1;
delay_us(62);
}
else
{
delay_us(1);
DQ_0;
delay_us(62);
DQ_1;
}
dat >>= 1;
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,LED2);
}
}
///////////// 从温度芯片DS18B20读配置或数据(接收一个字节) ////////////
unsigned char ds18b20_read(void)
{
unsigned char count,temp;
int sdt;
temp = 0x00; // 数据接收准备
for(count=0; count<8; count++) {
DQ_TO_0;
AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20);
DQ_0;
delay_us(2);
DQ_1;
temp>>=1;
DQ_TO_1; // 设置1-wire总线为输入
AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20);
delay_us(3);
sdt=*AT91C_PIOA_PDSR;
if(sdt&DQ_18B20)
{
temp|=0x80; // 读取总线电平,先收低位再收高位
}
else
{
temp&=0x7f;
}
delay_us(62); // 必须大于60us
DQ_TO_0;
AT91F_PIO_Enable(AT91C_BASE_PIOA,DQ_18B20);
DQ_1;
}
AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,LED3);
return temp;
}
/////////////温度转换函数//////////////////////
void convert_T(void)
{
if(ds18b20_reset()==1) { // 如果复位成功
ds18b20_write(0xcc); // 跳过多器件识别
ds18b20_write(0x44); // 启动温度转换
}
}
//////////////// 读取转换后的温度值 ///////////////////////
unsigned int read_Tz(void)
{
unsigned char a,b,temp;
volatile unsigned int t=0;
if(ds18b20_reset()==1) { // 如果复位成功
ds18b20_write(0xcc); // 跳过多器件识别
ds18b20_write(0xbe); // 读暂存器
a = ds18b20_read(); //读取温度值低位
b = ds18b20_read(); //读取温度值高位
//前5位符号,温度大于0,这5位为0,值乘0.0625即得实际温度
//温度小于0,这5位为1,数值取反加1再乘0.0625即得实际温度
temp = b & 0x80;
if(temp == 0)
{
t = b << 4;
a=a>>4;
t = t + a;
}
else
{
b = b & 0x07;
t = b << 8;
t = t + a;
t = ~t + 1;
}
t = t * 0.625;
return(t);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -