📄 lj.c
字号:
#include <reg51.H>
#include <string.H>
sbit ds = P1^0;
int tempValue;
char code disp_scan[]={0x0e,0Xd,0x0b,0x07}; //显示扫描码
char code disp_data[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳LED数码管段码表“0”“1”“2”“3”“4”“5”“6”“7”“8”“9”
char code sd_data[]={'0','1','2','3','4','5','6','7','8','9'};
//延时函数, 对于11.0592MHz时钟, 例i=10,则大概延时10ms.
void delay(unsigned int i)
{
unsigned int j;
while(i--)
{
for(j = 0; j < 125; j++);
}
}
//初始化DS18B20
//让DS18B20一段相对长时间低电平, 然后一段相对非常短时间高电平, 即可启动
void dsInit()
{
//对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于为8us
unsigned int i;
ds = 0;
i = 100; //拉低约800us, 符合协议要求的480us以上
while(i>0) i--;
ds = 1; //产生一个上升沿, 进入等待应答状态
i = 4;
while(i>0) i--;
}
void dsWait()
{
unsigned int i;
while(ds);
while(~ds); //检测到应答脉冲
i = 4;
while(i > 0) i--;
}
//向DS18B20读取一位数据
//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,
//之后DS18B20则会输出持续一段时间的一位数据
bit readBit()
{
unsigned int i;
bit b;
ds = 0;
i++; //延时约8us, 符合协议要求至少保持1us
ds = 1;
i++; i++; //延时约16us, 符合协议要求的至少延时15us以上
b = ds;
i = 8;
while(i>0) i--; //延时约64us, 符合读时隙不低于60us要求
return b;
}
//读取一字节数据, 通过调用readBit()来实现
unsigned char readByte()
{
unsigned int i;
unsigned char j, dat;
dat = 0;
for(i=0; i<8; i++)
{
j = readBit();
//最先读出的是最低位数据
dat = (j << 7) | (dat >> 1);
}
return dat;
}
//向DS18B20写入一字节数据
void writeByte(unsigned char dat)
{
unsigned int i;
unsigned char j;
bit b;
for(j = 0; j < 8; j++)
{
b = dat & 0x01;
dat >>= 1;
//写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1
if(b)
{
ds = 0;
i++; i++; //拉低约16us, 符号要求15~60us内
ds = 1;
i = 8; while(i>0) i--; //延时约64us, 符合写时隙不低于60us要求
}
else //写"0", 将DQ拉低60us~120us
{
ds = 0;
i = 8; while(i>0) i--; //拉低约64us, 符号要求
ds = 1;
i++; i++; //整个写0时隙过程已经超过60us, 这里就不用像写1那样, 再延时64us了
}
}
}
//向DS18B20发送温度转换命令
void sendChangeCmd()
{
dsInit(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化
dsWait(); //等待DS18B20应答
delay(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
writeByte(0x44); //写入温度转换命令字 Convert T
}
//向DS18B20发送读取数据命令
void sendReadCmd()
{
dsInit();
dsWait();
delay(1);
writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
writeByte(0xbe); //写入读取数据令字 Read Scratchpad
}
//获取当前温度值
int getTmpValue()
{
unsigned int tmpvalue;
int value; //存放温度数值
float t;
unsigned char low, high;
sendReadCmd();
//连续读取两个字节数据
low = readByte();
high = readByte();
//将高低两个字节合成一个整形变量
//计算机中对于负数是利用补码来表示的
//若是负值, 读取出来的数值是用补码表示的, 可直接赋值给int型的value
tmpvalue = high;
tmpvalue <<= 8;
tmpvalue |= low;
value = tmpvalue;
t = value * 0.0625;
//将它放大100倍, 使显示时可显示小数点后两位, 并对小数点后第三进行4舍5入
//如t=11.0625, 进行计数后, 得到value = 1106, 即11.06 度
//如t=-11.0625, 进行计数后, 得到value = -1106, 即-11.06 度
value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
return value;
}
display(int num_data)
{
int r;
idata num_temp[4];
num_temp[0]=num_data/1000;//求显示数字的千位
num_temp[1]=(num_data-num_temp[0]*1000)/100;//求显示数字的百位
num_temp[2]=((num_data-num_temp[0]*1000)-num_temp[1]*100)/10;//求显示数字的十位
num_temp[3]=num_data%10; //求显示数字的个位
for(r=0;r<4;r++)
{
P2=disp_scan[r];
P0=disp_data[num_temp[r]];
delay(1);
}
}
// 初始化串口
void init_serial()
{
TMOD = 0x21; // 定时器1工作于8位自动重载模式, 用于产生波特率
TH1 = 0xF3; // 波特率9600
TL1 = 0xF3;
SCON = 0x50; // 设定串行口工作方式
PCON &= 0xef; // 波特率不倍增
TR1 = 1; // 启动定时器1
}
// 发送数据 //
void send_data(unsigned char *buf)
{
unsigned char len; // 保存数据长度
unsigned char ecc; // 保存校验字节
int i;
len = strlen(buf); // 计算要发送数据的长度
ecc = len; // 开始进行校验字节计算
// 发送数据长度
TI = 0;
SBUF = len; // 发送长度
while(!TI);
TI = 0;
//发送数据
for(i=0; i<len; i++)
{
ecc = ecc^(*buf); // 计算校验字节
SBUF = *buf; // 发送数据
buf++;
while(!TI);
TI = 0;
}
// 发送校验字节
//SBUF = ecc; // 发送校验字节
//while(!TI);
//TI = 0;
}
void main()
{
int i,r;
idata num_temp[5];
idata char sd[5];
init_serial();
while(1)
{
//启动温度转换
sendChangeCmd();
tempValue=getTmpValue();
num_temp[0]=tempValue/1000;//求显示数字的千位
num_temp[1]=(tempValue-num_temp[0]*1000)/100;//求显示数字的百位
num_temp[3]=((tempValue-num_temp[0]*1000)-num_temp[1]*100)/10;//求显示数字的十位
num_temp[4]=tempValue%10; //求显示数字的个位
for(r=0;r<5;r++)
{
if(r==2)
sd[r]='.';
else
sd[r]=sd_data[num_temp[r]];
}
for(i=0;i<10;i++)
{ display(tempValue);}
send_data(sd);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -