新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 51單片機(jī)PC數(shù)據(jù)傳輸 溫度 距離 監(jiān)控系統(tǒng)設(shè)計(jì)

51單片機(jī)PC數(shù)據(jù)傳輸 溫度 距離 監(jiān)控系統(tǒng)設(shè)計(jì)

作者: 時間:2016-11-20 來源:網(wǎng)絡(luò) 收藏
>_<:功能概述:

通過串口PC和單片機(jī)通信,可以詢問單片機(jī)測得的溫度,可以詢問聲吶測距的測量距離,同時把測量溫度顯示在數(shù)碼管上。

本文引用地址:http://m.butianyuan.cn/article/201611/318639.htm

>_<:PC部分

這里com.cpp和com.h是串口通信的函數(shù)封裝,在主函數(shù)中:

  • 剛開始調(diào)用封裝好的串口通信函數(shù),設(shè)置打開串口COM4,波特率設(shè)置為9600,超時設(shè)置:

1 if(openport("com4"))2     printf("open comport successn");3 if(setupdcb(9600))4     printf("setupDCB successn");5 if(setuptimeout(0,0,0,0,0)) //如果所有寫超時參數(shù)均為0,那么就不使用寫超時6     printf("setuptimeout successn");7 clearall();//全清

  • 接著循環(huán)接收控制臺命令來與串口通信:這里用了串口通信函數(shù)WriteChar和ReceiveChar來與串口進(jìn)行信息傳送,注意這里的讀寫應(yīng)和單片機(jī)的一致,否則就會出現(xiàn)錯誤。這里舉a==5的例子說明:

    [命令5表示改變距離閾值,當(dāng)輸入5時,PC將向串口發(fā)送字符’5’,然后等待輸入改變后的溫度,當(dāng)輸入改變溫度時,將該溫度傳給串口[因?yàn)槲覀冞@里的范圍是0-100]所以一個char類型就能表示,將這個值發(fā)送給串口,當(dāng)單片機(jī)改變好距離閾值后會返回改好的命令,所以調(diào)用ReceiveChar接收返回信息。其他類似。]
