寻求一个用12864液晶显示DS18B20温度传感器的C程序。

不要从网上别人那拷贝,网上的我都看过了。请高手帮助
2024-12-28 00:15:59
推荐回答(3个)
回答1:

//并行连接,PSB引脚接电源正
#include
#include
#define uint unsigned int
#define uchar unsigned char

sbit rs=P2^0; /*数据\指令 选择*/
sbit rw=P2^1; /*读\写 选择*/
sbit e=P2^2; /*读\写使能*/
sbit ds=P3^2; //18B20脚

uint temp;
float ftemp;
uchar code table[]="0123456789.d";

void writecom(uchar com);
void writedat(uchar dat);
void initinal(void);

delay0(int k) //把你的延时函数改为以毫秒计时的一个延时函数,但是一个“非标准的”毫秒
{
int i,j;
for(i=k;i>0;i--) //i=xms即延时约xms毫秒
for(j=110;j>0;j--);
}

void dsreset() // ds18b20初始化函数
{
uint i;
ds=0; //拉低总线开始复位
i=103;
while(i>0)i--;
ds=1;//释放总线
i=4;
while(i>0)i--;
// 省去了等待芯片返回应答的过程 。。。。。。
}
bit readbit(void) //ds18b20读取一个二进制位,参照时序图
{
uint i;
bit dat;
ds=0;i++;
ds=1;i++,i++;
dat=ds;
i=8;while(i>0)i--;
return(dat);
}
uchar tempread(void) //ds18b20读取一个字节的数据
{
uchar i,j,dat;
dat=0;
for(i=0;i<8;i++)
{
j=readbit();
dat=(j<<7)|(dat>>1); //
}
return(dat);
}
void tempwrite(uchar dat) //ds18b20写入字节数据
{
uint i;uchar j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if(testb==1) // 写1
{
ds=0; // 拉低总线以开始一个写时序
i++;i++;
ds=1; // 释放总线
i=8;while(i>0)i--;
}
else // 写0
{
ds=0;
i=8;while(i>0)i--;
ds=1;
i++;i++;
}
}
}
void tempchang(void) //
{
dsreset();
delay0(1);
tempwrite(0xcc); //
tempwrite(0x44); //
}
uint gettemp() //
{
uchar a,b;
dsreset();
delay0(1);
tempwrite(0xcc); //
tempwrite(0xbe); //
a=tempread(); //
b=tempread(); //
temp=b;
temp<<=8; //////
temp=temp|a;
ftemp=temp*0.0625; //
temp=ftemp*10+0.5; //
ftemp=ftemp+0.05; //
return temp; //
}

//12MHZ晶振 延时50微秒
void delay50us(uint t)
{
uchar j;
for(;t>0;t--)
for(j=19;j>0;j--);
}
/////////////////////////////////////////////////////////////////////////
//主函数
void main()
{
initinal();

while(1)
{
uint a,b,c,d;
tempchang();
a=gettemp();
b=a/100;
c=a%100/10;
d=a%100%10;
writecom(0x83);
writedat(table[b]);
delay50us(1);
writedat(table[c]);
delay50us(1);
writedat(table[10]);
delay50us(1);
writedat(table[d]);
delay50us(1);
writedat(table[11]);
delay50us(4);
writecom(0x83);
}
}
//////////////////////////////////////////////////////////////////////////
//12864写命令
void writecom(uchar com)
{
rw=0;
rs=0;
delay50us(1);
P0=com;
e=1;
delay50us(10);
e=0;
delay50us(10);
}

//12864写数据
void writedat(uchar dat)
{
rw=0;
rs=1;
delay50us(1);
P0=dat;
e=1;
delay50us(10);
e=0;
delay50us(10);
}

//12864初始化
void initinal(void)
{
delay50us(2);
writecom(0x30);
delay50us(4);
writecom(0x30);
delay50us(4);
writecom(0x0f);
delay50us(4);
writecom(0x01);
delay50us(240);
writecom(0x06);
delay50us(10);
}

回答2:

#include
#define uchar unsigned char
#define uint unsigned int
uchar shi,fen,miao,date,month,year,num,s1num,s4num,count;
sbit lcd_rs=P3^5;
sbit lcd_en=P3^4;
sbit s1=P3^0;
sbit s2=P3^1;
sbit s3=P3^2;
sbit s4=P3^3; //按键定义
sbit DQ =P2^2; //定义通信端口
//bit flag,flag1;
uchar code table1[]=" 2010-08-21 SAT";
uchar code table2[]=" 00:00:00 C"; //LM032初始化字符表

