找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2415|回复: 3
收起左侧

求做一份带串口通信的单片机温度监测仪器设计,带注释的!

[复制链接]
ID:335604 发表于 2018-5-26 20:38 | 显示全部楼层 |阅读模式
50黑币
设计说明和要求:
①使用51单片机为核心设计一带串口通信的温度监测仪器;温度传感器要求使用DS18B20,每隔2s左右采集一次环境温度,精度精确到小数点后1位;温度上限值默认设置为32度;使用液晶器件LM016L显示采集的温度和温度上限值,第1行显示温度,第2行显示温度上限值;当采集的温度超过温度上限值时,当进行声光报警,点亮红色LED灯,并控制蜂鸣器发出蜂鸣声;当仪器通过串口接收到字符“A”时,仪器通过串口发送内容格式为“DD.DTDDU”的字符串,其中第1-4位“DD.D”为采集的温度,第5位为字符“T”,为温度标识,第6-7位“DD”为温度上限值,第8位为字符“U”,为温度上限值标识,比如“28.2T32U”,表示采集的温度为28.2度,当前设置的温度上限值为32度。
③使用Proteus(建议版本:Proteus-7.8sp2,提供,使用方法参考文档:Proteus 7 Professional 51单片机入门教程.pdf,提供)搭建仪器的硬件框架;使用C语言。使用虚拟串口软件(建议软件:vspdxp虚拟串口破解版,提供)虚拟串口线;使用串口调试助手(建议软件:串口调试助手V2.2.exe,提供)与仪器进行仿真调试。

最佳答案

查看完整内容

#include #include #define uchar unsigned char #define uint unsigned int #define LCDIO P0 //1602数据口 sbit DQ=P3^7;//ds18b20与单片机连接口 sbitrs=P2^0; //1602数据命令选择引脚 sbitrd=P2^1; //读写选择 sbitlcden=P2^2; //1602选通引脚 floatf_temp; //浮点型温度值 uinttvalue;//温度值 uchartflag; uchar code table[]= {"The temperature "}; //每行显示16个字符 uchar co ...
回复

使用道具 举报

ID:336165 发表于 2018-5-26 20:38 | 显示全部楼层
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

#define     LCDIO      P0  //1602数据口
sbit DQ=P3^7;//ds18b20与单片机连接口

sbitrs=P2^0;  //1602数据命令选择引脚
sbitrd=P2^1;   //读写选择
sbitlcden=P2^2;   //1602选通引脚

floatf_temp; //浮点型温度值
uinttvalue;//温度值
uchartflag;

uchar code table[]=   {"The temperature "};    //每行显示16个字符
uchar code table1[]=  {"is:  000.0C wfu"};

uchar data disdata[5];

