单片机AT89C51连接DS18B20然后将采集到的两个字节通过RS232发送到PC机界面中,请问单片机用C语言怎么编写
2个回答
展开全部
好编写啊,1.DS18B20采样 2.提取数据 3.UART传输。
给你点代码,自己参考下。
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dq=P1^5;
void sdelay(unsigned int i)
{
while(i--);
}
ds18b20on(void)//ds18b20初始化
{
uchar x=0;
dq=1;
sdelay(8);
dq=0;
sdelay(80);
dq=1;
sdelay(14);
sdelay(20);
}
//读一个字节
readds18b20(void)
{
uchar i=0,dat=0;
for(i=8;i>0;i--)
{
dq=0;
dat>>=1;
dq=1;
if(dq)
dat|=0x80;
sdelay(4);
}
return(dat);
}
//写一个字节
writeds18b20(uchar dat)
{
uchar i=0;
for(i=8;i>0;i--)
{
dq=0;
dq=dat&0x01;
sdelay(5);
dq=1;
dat>>=1;
}
}
//读取温度
readtemperature(void)
{
uchar a=0,b=0;
uint t=0;
float tt=0;
ds18b20on();
writeds18b20(0xCC);//跳过ROM
writeds18b20(0x44);//开启温度转换
ds18b20on();
writeds18b20(0xCC);
writeds18b20(0xBE);//读暂存器
a=readds18b20();
b=readds18b20();
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5;
return(t);
}
这部分是DS18B20的采样:
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5;
return(t);
这部分的处理是得到十进制的温度数据。
如果你想直接得到2个字节数据(a=readds18b20();b=readds18b20();
),那么刚才那段可以不处理,删掉!
然后是串口部分:
#include <reg52.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
uchar receive[35]; //串口接收数据存放
uchar t=0;
void delay(uint z)//延时子程序
{
uint x,y;
for(x=10;x>0;x--)
for(y=z;y>0;y--); //z*10 us
}
void init()//串口初始化
{
SCON=0x50; //SCON:串行口工作方式1, 8-bit UART,允许串行接收位(REN=1)
TMOD=0x20; //TMOD:定时器1,方式2,8位自动重装方式
PCON=0x80; //SMOD=1;(将串口传送的波特率加倍)
TH1=0xfa; //Baud:9600 fosc=11.0592MHz
TL1=0xfa;
TR1=1; //启动定时器/计数器1运行
//IE=0x90; //EA=1,ES=1允许总中断,允许串口中断
EA=1; //开总中断
ES=1; //开串口中断
}
void send_char(uchar a)//向串口发送一个字符
{
SBUF=a; //发送数据给“串口调试助手”接收窗口
while(TI==0);//等待发送完,TI置1
TI=0; //清零 TI为发送中断标志
}
void send_string(uchar *str) //向串口发送一个字符串,strlen为该字符串长度
{
uint k=0;
do
{
send_char(*(str + k));
k++;
} while(k<strlen(str));
t=0;//发送完毕,准备接收
}
//串口接收中断函数,并将数据放入预存放数组里,每收到一个字符中断一次
void serial() interrupt 4 using 3
{
if(RI==1)//RI为接受中断标志,可能是发送产生的中断
{
uchar a;
RI=0;//接受中断标志软件清零
P0=SBUF;//把收到的缓存数据赋给P0口
a=SBUF;//把缓存在单片机的数据给a
// send_char(a);
receive[t++]=a;//将接受数据放入预置数组
send_string(receive);//将收到的数据发送回去,给P0口&显示在“串口调试助手”接收框
}
}
/*******************************主函数*******************************************/
void main()
{
init(); //串口初始化
delay(1);
// send_string();//利用串口发送字符串
while(1);
}
这个是串口收发程序,收什么发什么,那么我们修改一下,把我们的数据传出去。
void main()
{
uchar aa[2];//用于发数据
uint bb=0;//用于保存温度数据
init(); //串口初始化
ds18b20on(); //ds18b20初始化
bb=readtemperature();//温度采样
aa[0]=bb; //取温度数据低字节
aa[1]=bb>>8; //取温度数据高字节
send_string(aa);//利用串口发送字符串
while(1);//这里只循环了一次,你可以做修改
}
基本思路就这样,程序要你自己修改一部分,有问题Hi我!
给你点代码,自己参考下。
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dq=P1^5;
void sdelay(unsigned int i)
{
while(i--);
}
ds18b20on(void)//ds18b20初始化
{
uchar x=0;
dq=1;
sdelay(8);
dq=0;
sdelay(80);
dq=1;
sdelay(14);
sdelay(20);
}
//读一个字节
readds18b20(void)
{
uchar i=0,dat=0;
for(i=8;i>0;i--)
{
dq=0;
dat>>=1;
dq=1;
if(dq)
dat|=0x80;
sdelay(4);
}
return(dat);
}
//写一个字节
writeds18b20(uchar dat)
{
uchar i=0;
for(i=8;i>0;i--)
{
dq=0;
dq=dat&0x01;
sdelay(5);
dq=1;
dat>>=1;
}
}
//读取温度
readtemperature(void)
{
uchar a=0,b=0;
uint t=0;
float tt=0;
ds18b20on();
writeds18b20(0xCC);//跳过ROM
writeds18b20(0x44);//开启温度转换
ds18b20on();
writeds18b20(0xCC);
writeds18b20(0xBE);//读暂存器
a=readds18b20();
b=readds18b20();
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5;
return(t);
}
这部分是DS18B20的采样:
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5;
return(t);
这部分的处理是得到十进制的温度数据。
如果你想直接得到2个字节数据(a=readds18b20();b=readds18b20();
),那么刚才那段可以不处理,删掉!
然后是串口部分:
#include <reg52.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
uchar receive[35]; //串口接收数据存放
uchar t=0;
void delay(uint z)//延时子程序
{
uint x,y;
for(x=10;x>0;x--)
for(y=z;y>0;y--); //z*10 us
}
void init()//串口初始化
{
SCON=0x50; //SCON:串行口工作方式1, 8-bit UART,允许串行接收位(REN=1)
TMOD=0x20; //TMOD:定时器1,方式2,8位自动重装方式
PCON=0x80; //SMOD=1;(将串口传送的波特率加倍)
TH1=0xfa; //Baud:9600 fosc=11.0592MHz
TL1=0xfa;
TR1=1; //启动定时器/计数器1运行
//IE=0x90; //EA=1,ES=1允许总中断,允许串口中断
EA=1; //开总中断
ES=1; //开串口中断
}
void send_char(uchar a)//向串口发送一个字符
{
SBUF=a; //发送数据给“串口调试助手”接收窗口
while(TI==0);//等待发送完,TI置1
TI=0; //清零 TI为发送中断标志
}
void send_string(uchar *str) //向串口发送一个字符串,strlen为该字符串长度
{
uint k=0;
do
{
send_char(*(str + k));
k++;
} while(k<strlen(str));
t=0;//发送完毕,准备接收
}
//串口接收中断函数,并将数据放入预存放数组里,每收到一个字符中断一次
void serial() interrupt 4 using 3
{
if(RI==1)//RI为接受中断标志,可能是发送产生的中断
{
uchar a;
RI=0;//接受中断标志软件清零
P0=SBUF;//把收到的缓存数据赋给P0口
a=SBUF;//把缓存在单片机的数据给a
// send_char(a);
receive[t++]=a;//将接受数据放入预置数组
send_string(receive);//将收到的数据发送回去,给P0口&显示在“串口调试助手”接收框
}
}
/*******************************主函数*******************************************/
void main()
{
init(); //串口初始化
delay(1);
// send_string();//利用串口发送字符串
while(1);
}
这个是串口收发程序,收什么发什么,那么我们修改一下,把我们的数据传出去。
void main()
{
uchar aa[2];//用于发数据
uint bb=0;//用于保存温度数据
init(); //串口初始化
ds18b20on(); //ds18b20初始化
bb=readtemperature();//温度采样
aa[0]=bb; //取温度数据低字节
aa[1]=bb>>8; //取温度数据高字节
send_string(aa);//利用串口发送字符串
while(1);//这里只循环了一次,你可以做修改
}
基本思路就这样,程序要你自己修改一部分,有问题Hi我!
2011-12-13
展开全部
建议 去 我的领地 5d6d 的 proteus 论坛看看
那里有很多 单片机仿真实例,包括仿真图 和 源码
搜 5d6d 和 proteus 2个关键词
那里有很多 单片机仿真实例,包括仿真图 和 源码
搜 5d6d 和 proteus 2个关键词
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询