标题:
初学8051:DS18B20,给初学者
[打印本页]
作者:
lcg111111
时间:
2015-11-30 21:38
标题:
初学8051:DS18B20,给初学者
初学8051,把买的的学习板带的程序给修改了、数码管显示,串口上位机显示
STC89C52RC
压缩包内有 下位机C51程序,proteus仿真,C#写的简单的串口。
在冰柜里测了低温,在proteus里仿真了100°C以上的高温,都能正确显示。在腋窝里测了下体温,用了好长时间才稳定在36.5°C 。
DS18B20.rar
2015-11-30 21:31 上传
点击文件名下载附件
下载积分: 黑币 -5
239.42 KB, 下载次数: 22, 下载积分: 黑币 -5
作者:
admin
时间:
2015-12-2 00:38
楼主的程序:
/*****************************************************************
*程序名称:DS18B20 4位数码管 上位机
*程序功能:读写DS18B20,数码管显示温度值,上位机显示。
*开发工具:谷雨电子 多功能51开发板
*MCU型号:STC89C52RC
*时钟频率:11.0592MHZ
*程序作者:LCG
*版权说明:
*****************************************************************/
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
//定义DS18B20通信端口,修改硬件时要修改的部分
sbit DQ = P2 ^ 0;
//0-9的8位共阳数码管位码 其中负号0xbf
uchar const LEDNumber[] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf };
//0-9的8位共阳数码管位码 带小数点
uchar const LEDNumberDot[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//LCG
uchar const LCGData[]={0xC7,0xC6,0xC2};
//温度是否是负
uchar tempSign;
//传感器的温度的高位低位
uchar tH=0x00;tL=0x00;
//当前温度
float tt=0;//临时
int CurrentT=0;
int t=0;//临时
//数位
uchar bw,sw,gw,sfw;//百位,十位,个位,十分位
//***********************以下为函数声明部分*****************
void DispLCG(int pos, int Data);
void LCGDisp(void);
void delay(uint us);
void Init_DS18B20(void);
uchar ReadOneChar(void);
void WriteOneChar(uchar dat);
void ReadTemperature(void);
void LedDispDig(int Pos, int Dig, uchar isDot);
void DisplayTemp(void);
void init_serial(void);
void Tranfer(char Data);
//char Temp_lower, Temp_upper; //温度的上限和下限
//=================================================================
// 函数名称 :void delay (uint us)
// 函数功能 :延时
// 入口参数 :us 延时时间的长短
// 出口参数 :无
//=================================================================
void delay(uint us)
{
//此函数精确计算[12MHz晶振]:18+6*(t-1)=延时时间(us)
while (us--);
}
//=================================================================
// 函数名称 :void Init_DS18B20(void)
// 函数功能 :DS18B20初始化函数
// 入口参数 :无
// 出口参数 :无
//=================================================================
void Init_DS18B20(void)
{
uchar x = 0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay(14);
x = DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(20);
}
//=================================================================
// 函数名称 :uchar ReadOneChar(void)
// 函数功能 :DS18B20读字节函数
// 入口参数 :无
// 出口参数 :dat 读回的字节数据
//=================================================================
uchar ReadOneChar(void)
{
uchar i = 0;
uchar dat = 0;
for (i = 0; i < 8; i++)
{
DQ = 0; // 给脉冲信号
dat >>= 1;
DQ = 1; // 给脉冲信号
if (DQ)
dat |= 0x80;
delay(4);
}
return dat;
}
//=================================================================
// 函数名称 :void WriteOneChar(uchar dat)
// 函数功能 :DS18B20写字节函数
// 入口参数 :dat 要写入的字节数据
// 出口参数 :无
//=================================================================
void WriteOneChar(uchar dat)
{
uchar i = 0;
for (i = 0; i <8; i++)
{
DQ = 0;
DQ = dat & 0x01;
delay(5);
DQ = 1;
dat >>= 1;
}
}
//=================================================================
// 函数名称 :float ReadTemperature(void)
// 函数功能 :DS18B20读取温度值函数
// 入口参数 :无
// 出口参数 :读取的温度值,为float型的数据
//=================================================================
void ReadTemperature(void)
{
Init_DS18B20();
WriteOneChar(0xcc); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xcc); //跳过读序号列号的操作
WriteOneChar(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
tL = ReadOneChar();
tH = ReadOneChar();
//合并为字
t = tH;
t <<= 8;
t = t | tL;
if((tH & 0xf8)==0xf8) //负温度
{
tt=(~t+1)*0.0625;
tempSign = 1;
}
else //正温度
{
tt=t*0.0625;
tempSign=0;
}
CurrentT=(int)(tt*10); //tt*10保留一位小数并对float型强制取整
bw=CurrentT/1000; //百位
sw=CurrentT%1000/100; //十位
gw=CurrentT%100/10; //个位
sfw=CurrentT%10; //小数十分位
}
//=================================================================
// 函数名称 :void DispLCG(int pos, int Data)
// 函数功能 :显示LCG
// 入口参数 :Pos 数码管的位置
// Data 要显示的数字
// 出口参数 :无
//=================================================================
void DispLCG(int Pos, int Data)
{
P0 = LCGData[Data];
P1 |= 0x0f;
P1 &= 0xff - (0x01 << Pos);
}
void LCGDisp(void)
{
int i,j;
for(j=0;j<500;j++) //大约2秒
{
for(i=0;i<3;++i)
{
DispLCG(i,i);
delay(300);
}
}
}
//=================================================================
// 函数名称 :void LedDispDig(int Pos,int Dig)
// 函数功能 :在指定的数码管上显示数字
// 入口参数 :Pos 数码管的位置
// Dig 要显示的数字
// isDot 是否是个位数,个位数带小数点
// 出口参数 :无
//=================================================================
void LedDispDig(int Pos, int Dig, uchar isDot)
{
if (isDot==1)
{
P0=LEDNumberDot[Dig]; //带小数点
}
else
{
P0 = LEDNumber[Dig]; //不带小数点
}
P1 |= 0x0f;
P1 &= 0xff - (0x01 << Pos);
}
//=================================================================
// 函数名称 :void scan(float Temp)
// 函数功能 :数码管动态扫描显示温度
// 入口参数 :Temp 数码管上要显示的温度值
// 出口参数 :无
//=================================================================
void DisplayTemp(void)
{
//针对4位数码管
if(tempSign==1) //负温度,不会超过 -100,百位总是0,所以只判断十位来确定在哪个位显示负号
{
if(sw==0)
{
LedDispDig(1,10,0);//十位显示负号,LEDNumber中第11个元素
delay(300);
LedDispDig(2,gw,1); //个位,1显示小数点
delay(300);
LedDispDig(3,sfw,0); //小数十分位
}
else
{
LedDispDig(0,10,0);//百位显示负号,LEDNumber中第11个元素
delay(300);
LedDispDig(1,sw,0); //十位
delay(300);
LedDispDig(2,gw,1); //个位,1显示小数点
delay(300);
LedDispDig(3,sfw,0); //小数十分位
}
}
else //正温度
{
if(bw!=0)
{
LedDispDig(0,bw,0); //百位
delay(300);
LedDispDig(1,sw,0); //十位
delay(300);
}
else if(sw!=0) //十位
{
LedDispDig(1,sw,0);
delay(300);
}
LedDispDig(2,gw,1); //个位,1显示小数点
delay(300);
LedDispDig(3,sfw,0); //小数十分位
}
//P1 |= 0x0f; //显示小数点
//P1 &= 0xfb;
//P0=0x7f;
//delay(300);
}
//====================================================================================
//函数名称:void init_serial(void)
//函数功能:初始化串口
//入口参数:无
//出口参数:无
//====================================================================================
void init_serial(void)
{
TMOD = 0x22; //定时器T1使用工作方式2
TH1 = 250; //设置初值
TL1 = 250;
TR1 = 1; //开始计时
PCON = 0x80; //SMOD=1;
SCON = 0x50; //工作方式1,波特率9600bit/s,允许接收
TI = 1;
}
//====================================================================================
//函数名称:void Tranfer(char Data)
//函数功能:发送数据程序
//入口参数:Data 要发送的数据
//出口参数:无
//====================================================================================
void Tranfer(char Data)
{
while (TI == 0);
SBUF = Data;
TI = 0;
}
//====================================================================================
//函数名称:int main(void)
//函数功能:主函数,主要用于上位机发送
//入口参数:无
//出口参数:无
//====================================================================================
int main(void)
{
float Temp;
//显示LCG
LCGDisp();
tempSign = 0;
IT1 = 1; //负跳变方式产生中断
EX1 = 1; //开外部中断1
EA = 1; //开总中断
Init_DS18B20();
init_serial();
while (1)
{
ReadTemperature();
DisplayTemp();
Tranfer('a');
//针对4位数码管
if(tempSign==1) //负温度不会超过 -100,百位总是0
{
Tranfer('-');//发送负号
if(sw==0) //十位为零,不发送百位和十位
{
Tranfer(gw+0x30); //个位
Tranfer(sfw+0x30); //小数十分位
}
else
{
Tranfer(sw+0x30); //十位
Tranfer(gw+0x30); //个位
Tranfer(sfw+0x30); //小数十分位
}
}
else //第一位百位
{
if(bw!=0)
{
Tranfer(bw+0x30); //百位
Tranfer(sw+0x30); //十位
}
else if(sw!=0) Tranfer(sw+0x30); //十位
Tranfer(gw+0x30); //个位
Tranfer(sfw+0x30); //小数十分位
}
Tranfer('b');
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1