void delay(uint z)//ms延时函数
{
uint x,y;
for(x=z; x>0; x--)
for(y=110;y>0;y--);
}

void write_com(uchar com)//向LM032液晶写命令函数
{
lcd_rs=0;
lcd_en=0;
P1=com;
delay(1);
lcd_en=1;
delay(1);
lcd_en=0;
}

void write_dat(uchar dat)//向LM032液晶写入数据
{
lcd_rs=1;
lcd_en=0;
P1=dat;
delay(1);
lcd_en=1;
delay(1);
lcd_en=0;
}
void init_LM032()//LM032液晶的初始化
{
uchar i;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
ET0=1;
write_com(0x80); //第一行的初始化
for(i=0;i<17;i++)
{
write_dat(table1[i]);
delay(1);
}

write_com(0x80+0x40); //第二行的初始化
for(i=0;i<18;i++)
{
write_dat(table2[i]);
delay(1);
}
write_com(0x80+0x40+15); //第二行的初始化
write_dat(0xdf);
}

void delay_18b20(unsigned int i)
{
while(i--);
}

//初始化DS18B20子函数
Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_18b20(1); //稍做延时
DQ = 0; //单片机将DQ拉低
delay_18b20(55); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_18b20(1);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_18b20(15);
}

//读一个字节
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_18b20(4);
}
return(dat);
}
//写一个字节
WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay_18b20(2);
DQ = 1;
dat>>=1;
}
delay_18b20(4);
}

//读取温度值
ReadTemperature(void)
{
uchar a,b,t;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay(850); //等待温度转换结束,不能过短,否则第一次显示不出实际温度,值显示85
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是用DS18B20温度传感器和1602液晶制作温度、可调闹钟和日期同时显温度
a=ReadOneChar(); //读取温度值低位
b=ReadOneChar(); //读取温度值高位
a=a>>4; //低位右移4位,舍弃小数部分
t=b<<4; //高位左移4位,舍弃符号位
t=t|a;
return(t);
}

void write_LM032(uchar address,uchar temp_dat)//向指定的地址中写入时、分、秒数据
{
uchar gewei,shiwei;
shiwei=temp_dat/10;
gewei=temp_dat%10;
write_com(0x80+0x40+address);
write_dat(0x30+shiwei); //根据LM032字符库做相应处理
write_dat(0x30+gewei);
}

void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_dat(0x30+shi);
write_dat(0x30+ge);
}
void keyscan() //调整时间,即手动改变时分秒
{
if(s1==0)
{
TR0=0;
delay(5);
if(s1==0)
{ s1num++;
while(!s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+7);
write_com(0x0f);
}
}
if(s1num==2)
{
write_com(0x80+0x40+4);
}
if(s1num==3)
{
write_com(0x80+0x40+1);
}
if(s1num==4)
{
s1num=0;
write_com(0x0c);
TR0=1;
}

}
if(s1num!=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(7,miao);
write_com(0x80+0x40+7);

}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(4,fen);
write_com(0x80+0x40+4);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(1,shi);
write_com(0x80+0x40+1);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
if(s1num==1)
{

miao--;
if(miao==-1)
miao=59;
write_sfm(7,miao);
write_com(0x80+0x40+7);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(4,fen);
write_com(0x80+0x40+4);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(1,shi);
write_com(0x80+0x40+1);
}
}
}
}
}

void main()
{
uchar temp;
init_LM032();
while(1)
{ delay(100); //去除0秒和1秒之间显示间隔跟正常1秒间隔相差过大
keyscan();
if(miao==0) //每分钟进行温度采集一次
{
TR0=0; //进入温度采集后,关闭定时器
miao++;
flagt=1; //flag=T1向第二行写数据
//write_com(0x80+0x40+10);
//write_dat(0x30+1); //消除不显示数字1
temp=ReadTemperature(); //读取DS18B20的温度值
write_LM032(13,temp); //向LM032中写入温度值
TR0=1; //温度采集完成后,打开定时器
// delay(500);//等待miao不等零,跳出循环
}
}
}

void timer0() interrupt 1//定时器1的中断服务程序,并向LM032中写时分秒显示时间和日期
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
count++;
if (count==18)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
date++;
if(date==30)
{
date=0;
month++;
if(month==12)
{
month=0;
month++;
//flag1=0;//flag=10,向第一行写数据
year++; //范围仅限于0——9
write_sfm(7,year);
}
write_sfm(9,month);
}
write_LM032(12,date);
}
write_LM032(1,shi);
}
write_LM032(4,fen);
}
write_LM032(7,miao);
}
}

回答3:

话说这么多做省赛求程序的,你们现在搞定没?