这是我做的18b20温度显示,做了一个上位机,晒一下,大家学习交流一下。下面是下位机的源程序:
/*****************************************************************
*程序名称:18b20数码管显示温度
*程序功能: 显示实时温度监测,带上位机
*端口定义: DQ -P1^7
*编写:muye414
*修改:
*修改何处:
*****************************************************************/
#include <reg52.h>
#include <string.h>
#include <stdio.h>
#define XTAL 11059200 // CUP 晶振频率
#define baudrate 9600 // 通信波特率
#define uchar unsigned char
#define uint unsigned int
#define duan P0 //数码管显示的段选
#define wei P2 //数码管显示的位选
/*********************函数声明************************/
void Send_Byte(uchar);
void Send_Str(char);
void send_char(void);
/*********************函数声明结束********************/
sbit DQ = P1^7; // 定义DS18B20端口DQ
sbit BEEP = P3^7; //蜂鸣器端口定义
bit sendtempflag=0;
uchar presence ;
float f_temp;
uint temp;
uchar code LEDData1[ ]={0x40,0x79,0x24,0x30,0x19,0x12,
0x02,0x78,0x00,0x10,0xff};//带小数点的共阳数码管"0-9"段码数字
uchar code LEDData[ ]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,
0x82,0xF8,0x80,0x90,0xff};//共阳数码管段码
uchar code ditab[16] = {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,
0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};//温度的小数位
uchar data temp_data[2] = {0x00,0x00};
uchar data display[5] ={0x00,0x00,0x00,0x00,0x00};
void beep();
bit flash=0; // 显示开关标记
bit flag_zf=0; // 正负温度标志
/**********************************************************/
void Delay(unsigned int num)// 延时函数
{
while( --num );
}
/*********************************************************
********************以下为1820相关函数*******************
/*********************************************************/
uchar Init_DS18B20(void) // 初始化ds1820
{
DQ = 1; // DQ复位
Delay(8); // 稍做延时
DQ = 0; // 单片机将DQ拉低
Delay(90); // 精确延时 大于 480us
DQ = 1; // 拉高总线
Delay(8);
presence = DQ; // 如果=0则初始化成功 =1则初始化失败
Delay(100);
DQ = 1;
return(presence); // 返回信号,0=presence,1= no presence
}
/**********************************************************/
uchar ReadOneChar(void) // 读一个字节
{
unsigned char i = 0;
unsigned char dat = 0;
for (i = 8; i > 0; i--)
{
DQ = 0; // 给脉冲信号
dat >>= 1;
DQ = 1; // 给脉冲信号
if(DQ)
dat |= 0x80;
Delay(4);
}
return (dat);
}
/**********************************************************/
void WriteOneChar(unsigned char dat)// 写一个字节
{
unsigned char i = 0;
for (i = 8; i > 0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delay(5);
DQ = 1;
dat>>=1;
}
}
/*********************************************************/
Read_Temperature(void)// 读取温度
{
uchar a,b;
Init_DS18B20();
if(presence==1)
{
beep();Delay(25000);
flash=1;
} // DS18B20不正常,蜂鸣器报警
else
{
flash=0;
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0xBE); // 读取温度寄存器
a = ReadOneChar(); // 温度低8位
b = ReadOneChar(); // 温度高8位
temp_data[0]=a;
temp_data[1]=b;
temp=b;
temp<<=8;
temp=temp|a;
f_temp=temp*0.0625;
temp=f_temp*10+0.5;//后面小数取一位,并四舍五入
f_temp=f_temp+0.05;
return temp;
}
}
/*********************************************************/
void Disp_Temperature()// 显示温度
{
unsigned char n=0;
if(temp_data[1]>7) //当温度高八位中的高五位全为O
{ flag_zf=1; // 所测温度为负时,要进行转换
temp_data[1]=!( temp_data[1]);
temp_data[0]=!( temp_data[0]);
temp_data[0]= temp_data[0]+1;
if(temp_data[0]==0)
{ temp_data[1]= temp_data[1]+1;}
}
else
{flag_zf=0;} //判断测得的温度数据是正还是负,如果为正,不做任何处理
display[4]=temp_data[0]&0x0f;
display[0]=ditab[display[4]]; // 查表得小数位的值
display[4]=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x0f)<<4);
display[3]=display[4]/100;//百位
display[1]=display[4]%100;//存储十位和个位
display[2]=display[1]/10;//十位
display[1]=display[1]%10;//个位
if(flag_zf==1)
{duan=0xbf;//"-"
wei=0x02;
Delay(100);} //温度为负数时第二个数码管显示负号
if(!display[3]) // 高位为0,不显示
{
display[3]=0x0a;
if(!display[2]) // 次高位为0,不显示
display[2]=0x0a;
}
duan = 0xc6; // 显示 C
wei = 0xfe; // 位选线为P2.7口,LED为共阳极显示,当位选线为低电平时选通
Delay(100);
duan = 0x9c; // 显示 °
wei = 0xfd; // 选中P2.6口
Delay(100);
duan = 0x7F; //在个位上显示小数点"."
wei = 0xf7; //位选
Delay(100);
duan =LEDData[display[0]] ; // 显示小数位
wei = 0xfb; //p2.5
Delay(100);
duan =LEDData[display[1]]; // 显示个位
wei = 0xf7;
Delay(100);
duan =LEDData[display[2]]; // 显示十位
wei = 0xef;
Delay(100);
duan =LEDData[display[3]]; // 显示百位
wei = 0xdf;
Delay(100);
wei = 0xff; // 关闭显示
}
/*********************************************************
******************1820相关函数到此结束*******************
/*********************************************************/
void beep(void)
{
unsigned char i;
for (i=0;i<100;i++)
{
Delay(120);
BEEP=!BEEP; // BEEP取反
}
BEEP=1; // 关闭蜂鸣器
}
/*********************************************************
********************以下为初始化函数*********************
/*********************************************************/
void Init(void)
{
TMOD = 0x20; // 定时器1工作于8位自动重载模式, 用于产生波特率
// TH1=(uchar)(256 - (XTAL / (32L * 12L * baudrate)));
// TL1=(uchar)(256 - (XTAL / (32L * 12L * baudrate))); // 定时器1赋初值
TH1=0xfd; //Baud:9600 fosc="11.0592"MHz
TL1=0xfd;
SCON = 0x50; // 设定串行口工作方式- 模式 1, 8-bit UART, 使能接收
//串口设置为方式1,REN=1,允许接收
PCON &= 0x00; // 波特率不倍增
// ES=1; //打开串口中断
TR1 = 1; // 启动定时器1
// EA = 1; // "中断总允许"
// IE = 0x00; // 禁止任何中断
}
/*********************************************************
********************以下为串口相关函数*******************
/*********************************************************/
void sendchar(char *ch)
{
do{
SBUF=*ch++;//发送数据
while(!TI);//等待发送完毕,标志置1
TI=0; //标志清零
}
while(*ch);//循环直至发送完毕
}
/*********************************************************
*************************主函数**************************
/*********************************************************/
void main()
{
uchar buff[4];
Init();
while(1)
{
Read_Temperature(); // 读取温度
if (flash==0)
{
sprintf(buff,"%f",f_temp);//将浮点温度格式化为字符型
Disp_Temperature(); // 显示温度
sendchar(buff); // 传送采集的温度
}
else
{
wei = 0x00 ; // DS18B20不正常,关闭显示
}
}
}
/******************************************************************/
下面是上位机的截图,上位机简单美化了一下,其中用到了Edit类、按键类等。
(原文件名:vc1.jpg)
(原文件名:VC3.jpg)
实拍图
(原文件名:IMG0698A.jpg)
上位机程序共享出来
上位机源程序ourdev_618148AOGWI2.rar(文件大小:4.00M) (原文件名:Temper.rar) |
|
|
|