標(biāo)題: 求做一份帶串口通信的單片機(jī)溫度監(jiān)測(cè)儀器設(shè)計(jì),帶注釋的! [打印本頁(yè)]

作者: ennnnnmin    時(shí)間: 2018-5-26 20:38
標(biāo)題: 求做一份帶串口通信的單片機(jī)溫度監(jiān)測(cè)儀器設(shè)計(jì),帶注釋的!
設(shè)計(jì)說(shuō)明和要求:
①使用51單片機(jī)為核心設(shè)計(jì)一帶串口通信的溫度監(jiān)測(cè)儀器;溫度傳感器要求使用DS18B20,每隔2s左右采集一次環(huán)境溫度,精度精確到小數(shù)點(diǎn)后1位;溫度上限值默認(rèn)設(shè)置為32度;使用液晶器件LM016L顯示采集的溫度和溫度上限值,第1行顯示溫度,第2行顯示溫度上限值;當(dāng)采集的溫度超過(guò)溫度上限值時(shí),當(dāng)進(jìn)行聲光報(bào)警,點(diǎn)亮紅色LED燈,并控制蜂鳴器發(fā)出蜂鳴聲;當(dāng)儀器通過(guò)串口接收到字符“A”時(shí),儀器通過(guò)串口發(fā)送內(nèi)容格式為“DD.DTDDU”的字符串,其中第1-4位“DD.D”為采集的溫度,第5位為字符“T”,為溫度標(biāo)識(shí),第6-7位“DD”為溫度上限值,第8位為字符“U”,為溫度上限值標(biāo)識(shí),比如“28.2T32U”,表示采集的溫度為28.2度,當(dāng)前設(shè)置的溫度上限值為32度。
③使用Proteus(建議版本:Proteus-7.8sp2,提供,使用方法參考文檔:Proteus 7 Professional 51單片機(jī)入門教程.pdf,提供)搭建儀器的硬件框架;使用C語(yǔ)言。使用虛擬串口軟件(建議軟件:vspdxp虛擬串口破解版,提供)虛擬串口線;使用串口調(diào)試助手(建議軟件:串口調(diào)試助手V2.2.exe,提供)與儀器進(jìn)行仿真調(diào)試。


作者: 優(yōu)雅的刺猬    時(shí)間: 2018-5-26 20:38
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

#define     LCDIO      P0  //1602數(shù)據(jù)口
sbit DQ=P3^7;//ds18b20與單片機(jī)連接口

sbitrs=P2^0;  //1602數(shù)據(jù)命令選擇引腳
sbitrd=P2^1;   //讀寫選擇
sbitlcden=P2^2;   //1602選通引腳

floatf_temp; //浮點(diǎn)型溫度值
uinttvalue;//溫度值
uchartflag;

uchar code table[]=   {"The temperature "};    //每行顯示16個(gè)字符
uchar code table1[]=  {"is:  000.0C wfu"};

uchar data disdata[5];