void delay(uint z) //短延时
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(uchar com)   //1602写命令子程序
{
rs=0;    //RS是数据命令选择短,高电平写数据,低电平写命令
rd=0;    //RD是读写选择短,高电平读,低电平写
lcden=0; //1602选通端,高电平选通,低电平禁止
    LCDIO=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_date(uchar date) //1602写数据子程序
{
rs=1; //RS是数据命令选择短,高电平写数据,低电平写命令
rd=0; //RD是读写选择短,高电平读,低电平写
lcden=0; //1602选通端,高电平选通,低电平禁止
    LCDIO=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidinit()           //1602初始化程序
{
ucharnum;
lcden=0;

write_com(0x38);  //0011 1000B,功能模式设置,设置为8为数据口,两行显示,5*7点阵
write_com(0x0c);  //0000 1011B,显示开及光标设置,关显示,显示光标,光标闪烁
write_com(0x06);  //0000 0110B,显示光标移动设置,读或写一个字符,地址指针减一且光标减一,写一个字符屏幕显示不移动
write_com(0x01);  //0000 0001B,显示清屏,数据指针和所有显示清屏
write_com(0x80);  //1000 000B,关闭显示
delay(5);
write_com(0x80);  //1000 000B,设置为2行显示,写入第一行字符的地址,第一行地址是00-2F
for(num=0;num<16;num++)
       {
write_date(table[num]); //写入第一行数据
delay(5);
       }
write_com(0x80+0x40);   //1100 0000B,设置为2行显示,写入第二行字符的地址,第而行地址是40-67
for(num=0;num<16;num++) //写入第二行数据
       {
write_date(table1[num]);//写入第二行数据
delay(5);
       }

}
void delay_18B20(unsignedinti)//延时1微秒
{
while(i--);
}

void ds1820rst()      /*ds1820复位*/
//DS18B20要求数据线拉低500US即可复位。
{  unsignedchar x=0;
     DQ = 1;          //DQ复位
     delay_18B20(4);  //延时
     DQ = 0;          //DQ拉低
     delay_18B20(100); //精确延时大于480us
     DQ = 1;          //拉高
     delay_18B20(40);  
   }

uchar ds1820rd()/*读数据*/
{ unsignedchar i=0;
unsignedchardat = 0;
for (i=8;i>0;i--)
     {   DQ = 0; //给脉冲信号
dat>>=1;
         DQ = 1; //给脉冲信号
if(DQ)
dat|=0x80;
         delay_18B20(10);
     }
return(dat);
  }

void ds1820wr(ucharwdata)/*写数据*/
  {unsignedchar i=0;
for (i=8; i>0; i--)
{ DQ = 0;
     DQ = wdata&0x01;
     delay_18B20(10);
     DQ = 1;
wdata>>=1;
   }
}
read_temp()/*读取温度值并转换*/
{uchara,b;
ds1820rst();   

   ds1820wr(0xCC);//跳过ROM
   _nop_();
//ds1820wr(0x4E);//写EEPROM,发出向内部RAM的3、4 字节写上、下限温度数据命令,紧跟该命令之后,是传送两字节的数据
// ds1820wr(0x00);//Th
//ds1820wr(0x00);//Tl


ds1820wr(0x7f);//12 bits温度分辨率x1f, 0x3f, 0x5f ,0x7f温度读数分辨率分别对应0.5, 0.25, 0.125 ,0.0625

//ds1820wr(0xcc);    //跳过读EPROM序列
//ds1820wr(0x48);   将RAM 中第3 、4 字节的内容复制到EEPROM中
ds1820rst();
   ds1820wr(0xcc);//*跳过读序列号*/
  _nop_();
  ds1820wr(0x44);//*启动温度转换*/

ds1820rst();  
  ds1820wr(0xcc);//*跳过读序列号*/
  ds1820wr(0xbe);//*读取温度*/
  a=ds1820rd();
  b=ds1820rd();
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
if(tvalue<0x0fff)
tflag=0;
else
   {tvalue=~tvalue+1;
tflag=1;
   }
//tvalue=tvalue*(0.425);//温度值扩大10倍,精确到1位小数
f_temp=tvalue*(0.0625);    // 温度在寄存器中为12位,分辨率为0.0625
tvalue=f_temp*10+0.5;    //乘以10表示小数点后面只取1位,加0.5时四舍五入
//f_temp=f_temp+0.05;
//f_temp=tvalue*(0.0625);
//tvalue=f_temp*100+(tvalue>0?0.5:-0.5);


return(tvalue);
  }


void ds1820disp()//温度值显示
{ ucharflagdat;
disdata[0]=tvalue/1000+0x30;//百位数
disdata[1]=tvalue%1000/100+0x30;//十位数
disdata[2]=tvalue%100/10+0x30;//个位数
disdata[3]=tvalue%10+0x30;//小数位

if(tflag==0)
flagdat=0x20;//正温度不显示符号
else
flagdat=0x2d;//负温度显示负号:-

if(disdata[0]==0x30)
       {disdata[0]=0x20;//如果百位为0,不显示
if(disdata[1]==0x30)
         {disdata[1]=0x20;//如果百位为0,十位为0也不显示
         }
       }


write_com(0x80+0x44);      //1100 0000B,设置为2行显示,写入第二行字符的地址,第而行地址是40-67
write_date(flagdat);//显示符号位
write_com(0x80+0x45);
write_date(disdata[0]);//显示百位
write_com(0x80+0x46);
write_date(disdata[1]);//显示十位
write_com(0x80+0x47);
write_date(disdata[2]);//显示个位
write_com(0x80+0x48);
write_date(0x2e);//显示小数点
write_com(0x80+0x49);
write_date(disdata[3]);//显示小数位
write_com(0x80+0x4a);
write_date('C');
   }

void main()
{   
init();

read_temp();//读取温度
    ds1820disp();//显示
while(1)
    {

read_temp();//读取温度
     ds1820disp();//显示

    }
}
回复

使用道具 举报

ID:335604 发表于 2018-5-27 11:54 | 显示全部楼层
优雅的刺猬 发表于 2018-5-26 23:01
#include
#include
#define uchar unsigned char

运行有错误呀,有些定义没定义到,能顺便把proteus图也发一下吗
回复

使用道具 举报

ID:308173 发表于 2018-5-28 15:23 来自手机 | 显示全部楼层
郭天祥写的那本51单片机C语言教程里面有这个里面有这个
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表