|
这是我们学校图书馆找到的,另外请高手帮个忙。怎样去修改下面这个程序既能测温又能测湿度?最好给个仿真图
这是例子:点击此处下载 ourdev_258709.rar(文件大小:2.73M) (原文件名:MCS-51 examples.rar)
//********************************************* C程序 *****************************************************************************//
//*MCU: AT89C51 //
//*MCU-crystal: 12M //
//*Version: 01 //
//*Last Updata: 2008-4-22 //
//*Author: //
//*Description: //
//DS18B20的读写程序,数据脚P3.4 //
//温度传感器汇编程序,采用器件默认的12位转化 //
//最大转化时间750微秒,显示温度-55到+125度,显示精度 //
//为0.1度,显示采用4位LED共阳显示测温值 //
//P1口为段码输入,P0~P3为位选 //
//***************WAVE-E6000/T**********************//
#include "reg52.h"
#define uchar unsigned char
#define uint unsigned int
#define Disdata P1 // 段码入口
sbit DQ=P3^4; // 温度输入口
uint temp; // variable of temperature 定义一个变量
uchar flag1; // 定义一个标志,标志温度是负还是正,1为负,0为正
sbit DIN=P1^7; // 小数点控制
#define discan P3 //扫描口
uchar h; // 定义变量
//位选位定义
sbit DEC=P3^0; // 小数
sbit POS=P3^1; // 个位
sbit TEN=P3^2; // 十位
sbit HUN=P3^3; // 百位,符号位
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
//共阳数码管段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "灭" "-"
unsigned char code table1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//带小数点的编码
//共阳数码管带小数点段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"
uchar data temp_data[2]={0x00,0x00};//读出温度暂放
uchar data Dis_play[5]={0x00,0x00,0x00,0x00,0x00};//显示单元数据,共4个数据和一个运算暂用
uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};
//小数部分对应十进制 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F"
uchar code scan_con[4]={0xfe,0xfd,0xfb,0xf7}; //列扫描控制字
/***************************************/
/* 延时子程序 */
/***************************************/
void delay(uint i) //delay
{
while(i--);
}
/************************************************/
/* 初始化ds18b2子函数* */
/************************************************/
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);
}
/*************************************************/
/* 读字节子函数 */
/*************************************************/
ReadOneChar(void)
{
uchar i = 0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1; // 数据右移一位
DQ = 1; // 给脉冲信号
if(DQ) // DQ为1
dat|=0x80; // 读出数据
delay(4); // 延时
}
return(dat);
}
/*************************************************/
/* 写字节子函数 */
/*************************************************/
WriteOneChar(unsigned char dat)
{
uchar i = 0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01; //写入一位数据
delay(5);
DQ = 1;
dat>>=1; //右移一位数据
}
}
/*************************************************/
/* DS18B20写命令函数 */
/*************************************************/
/*void tmpwritebyte(uchar dat) // write a byte to ds18b20
{ // 给温度传感器写一个字节
uint i;
uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb) //写入 1
{
DQ=0;
i++;i++;
DQ=1;
i=8;while(i>0)i--; // 适当延时
}
else //写入 0
{
DQ=0;
i=8;while(i>0)i--; // 适当延时
DQ=1;
i++;i++;
}
}
}*/
/******************************************/
/* 发送温度转换命令 */
/******************************************/
void tmpchange(void) // DS18B20 begin change
{
Init_DS18B20(); // 初始化DS18B20
delay(200); // 延时
WriteOneChar(0xcc); // 跳过序列号命令
WriteOneChar(0x44); // 发送温度转换命令
}
/******************************************/
/* 读出温度函数 */
/******************************************/
uint tmp() //get the temperature
{
// float tt;
Init_DS18B20(); // 初始化ds18b2子函数
delay(1);
WriteOneChar(0xcc); // 跳过ROM命令
WriteOneChar(0xbe); // 发送读取数据命令
temp_data[0]=ReadOneChar(); // 连续读两个字节数据
temp_data[1]=ReadOneChar();
temp=temp_data[1];
temp<<=8;
temp=temp|temp_data[0]; // 两字节合成一个整型变量。
// tt=temp*0.0625; // 得到真实十进制温度值,因为DS18B20
// 可以精确到0.0625度,所以读回数据的最低位代表的是
// 0.0625度。
// temp=tt*10+0.5; // 放大十倍,这样做的目的将小数点后第一位
// 也转换为可显示数字,同时进行一个四舍五入操作。
return temp; // 返回温度值
}
/******************************************/
/* 读出序列号函数 */
/******************************************/
/*void readrom() // read the serial 读取温度传感器的序列号
{ // 本程序中没有用到此函数
uchar sn1,sn2;
Init_DS18B20(); // DS18B20初始化
delay(1);
WriteOneChar(0x33); // Read ROM
sn1=ReadOneChar(); // 8位系列编码
sn2=ReadOneChar(); // 8位CRC码
}*/
/******************************************/
/* 温度数据显示处理函数 */
/******************************************/
void tem_deal(uint tem)
{
/*************温度数据处理*****************/
if(tem>6348) // 温度值正负判断
{tem=65536-tem;flag1=1;} // 负温度求补码,标志位置1
Dis_play[4]=tem&0x0f; // 取小数部分的值
Dis_play[0]=ditab[Dis_play[4]]; // 存入小数部分显示值
Dis_play[4]=tem>>4; // 取中间八位,即整数部分的值
Dis_play[3]=Dis_play[4]/100; // 取百位数据暂存
Dis_play[1]=Dis_play[4]%100; // 取后两位数据暂存
Dis_play[2]=Dis_play[1]/10; // 取十位数据暂存
Dis_play[1]=Dis_play[1]%10; // 取个位数据暂存
if(!Dis_play[3]) // 最高位为0都不显示
{
Dis_play[3]=0x0a; // 先判断百位是否为0
if(!Dis_play[2])
{
Dis_play[2]=0x0a; // 再判断十位是否为0
}
}
if(flag1)
{
Dis_play[3]=0x0b; // 为负数时,最高位显示 "-"
}
}
/******************温度数据显示********************/
void display()
{
char k;
for(k=0;k<4;k++) //4位LED扫描控制
{
Disdata=table[Dis_play[k]]; //数据显示
if (k==1){DIN=0;} //小数点显示
discan=scan_con[k]; //位选
delay(90); //延时
discan=0xff;
}
}
/******************************************/
/* 主函数 */
/******************************************/
void main()
{
Disdata=0xff; //端口初始化
P3=0xff;
//开机显示"888.8";这段程序可以不要.
for(h=0; h<4; h++)
{
Dis_play[h]=8;
}
for(h=0; h<50; h++)
{
display(); //显示数据
delay(1000); //延时
}
//温度显示
do
{
tmpchange(); //温度转换
tem_deal(tmp()); //显示温度值
display();
}
while(1);
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
|