void delay(uint z) //短延時(shí)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(uchar com)   //1602寫命令子程序
{
rs=0;    //RS是數(shù)據(jù)命令選擇短,高電平寫數(shù)據(jù),低電平寫命令
rd=0;    //RD是讀寫選擇短,高電平讀,低電平寫
lcden=0; //1602選通端,高電平選通,低電平禁止
    LCDIO=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_date(uchar date) //1602寫數(shù)據(jù)子程序
{
rs=1; //RS是數(shù)據(jù)命令選擇短,高電平寫數(shù)據(jù),低電平寫命令
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,功能模式設(shè)置,設(shè)置為8為數(shù)據(jù)口,兩行顯示,5*7點(diǎn)陣
write_com(0x0c);  //0000 1011B,顯示開及光標(biāo)設(shè)置,關(guān)顯示,顯示光標(biāo),光標(biāo)閃爍
write_com(0x06);  //0000 0110B,顯示光標(biāo)移動(dòng)設(shè)置,讀或?qū)懸粋(gè)字符,地址指針減一且光標(biāo)減一,寫一個(gè)字符屏幕顯示不移動(dòng)
write_com(0x01);  //0000 0001B,顯示清屏,數(shù)據(jù)指針和所有顯示清屏
write_com(0x80);  //1000 000B,關(guān)閉顯示
delay(5);
write_com(0x80);  //1000 000B,設(shè)置為2行顯示,寫入第一行字符的地址,第一行地址是00-2F
for(num=0;num<16;num++)
       {
write_date(table[num]); //寫入第一行數(shù)據(jù)
delay(5);
       }
write_com(0x80+0x40);   //1100 0000B,設(shè)置為2行顯示,寫入第二行字符的地址,第而行地址是40-67
for(num=0;num<16;num++) //寫入第二行數(shù)據(jù)
       {
write_date(table1[num]);//寫入第二行數(shù)據(jù)
delay(5);
       }

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

void ds1820rst()      /*ds1820復(fù)位*/
//DS18B20要求數(shù)據(jù)線拉低500US即可復(fù)位。
{  unsignedchar x=0;
     DQ = 1;          //DQ復(fù)位
     delay_18B20(4);  //延時(shí)
     DQ = 0;          //DQ拉低
     delay_18B20(100); //精確延時(shí)大于480us
     DQ = 1;          //拉高
     delay_18B20(40);  
   }

uchar ds1820rd()/*讀數(shù)據(jù)*/
{ unsignedchar i=0;
unsignedchardat = 0;
for (i=8;i>0;i--)
     {   DQ = 0; //給脈沖信號(hào)
dat>>=1;
         DQ = 1; //給脈沖信號(hào)
if(DQ)
dat|=0x80;
         delay_18B20(10);
     }
return(dat);
  }

void ds1820wr(ucharwdata)/*寫數(shù)據(jù)*/
  {unsignedchar i=0;
for (i=8; i>0; i--)
{ DQ = 0;
     DQ = wdata&0x01;
     delay_18B20(10);
     DQ = 1;
wdata>>=1;
   }
}
read_temp()/*讀取溫度值并轉(zhuǎn)換*/
{uchara,b;
ds1820rst();   

   ds1820wr(0xCC);//跳過(guò)ROM
   _nop_();
//ds1820wr(0x4E);//寫EEPROM,發(fā)出向內(nèi)部RAM的3、4 字節(jié)寫上、下限溫度數(shù)據(jù)命令,緊跟該命令之后,是傳送兩字節(jié)的數(shù)據(jù)
// ds1820wr(0x00);//Th
//ds1820wr(0x00);//Tl


ds1820wr(0x7f);//12 bits溫度分辨率x1f, 0x3f, 0x5f ,0x7f溫度讀數(shù)分辨率分別對(duì)應(yīng)0.5, 0.25, 0.125 ,0.0625

//ds1820wr(0xcc);    //跳過(guò)讀EPROM序列
//ds1820wr(0x48);   將RAM 中第3 、4 字節(jié)的內(nèi)容復(fù)制到EEPROM中
ds1820rst();
   ds1820wr(0xcc);//*跳過(guò)讀序列號(hào)*/
  _nop_();
  ds1820wr(0x44);//*啟動(dòng)溫度轉(zhuǎn)換*/

ds1820rst();  
  ds1820wr(0xcc);//*跳過(guò)讀序列號(hào)*/
  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);//溫度值擴(kuò)大10倍,精確到1位小數(shù)
f_temp=tvalue*(0.0625);    // 溫度在寄存器中為12位,分辨率為0.0625
tvalue=f_temp*10+0.5;    //乘以10表示小數(shù)點(diǎn)后面只取1位,加0.5時(shí)四舍五入
//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;//百位數(shù)
disdata[1]=tvalue%1000/100+0x30;//十位數(shù)
disdata[2]=tvalue%100/10+0x30;//個(gè)位數(shù)
disdata[3]=tvalue%10+0x30;//小數(shù)位

if(tflag==0)
flagdat=0x20;//正溫度不顯示符號(hào)
else
flagdat=0x2d;//負(fù)溫度顯示負(fù)號(hào):-

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


write_com(0x80+0x44);      //1100 0000B,設(shè)置為2行顯示,寫入第二行字符的地址,第而行地址是40-67
write_date(flagdat);//顯示符號(hào)位
write_com(0x80+0x45);
write_date(disdata[0]);//顯示百位
write_com(0x80+0x46);
write_date(disdata[1]);//顯示十位
write_com(0x80+0x47);
write_date(disdata[2]);//顯示個(gè)位
write_com(0x80+0x48);
write_date(0x2e);//顯示小數(shù)點(diǎn)
write_com(0x80+0x49);
write_date(disdata[3]);//顯示小數(shù)位
write_com(0x80+0x4a);
write_date('C');
   }

void main()
{   
init();

read_temp();//讀取溫度
    ds1820disp();//顯示
while(1)
    {

read_temp();//讀取溫度
     ds1820disp();//顯示

    }
}

作者: ennnnnmin    時(shí)間: 2018-5-27 11:54
優(yōu)雅的刺猬 發(fā)表于 2018-5-26 23:01
#include
#include
#define uchar unsigned char

運(yùn)行有錯(cuò)誤呀,有些定義沒定義到,能順便把proteus圖也發(fā)一下嗎
作者: miaoxiaobaiqaq    時(shí)間: 2018-5-28 15:23
郭天祥寫的那本51單片機(jī)C語(yǔ)言教程里面有這個(gè)里面有這個(gè)




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1