1 while(1){2     scanf("%d",&a);//1表示要溫度,2表示要距離,3表示距離警報關(guān)閉,4溫度警報關(guān)閉,5改變距離閾值,6改變溫度閾值3     if(a==5){ 4         m_szWriteBuffer[0]=5;5         WriteChar(m_szWriteBuffer,1);6         printf("Please enter the num:(0-100cm) n");7         scanf("%d",&a);8         m_szWriteBuffer[0]=(BYTE)(a);9         WriteChar(m_szWriteBuffer,1);10         ReceiveChar(m_szReceiveBuffer,20);11         printf("%sn",m_szReceiveBuffer);12     }else if(a==6){13         m_szWriteBuffer[0]=6;14         WriteChar(m_szWriteBuffer,1);15         printf("Please enter the num:(0-100℃) n");16         scanf("%d",&a);17         m_szWriteBuffer[0]=(BYTE)(a);18         WriteChar(m_szWriteBuffer,1);19         ReceiveChar(m_szReceiveBuffer,20);20         printf("%sn",m_szReceiveBuffer);21     }else{22         m_szWriteBuffer[0]=(BYTE)(a+0);23         WriteChar(m_szWriteBuffer,1);24 25         ReceiveChar(m_szReceiveBuffer,20);26         printf("%sn",m_szReceiveBuffer);27     }28 }

>_<:單片機(jī)部分

設(shè)備:

  • 18B20溫度傳感器
  • 8位數(shù)碼管顯示
  • 串口通信
  • HC-SR04超聲波測距
  • STC89C52[11.0952MHz]
  • 蜂鳴器

連線:

  這里選用11.0592MHz的晶振,將8位7段數(shù)碼管公共線接P0的8個端口,P2.3接位碼,P2.2接段碼;串口通信采用MAX232連接如圖所示。

main函數(shù)介紹:

#初始化部分介紹:

1 unsigned int TempH,TempL,temp;2 Init_Timer0();3 UART_Init(); // 串口初始化4 Init_Timer1();5 6 ReadTemperature();//這里放置3個溫度讀取,防止出現(xiàn)初始化溫度不穩(wěn)定情況7 ReadTemperature();8 ReadTemperature();
  • 第2行:初始定時器:MOD=0x01T0定時16位模式
  • 第3行:串口初始化:具體信息見注釋
1 void UART_Init(void)2 {3     SCON = 0x50;         // 設(shè)定串行口工作方式,8位數(shù)據(jù)位,允許接收4     T2CON = 0x34;         //設(shè)置定時器2,作為波特率發(fā)生器5     RCAP2L = 0XDC;      //9600波特率的低8位6     RCAP2H = 0XFF;        //9600波特率的高8位    7     ES = 1;                 //允許串口中斷8     EA = 1;                 //允許總中斷9 }
  • 第6-8行:在系統(tǒng)初始前先讀取3次溫度,防止系統(tǒng)初始時溫度的值不正常而觸發(fā)報警

#主循環(huán)介紹:

1 while (1)    2 {3     if(isInclude  isAbove){4         //LED_Show(2);5         //if(freq==200);6         SPK=!SPK;7     }8     if(uart_flag==1)   //接收到9     {10         ES=0;       //關(guān)串口中斷11         if(come==1){//接收并改變距離閾值12             maxJuLi=(unsigned int)a;13             come=0;14             UART_Send_Byte(O);15             UART_Send_Byte(K);16             UART_Send_Byte(#);17             UART_Send_Byte(n);18         }else if(come==2){//接收并改變溫度閾值19             maxWenDu=(unsigned int)a;20             come=0;21             UART_Send_Byte(O);22             UART_Send_Byte(K);23             UART_Send_Byte(#);24             UART_Send_Byte(n);25         }else//其他操作26         switch(a){//要溫度27         case 1:28             for(i=0;i<17;i++)29             {30                 UART_Send_Byte(SendData[i]);//將數(shù)據(jù)發(fā)給串口31             }32             UART_Send_Byte(n);33             break;34         case 2://要距離35             for(i=0;i<16;i++)36             {37                 UART_Send_Byte(SendData1[i]);//將數(shù)據(jù)發(fā)給串口38             }39             UART_Send_Byte(n);40             break;41         case 3:42             if(isInclude){43                 isInclude=0;44                 UART_Send_Byte(c);45                 UART_Send_Byte(l);46                 UART_Send_Byte(o);47                 UART_Send_Byte(s);48                 UART_Send_Byte(e);49                 UART_Send_Byte(#);50                 UART_Send_Byte(n);51             }else{52                 UART_Send_Byte(n);53                 UART_Send_Byte(o);54                 UART_Send_Byte( );55                 UART_Send_Byte(p);56                 UART_Send_Byte(e);57                 UART_Send_Byte(r);58                 UART_Send_Byte(s);59                 UART_Send_Byte(o);60                 UART_Send_Byte(n);61                 UART_Send_Byte(#);62                 UART_Send_Byte(n);63             }64             break;65         case 4:66             if(isAbove){67                 isAbove=0;68                 UART_Send_Byte(c);69                 UART_Send_Byte(l);70                 UART_Send_Byte(o);71                 UART_Send_Byte(s);72                 UART_Send_Byte(e);73                 UART_Send_Byte(#);74                 UART_Send_Byte(n);75             }else{76                 UART_Send_Byte(n);77                 UART_Send_Byte(o);78                 UART_Send_Byte( );79                 UART_Send_Byte(f);80                 UART_Send_Byte(i);81                 UART_Send_Byte(r);82                 UART_Send_Byte(e);83                 UART_Send_Byte(#);84                 UART_Send_Byte(n);85             }86             break;87         case 5:88             come=1;89             break;90         case 6:91             come=2;92             break;93         default://錯誤操作94             for(i=0;i<16;i++)95             {96                 UART_Send_Byte(SendData2[i]);//將數(shù)據(jù)發(fā)給串口97             }98             UART_Send_Byte(n);99             break;100         }101         ES=1;    //允許串口中斷102         uart_flag=0;  //中斷標(biāo)志位置0103     }104     else if(ReadTempFlag==1)//通過定時器,每隔1200ms掃描一次溫度105     {106         ReadTempFlag=0;107         temp=ReadTemperature();108         if(temp&0x8)//第一位為1就表示為負(fù)要取反加1第一位弄個負(fù)號109         {110             TempData[0]=0x40;//負(fù)號標(biāo)志temp=~temp;  // 取反加1112             temp +=1;113         }114         else115             TempData[0]=0;//其他情況就該顯示負(fù)號的不顯示116         117         TempH=temp>>4;//去除低四位118         TempL=temp&0x0F;//獲取溫度低四位119         TempL=TempL*6/10;//小數(shù)近似處理!120 121         if(TempH>0 && TempH>maxWenDu)isAbove=1;//界限判斷122 123         if(TempH/100==0)//百位數(shù)據(jù)124             TempData[1]=0;125         else126             TempData[1]=DuanMa[TempH/100]; //百位溫度127         if((TempH%100)/10==0)//十位溫度128             TempData[2]=0;129         else130             TempData[2]=DuanMa[(TempH%100)/10];131         TempData[3]=DuanMa[(TempH%100)%10]0x80; //個位溫度,帶小數(shù)點(diǎn)132         TempData[4]=DuanMa[TempL];133         TempData[6]=0x39;         //顯示C符號134 135         136         SendData[11]=(unsigned char)(TempH/100+0);137         SendData[12]=(unsigned char)(TempH%100/10+0);138         SendData[13]=(unsigned char)(TempH%100%10+0);139         SendData[14]=.;140         SendData[15]=(unsigned char)(TempL+0);141     }else if(ReadTempFlag==2){142         ReadTempFlag=0;143         StartModule();        //測距144         while(!RX);            //當(dāng)RX為零時等待145         TR1=1;                //開啟計(jì)數(shù)146         while(RX);            //當(dāng)RX為1計(jì)數(shù)并等待147         TR1=0;                //關(guān)閉計(jì)數(shù)148         Conut();            //計(jì)算149     }150 }
  • 第3-7行:當(dāng)溫度在閾值外或者距離在閾值內(nèi)時就響鈴
  • 第8-103行:當(dāng)串口通信發(fā)生串口中斷時,會把uart_flag標(biāo)志位置1,然后主程序就會處理PC端傳送過來的數(shù)據(jù),這里采用串口中斷來檢測是否收到PC發(fā)來的數(shù)據(jù)的:
1 void UART(void) interrupt 42 {3     if(RI)                   //檢測接收完成標(biāo)志位置14     {5         RI=0;            //清零接收完成標(biāo)志位6         a=SBUF;            //讀取接收到的數(shù)據(jù)7         uart_flag = 1;    //中斷標(biāo)志位置18     }9 }
  • 第11-25行:這里是要修改溫度或者距離的閾值時用到的特殊處理,因?yàn)楫?dāng)收到修改閾值的命令之后還要等待要改成的值,為了區(qū)別這個值和命令值,于是用come標(biāo)記是否是要修改閾值,如果不是修改閾值,就正常判斷命令,否則就做相應(yīng)的閾值修改。
  • 第27-33行:將溫度發(fā)送給PC,最后要發(fā)送一個換行,當(dāng)做結(jié)束標(biāo)志位[這是和PC端的接收程序有關(guān),2個通信的協(xié)議要一致],其他類似,不做詳解。
  • 第41-86行:關(guān)閉報警命令,如果正在報警,就關(guān)閉報警,返回給電腦已經(jīng)關(guān)閉的信息;如果沒有報警,就電腦相應(yīng)信息。
  • 第87-92行:要修改閾值,就把come置成相應(yīng)的值,等待接受要修改值,與第11-25行相對應(yīng)
  • 第104-141行:如果沒有電腦命令傳過來就進(jìn)行溫度采集和距離測試:
1 void Timer0_isr(void) interrupt 1 2 {3     static unsigned int num;4     TH0=(65536-2)/256;//重新賦值 2ms5     TL0=(65536-2)%256;6     7     Display(0,8);  // 調(diào)用數(shù)碼管掃描8     num++;9     if(num==100){10         ReadTempFlag=1;//讀溫度標(biāo)志位置211     }else if(num==150)      12     {13         num=0;14         ReadTempFlag=2;//讀距離標(biāo)志位置1 15     }16 }
  • 第143-147行:測量時間差[用定時器TH1,TL1]
  • 第148行:計(jì)算超聲波測距的距離[根據(jù)上面計(jì)算的聲波來回的時差]
1 void Conut(void)2 {3     time=TH1*256+TL1;4     TH1=0;5     TL1=0;6     S=(time*1.87)/100;     //算出來是CM7     if(flag==1)            //超出測量8     {9         flag=0;10         //printf("--n"); 11     }12     if(S



評論


技術(shù)專區(qū)

關(guān)閉