#include "reg52.h"
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//温度ds18b20 的引脚
sbit ds=P3^0;
//湿度 模数转换adc0809 的引脚
sbit ST=P3^1; //定义START引脚
sbit OE=P3^3; //定义OE引脚
sbit EOC=P3^2; //定义EOC引脚
sbit CLK=P3^4; //定义CLOCK引脚
//显示数据 lcd1602 的引脚
sbit rs = P3^7;
sbit rw = P3^6;
sbit eq = P3^5;
uchar lcd_temperature[]="tem C"; //温度数组
uchar lcd_humidity[] = "hum %"; //湿度数组
//温度定义变量
uint shu;//测量到的温度的整数部分
uchar xiaoshu1;//小数第一位
uchar xiaoshu2;//小数第一位
bit fg; //温度正负标志
//湿度定义变量
int getdata,temp; //getdata-- adc0809 输出的数据,temp--转换为湿度的数据
void dsInit()
{//对于11.0592MHz时钟, unsigned int型的i, 作一个i++操作的时间大于?us
ds = 0;
delay1(100); //拉低约800us, 符合协议要求的480us以上
ds = 1; //产生一个上升沿, 进入等待应答状态
delay1(1);
}
void dsWait()
{
while(ds);
while(~ds); //检测到应答脉冲
delay1(1);
}
//向DS18B20读取一位数据
//读一位, 让DS18B20一小周期低电平, 然后两小周期高电平,
//之后DS18B20则会输出持续一段时间的一位数据
bit readBit()
{
uint i;
bit b;
ds = 0;
i++; //延时约8us, 符合协议要求至少保持1us
ds = 1;
delay1(1); //延时约16us, 符合协议要求的至少延时15us以上
b = ds;
delay1(7); //延时约64us, 符合读时隙不低于60us要求
return b;
}
//读取一字节数据, 通过调用readBit()来实现
uchar readByte()
{
uchar i;
uchar j, dat;
dat = 0;
for(i=0; i<8; i++)
{
j = readBit();//最先读出的是最低位数据
dat = (j << 7) | (dat >> 1);
}
return dat;
}
//向DS18B20写入一字节数据
void writeByte(uchar dat)
{
uchar j;
uchar b;
for(j = 0; j < 8; j++)
{
b = dat & 0x01;
dat >>= 1;//写"1", 将DQ拉低15us后, 在15us~60us内将DQ拉高, 即完成写1
if(b)
{
ds = 0;
delay1(1); // 符号要求15~60us内
ds = 1;
delay1(7); //符合写时隙不低于60us要求
}
else //写"0", 将DQ拉低60us~120us
ds = 0;
delay1(7);
ds = 1;
delay1(1);
}
}
//向DS18B20发送温度转换命令
void sendChangeCmd()
{
dsInit(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化
dsWait(); //等待DS18B20应答
delay1(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
writeByte(0x44); //写入温度转换命令字 Convert T
}
//向DS18B20发送读取数据命令
void sendReadCmd()
{
dsInit();
dsWait();
delay1(1);
writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
writeByte(0xbe); //写入读取数据令字 Read Scratchpad
}
//获取当前温度值并显示温度
void getTmpValue()
{
uchar templ,temph,i;
uchar tem;
sendReadCmd();
templ = readByte(); //读取低位温度
temph = readByte(); //读取高位温度
if(temph > 0x7f) //最高位为1时温度是负
{ //补码转换,取反加一
tem = ~((temph*256)|templ)+1;
templ = tem & 0x00ff;
temph = tem & 0xff00;
fg=0; //读取温度为负时fg=0
}
else
fg=1;
shu = templ/16+(temph&0x07)*16; //整数部分
xiaoshu1 = (templ&0x0f)*10/16; //小数第一位
xiaoshu2 = (templ&0x0f)*100/16%10;//小数第二位
if(fg==1) //温度为正时显示的数据
{
lcd_temperature[6]=' '; //输出十位数
}
else //温度为负时显示的数据
{
lcd_temperature[6]='-';
} //负号
lcd_temperature[7] = 0x30|(shu/10);//计数的十位显示
lcd_temperature[8] = 0x30|(shu%10); //计数的个位显示
lcd_temperature[9] = '.'; //计数的小数点显示
lcd_temperature[10] = 0x30|xiaoshu1;//计数的小数点后一位显示
lcd_temperature[11] = 0x30|xiaoshu2;//计数的小数点后二位显示
lcd_wcmd(0x80);
for(i=0; i<14; i++)//显示字母
{
lcd_wdat(lcd_temperature[i]);
}
}
void
timer0_init() //中断服务程序初始化
{
TCON = 0x10;
TMOD=0x01;
TH0=(65536-20)/256;
TL0=(65536-20)%256;
EA=1;
ET0=1;
TR0=1;
}
void gethumidity()
{
uchar i;
OE=0; //刚开始禁止将转换结果输出
ST=0;
ST=1;
ST=0; //启动AD转换开始
while(EOC==0); //等待转换结束
OE=1; //允许转换结果输出
getdata=P2; //将转换结果赋值给变量getdata
OE=0; //禁止转换结果输出
temp=getdata*1.0/255*100; //将得到的数据进行处理
if(temp/100 == 0)
lcd_humidity[6]=' '; //取得百位数
else
lcd_humidity[6]=(temp/100)|0x30; //取得百位数
lcd_humidity[7]=(temp/10%10)|0x30; //取得十位数
lcd_humidity[8]=(temp%10)|0x30; //取得个位数
lcd_wcmd(0x80+0x40);
for(i=0; i<11; i++)//显示字母
{
lcd_wdat(lcd_humidity[i]);
}
}
void timer0() interrupt 1 //给AD0809提供25KHZ的时钟脉冲
{
TH0=(65536-20)/256;
TL0=(65536-20)%256;
CLK=~CLK;
}
//测试LCD忙状态 返回result
bit lcd_bz()
{
bit result;
rs = 0;
rw = 1;
eq = 1;
_nop_(); _nop_(); _nop_(); _nop_();
result = (bit)(P1&0x80);
eq = 0;
return result;
}
//写指令数据到LCD
void lcd_wcmd(uchar cmd)
{
rs = 0;
rw = 0;
eq = 1;
P1 = cmd;
delay(1);
eq = 0;
}
//写入显示数据到LCD
void lcd_wdat(uchar dat)
{
while(lcd_bz());
rs = 1;
rw = 0;
eq = 1;
P1 = dat;
delay(10);
eq = 0;
}
//LCD初始化
void lcd_init()
{
lcd_wcmd(0x38);//显示模式设置,5*7点阵,8位数据接口
lcd_wcmd(0x0c);//显示开及光标设置不显示
lcd_wcmd(0x06);//显示光标移动设置
lcd_wcmd(0x01);//显示清屏
}
void main()
{
lcd_init(); //LCD1602初始化
timer0_init(); //中断服务程序初始化
while(1)
{
//启动温度转换
EA = 0; //总中断影响温度显示
sendChangeCmd();
getTmpValue();
EA = 1;
//启动湿度转换
gethumidity();
}
}
帮忙keil运行这个程序看看啊,我找不到错误在哪,急死了,摆脱哪位高手了!!!
一周热门 更多>