📄 ds1820ds.c
字号:
//**********************************************************************//
// 头文件区 //
//**********************************************************************//
#include <reg52.h> /*单片机内部寄存器*/
#include <intrins.h> /*内部函数调用,如_nop_() 、_crol_()、cror();*/
#include <absacc.h> /*绝对地址访问,如XBYTE[0x0fff0]*/
//**********************************************************************//
// 全局变量定义区 //
//**********************************************************************//
#define Com7218 XBYTE [0x0300] //外部地址必须大于FF,否则不能正常读写
#define IN0 XBYTE[0x8FFa] //定义ADC0809的通道0地址//ADC0809地址定义
sbit ICM7218Mode = P1^4; //7218模式选择,状态为0是即选择送数据,
sbit TSOR = P2^3;
static unsigned char MSB=0,LSB=0;//温度值的整数部分,小数部分
static unsigned char count_remain=0,count_pre_c=0;
//**********************************************************************//
// 7218字型码表 0~9,A~F //
//**********************************************************************//
unsigned char code table[]={0xFB,0xB0,0xED,0xF5,0xB6, /* 0,1,2,3,4 */
0xD7,0xDF,0xF0,0xFF,0xF7, /* 5,6,7,8,9 */
0xFE,0x9F,0xCB,0xBD,0xCF, /* A,b,C,d,E */
0xCE,0x00,0x80,0xEE,0xF6, /* F,.(16),blank(17),P(18),q(19)*/
0xBE,0x84,0xBB,0xFA /* H(20), -(21),U(22),n(23) */
}; /*字型码表 */
unsigned char code top_table[]={0x7b,0x30,0x6D,0x75,0x36,0x57,0x5F,0x70,0x7F,0x77};
// 0.,1.,2.,3.,4., 5.,6.,7.,8.,9. 小数点显示
unsigned char buffer[8]={0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80};
//码表缓冲区
//**********************************************************************//
// 延时子程序 //
//**********************************************************************//
void delay(unsigned int d) //延时d微秒
{
while(d--);
}
void delay100ms(void)
{
unsigned char i,j,k;
for(i=0;i<8;i++)
for(j=0;j<25;j++)
for(k=0;k<250;k++);
}
void delay15us(void)
{
unsigned char i;
for(i=0;i<8;i++);
}
void delay60us(void)
{
unsigned char i;
for(i=0;i<30;i++);
}
void showdate(unsigned int t)
{
unsigned char mil,tho,hun,ten,one,i;
unsigned int count;
count=t;
mil=t/10000;
tho=t/1000%10;
hun=t/100%10;
ten=t/10%10;
one=t%10;
if(mil==0)
{
buffer[4] = 0x80;
}
else
{
buffer[4] = table[mil];
}
if(mil==0&&tho==0)
{
buffer[3] = 0x80;
}
else
{
if((count>=100)&&(count<=999))
buffer[3] = top_table[tho];
else buffer[3] = table[tho];
}
if(mil==0&&tho==0&&hun==0)
{
buffer[2] = 0x80;
}
else
{
if((count>=10)&&(count<=99))
buffer[2] = top_table[hun];
else buffer[2] = table[hun];
}
if(mil==0&&tho==0&&hun==0&&ten==0)
{
buffer[1] = 0x80;
}
else
{
buffer[1] = table[ten];
}
buffer[0] = table[one];
ICM7218Mode = 1 ; //ICM7218B的方式字
Com7218 = 0xF0 ; //非译码方式
delay(10);
//连续向显示芯片送显示数据
//=======================
ICM7218Mode=0;
for(i=0;i<8;i++)
{
Com7218 = buffer[ i ] ;
}
}
void write_0_DS(void)//写 bit 0
{//写数据位0:置总线为低电平并保持至少15us,
//然后保持低电平15us~45us等待从端对电平采样,最后拉高电平完成写操作
TSOR=1;
TSOR=0;
delay15us();
delay15us();
delay15us();
delay15us();
delay15us();
TSOR=1;
_nop_();
_nop_();
}
void write_1_DS(void)//写 bit 1
{//写数据位1:置总线为低电平并保持1us~15us,
//然后拉高电平并保持15us~45us等待从端对电平采样,最后完成写操作
TSOR=1;
TSOR=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TSOR=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
delay15us();
delay15us();
}
bit read_DS(void)//读取数据位
{//读数据位:置总线为低电平并保持至少1us,然后拉高电平保持1us,
//在15us内采样总线电平获得数据,延时45us完成读操作
bit b;
TSOR=1;
TSOR=0;
_nop_();
_nop_();
_nop_();
TSOR=1;
_nop_();
_nop_();
_nop_();
b=TSOR;
delay15us();
delay15us();
delay15us();
_nop_();
_nop_();
return b;
}
void reset_DS(void)//复位总线
{//总线复位:置总线为低电平并保持480us,然后拉高电平,
//等待从端重新拉低电平作为响应,则总线复位完成
unsigned char i;
TSOR=1;
TSOR=0;
for(i=0;i<9;i++)
delay60us();
TSOR=1;
while(TSOR);//程序的关键,总线控制器发出(TX)一个复位脉冲(一个最少480us的
//低电平信号),然后释放总线,进入接收状态(RX)。单线总线由4.7K上拉电阻拉到
//到高电平。探测到I/0引脚上的上升沿后,DS182015等待15~60us,然后发出存在脉冲
//(一个60~240us的低电平信号。
for(i=0;i<3;i++)
delay60us();
}
void write_byte_DS(unsigned char byte)//写一个字节(byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byte & 0x01==0x01) //最低bit是否为0?
write_1_DS();
else
write_0_DS();
byte=byte>>1;
}
}
unsigned char read_byte_DS(void) //读一个字节(byte)
{
unsigned char i,j=0;
bit b;
for(i=0;i<8;i++)
{
b=read_DS(); //读取1bit
if(b) //为1否?
j+=1;
j=_cror_(j,1); //循环右移1位
}
return j;
}
void init_DS(void)
{
reset_DS(); //复位总线
write_byte_DS(0xcc); //忽略ROM匹配操作
write_byte_DS(0x4e); //设置写模式
write_byte_DS(0x64); //写温度上限TH为100度
write_byte_DS(0x8a); //写温度下限为负10度
write_byte_DS(0x1f); //写温度计配置寄存器
}
void get_temp_DS(void) //获得温度,2字节的数据分别放在MSB,LSB中
{
reset_DS(); //复位总线
write_byte_DS(0xcc); //忽略ROM匹配操作
write_byte_DS(0x44); //温度转换命令
delay100ms();
delay100ms();
delay100ms();
reset_DS(); //复位总线
write_byte_DS(0xcc); //忽略ROM匹配操作
write_byte_DS(0xbe); //读取寄存器
LSB=read_byte_DS(); //读取第1字节
MSB=read_byte_DS(); //读取第2字节
read_byte_DS(); //读取第3字节
read_byte_DS(); //读取第4字节
read_byte_DS(); //读取第5字节
read_byte_DS(); //读取第6字节
count_remain=read_byte_DS(); //读取第7字节
count_pre_c=read_byte_DS(); //读取第8字节
read_byte_DS(); //读取第9字节
/*
MSB=MSB<<4;
MSB+=(LSB&0xf0)>>4; //获得温度值整数部分
LSB=(LSB&0x0f) ? 5:0; //获得温度值小数部分
//count_pre_c=(count_pre_c-count_remain)*10/count_pre_c;*/
}
void main(void)
{
TSOR=1; //1-wire总线释放
showdate(2);
delay(60000);
init_DS();
while(1)
{
get_temp_DS();
showdate(count_remain*1000);
delay(50000);
get_temp_DS();
showdate(count_pre_c);
delay(50000);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -