📄 18b20.txt
字号:
#include<reg52.h>
#include<intrins.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define LCM_Data P2
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
sbit LCM_RW = P1^1;
sbit LCM_RS = P1^2;
sbit LCM_E = P1^0;
sbit DQ=P1^7;
bit Bshow=0;
uint TimeCount=0;
uint SampleCount=0;
uint Average=0;
uint Tempture[5]={0,0,0,0,0};
void delay(uint del)
{del=del*1.5;
while(del--);
}
Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay(50); //稍做延时
DQ = 0; //单片机将DQ拉低
delay(480); //精确延时 大于 480us
DQ = 1; //拉高总线
delay(85);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(120);
}
//读一个字节
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(25);
}
return(dat);
}
//写一个字节
WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(30);
DQ = 1;
dat>>=1;
}
//delay(4);
}
//读取温度
ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
uchar tt=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar();
b=ReadOneChar();
a=a&0xf0;
a=a>>4;
b=b&0x0f;
b=b<<4;
t=a+b;
return(t);
}
void Filter()
{uchar i,j;
uchar Temp;
for(i=0;i<4;i++)
{for(j=0;j<4;j++)
if(Tempture[j]>Tempture[j+1])
{Temp=Tempture[j+1];
Tempture[j+1]=Tempture[j];
Tempture[j]=Tempture[j+1];
}
}
Average=(Tempture[1]+Tempture[2]+Tempture[3])/3;
}
void lcd_e_toggle(void)
{
LCM_E = 1;
delay(10);
LCM_E = 0;
}
void check_busy(void)
{
bit result;
do{
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 1;
LCM_Data=0xff;
result = (bit)(LCM_Data&0x80);
LCM_E = 0;
}while (result == 1);
delay(1000);
}
// 循环检测LCD忙标志(BF),直到其值为0,方可执行下一指令
void lcd_wait_until_finish(void)
{
LCM_RW = 1; // RW置1,状态为读
LCM_RS = 0; // RS置0,读状态时RS需置低电平
LCM_E = 1; // E 置1,读取信息
check_busy();
LCM_E = 0; // E重置为0
}
// 公共函数
// 向LCD写命令字
void lcd_command(uchar cmd)
{
LCM_RW = 0; // RW置0,状态为写
LCM_RS = 0; // RS置0,写入命令字
LCM_Data = cmd; // 将命令字cmd送入LCD的数据端口
lcd_e_toggle(); // 产生使能脉冲,在下降沿开始执行,将命令字读入
lcd_wait_until_finish(); // 等待执行完毕
}
// 设置显示位置( 即写入显示地址),x,y均从0开始
void lcd_goto_xy(uchar x, uchar y)
{
uchar p; // p为字符显示位置,即DDRAM中的地址
if (y==0)
{
p = 0x00 + x; // (0,0)显示位置为0x00
}
else
{
p = 0x40 + x; // (0,1)显示位置为0x40
}
lcd_command(p + 0x80); // 写入显示地址时DB7须为高电平,加0x80
}
// 写字符(传入的参数实际为所需显示字符的地址,即液晶字符产生器中字符的地址)
void lcd_putc(uchar c)
{
LCM_RW = 0; // RW置0,状态为写
LCM_RS = 1; // RS置1,写入数据
LCM_Data = c; // 将字符c(实际上是字符的地址)送入LCD数据端口
lcd_e_toggle(); // 使能脉冲
lcd_wait_until_finish(); // 等待完成
}
// 指定位置写字符
/*
void lcd_xy_putc(uchar x, uchar y, uchar c)
{
lcd_goto_xy(x,y);
lcd_putc(c);
}
*/
// 写字符串
void lcd_puts(uchar *s)
{
while(*s)
{
lcd_putc(*s);
s++;
}
}
// 指定位置写字符串
/*
void lcd_xy_puts(uchar x, uchar y, uchar *s)
{
lcd_goto_xy(x, y);
lcd_puts(s);
}
*/
// LCD初始化
void lcd_init(void)
{
delay(1000); // 上电后适当延时
lcd_command(0x38); // 设为8位接口模式,显示2行字符
lcd_command(0x06); // 写入新数据后光标右移
lcd_command(0x0c); // 显示功能开,不显示光标
lcd_command(0x01); // 清屏
}
void itoa ( uchar *string,uint integer) //整数转换成字符串
{ int i,j=0,bit0;
uchar temp[5];
for(i=0;integer>=1;i++,integer=integer/10)
{
bit0=integer%10;
temp[i]=bit0+48;
}
i--;
for(;i>=0;i--,j++)
{
string[j]=temp[i];
}
string[j]='\0';
}
void main(void)
{
uint cnt = 0;
uchar p[4];
TMOD = 0x01;
TH0 = 0x4C;
TL0 = 0x00;
EA=1;
ET0=1;
TR0=1;
lcd_init() ;
while(1)
{Bshow=0;
lcd_goto_xy(0,0); // 字符位置:(0,0)
lcd_puts("Tempture:");
if(Bshow)
{itoa(p,Average);
lcd_goto_xy(9,0);
lcd_puts(p);
Bshow=0;
}
}
}
void timer0() interrupt 1//断采样,0.1S采样一次
{ TH0 = 0x4C;
TL0 = 0x00;
TimeCount++;
if(TimeCount>=10)//0.5s 采样一次
{TR0=0;
TimeCount=0;
Tempture[SampleCount++]=ReadTemperature();
if(SampleCount>=5)
{SampleCount=0;
Filter();
Bshow=1;
}
TR0=1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -