📄 at89s51+ds18b20+led.txt
字号:
#include <reg51.h>
#include <stdlib.h>
#include <intrins.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define ledport P0
sbit shi=P1^0; //十位数码管位选
sbit gew=P1^1; //个位数码管位选
sbit sfw=P1^2; //十分位数码管位选
sbit ds18b20_dat=P3^0; //ds18b20数据端
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
uchar code ds18b20_xs_tab[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//ds18b20小数转换表格
uchar code ds18b20_ledtab1[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67,0x00};
//共阳数码管0~9和不显示字形码表
uchar code ds18b20_ledtab2[]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xE7};
uchar data ds18b20_t[2]={0x00,0x00};//定义ds18b20读取温度高低字节保存位置
bit ds18b20_flag; //ds18b20标记位,为0说明检测到ds18b20,否则没有检测到ds18b20
uchar ds18b20_zf;//ds18b20温度正负标志保存部分
uchar ds18b20_shi; //十位数码管缓冲区
uchar ds18b20_ge; //个位数码管缓冲区
uchar ds18b20_sfw; //十分位数码管缓冲区
void uDelay(uint i) //us延时
{
while(i--);
}
void mDelay(uint mDelay1) //1ms延时
{
uint mDelay2;
for(;mDelay1>0;mDelay1--)
{
for(mDelay2=0;mDelay2<114;mDelay2++)
{;;}
}
}
/* DS18B20读一个字节*/
uchar ds18b20_read()
{
uchar i;
uchar dat;
for(i=8;i>0;i--)
{
ds18b20_dat=0; //拉低总线
dat>>=1;
ds18b20_dat=1;
if(ds18b20_dat)
dat|=0x80;
uDelay(4);
}
return(dat);
}
/* DS18B20读一个字节 //
uchar ds18b20_read()
{
uchar i;
uchar dat;
for(i=8;i>0;i--)
{
ds18b20_dat=0; //拉低总线
CY=ds18b20_dat; //读取数据到CY
ACC7=CY;
ds18b20_dat=1;
ACC=ACC>>1;
uDelay(4);
}
return(dat);
}
*/
/* DS18B20写一个字节
void ds18b20_write(uchar ds18b20_cmd)
{
uchar i;
ACC=ds18b20_cmd;
for(i=8;i>0;i--)
{
ds18b20_dat=0; //拉低总线
ds18b20_dat=ACC0;//最低位先送
uDelay(5); //延时约16us
ds18b20_dat=1; //总线复位
ACC=ACC>>1;
}
uDelay(5);
}
*/
/* DS18B20写一个字节*/
void ds18b20_write(uchar ds18b20_cmd)
{
uchar i;
for(i=8;i>0;i--)
{
ds18b20_dat=0; //拉低总线
ds18b20_dat=ds18b20_cmd&0x01;
uDelay(5); //延时约16us
ds18b20_dat=1; //总线复位
ds18b20_cmd>>=1;
}
uDelay(5);
}
/* DS18B20复位*/
void ds18b20_reset()
{
ds18b20_dat=1;
uDelay(8);
ds18b20_dat=0;
uDelay(80); //复位脉冲
ds18b20_dat=1;
uDelay(14); //拉高总线等待应答
ds18b20_flag=ds18b20_dat; //0是存在,1是不存在
uDelay(20);
ds18b20_dat=1;
// ruturn(ds18b20_flag);
}
/* 读取DS18B20温度寄存器前2个字节*/
void ds18b20_read_temp()
{
uchar i;
uint ds18b20_zs; //保存转换后的整数部分
uint ds18b20_xs; //保存转换后的小数部分
ds18b20_reset();
ds18b20_write(0xcc);//跳过rom
ds18b20_write(0x44);//温度转换
uDelay(5);
ds18b20_reset();
ds18b20_write(0xcc);//跳过rom
ds18b20_write(0xbe);//读取暂存器前2个字节,第0个字节是温度低8位,第1个字节是温度高8位
for(i=0;i<2;i++)
{
ds18b20_t[i]=ds18b20_read();
}
ds18b20_reset();
ds18b20_zs=((ds18b20_t[1]&0x0f)<<4)|((ds18b20_t[0]&0xf0)>>4);//整数部分转换
ds18b20_xs=ds18b20_t[0]&0x0f;//小数部分转换
// if(ds18b20_zs&0x80==0x80)//使用这句判断温度正负的话测试到的温度的整数如果是奇数的话则显示混乱,很不解!
if(ds18b20_zs>0xf7) //如果是负数
{
ds18b20_zs=~ds18b20_zs;
ds18b20_xs=~ds18b20_xs+1;
// ds18b20_zf=0xbf;//负标记第一位数码管显示“-”
// }
// else
// {
// ds18b20_zf=0xff;//正标记数码管不显示
}
ds18b20_ge=ds18b20_zs%100;
ds18b20_shi=ds18b20_ge/10; //十位转换
ds18b20_ge=(ds18b20_ge%10); //个位转换
// ds18b20_sfw=(ds18b20_xs*625)/1000; //使用这种方法计算小数位生成的目标文件比查表方式大了84个字节
ds18b20_sfw=(ds18b20_xs_tab[ds18b20_xs]);//小数的十分位部分部分查表取得并转换为ASCII码
}
void ds18b20_disp_temp() //显示温度
{
ledport=ds18b20_ledtab1[ds18b20_shi];
shi=0;
mDelay(2);
shi=1;
ledport=ds18b20_ledtab2[ds18b20_ge];
gew=0;
mDelay(2);
gew=1;
ledport=ds18b20_ledtab1[ds18b20_sfw];
sfw=0;
mDelay(2);
sfw=1;
}
void main()
{
ds18b20_reset();
while(1)
{
ds18b20_read_temp();
ds18b20_disp_temp();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -