久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

基于51單片機(jī)串口通信的實(shí)時(shí)溫度采集系統(tǒng)主要程序

作者:huqin   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年04月04日   【字體:

測(cè)試環(huán)境:Keil μVision4
測(cè)試芯片:STC89C52RC
所需器件:DS18B20
//
//Created by XD on 03/04/14
//
#include <AT89X52.h>//調(diào)用51單片機(jī)的頭文件
#include <Intrins.h>//這個(gè)頭文件里有_nop()_;函數(shù)的定義
//---------------------------------------
//1602液晶相關(guān)I/O設(shè)置
sbit E = P1^2; //液晶E接口位定義,對(duì)位操作,要先進(jìn)行位定義,因?yàn)锳T89X52.h頭文件里沒有相關(guān)的位定義
sbit RW = P1^1;//液晶RW接口位定義,對(duì)位操作,要先進(jìn)行位定義,因?yàn)锳T89X52.h頭文件里沒有相關(guān)的位定義
sbit RS = P1^0;//液晶RS接口位定義,對(duì)位操作,要先進(jìn)行位定義,因?yàn)锳T89X52.h頭文件里沒有相關(guān)的位定義
//---------------------------------------
sbit DS18B20 = P2^0;//DS18B20接口定義
sbit LED = P2^7;
//---------------------------------------
//串口接收寄存器設(shè)置
unsigned char senddata;
unsigned char USARTbuf;//定義一個(gè)8位的變量來暫存串口接收內(nèi)容
//---------------------------------------
//1602液晶寄存器設(shè)置
unsigned char DISbuf;     //設(shè)置8位的unsigend char型寄存器用來暫存1602要顯示的內(nèi)容
//---------------------------------------
//DS18B20相關(guān)變量
unsigned char temp1;//小數(shù)部分
unsigned char temp2;//整數(shù)部分
unsigned char code table[16] = {0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,9};//小數(shù)部分顯示的數(shù)組
//---------------------------------------
//名稱:延時(shí)函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
void Delay(unsigned int nTimeDelay)
{
        unsigned int i;//定義無符號(hào)變量i
        /*
         *nTimeDelay自減一次,執(zhí)行一次下面語句,直到nTimeDelay為0時(shí),
         *結(jié)束循環(huán),一共執(zhí)行下面語句nTimeDelay次,while語句的循環(huán)體只有一句for循環(huán),其沒有循環(huán)體。
         */
        while (nTimeDelay--)
        for (i = 0;i < 125;i++);
}

//---------------------------------------
//名稱:復(fù)位DS18B20函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
bit Reset(void)
{
        unsigned int i;//定義無符號(hào)整型變量,用于下面的時(shí)序延時(shí)
        bit k;//定義bit型變量k,k=1為復(fù)位成功,k=0為復(fù)位失敗
        
        /*
         *在初始化時(shí)序中,拉低DQ總線至少保持480μs的低電平信號(hào)
         */
        DS18B20 = 0;
        i = 200;        
        while(i > 0)       
        i--;     
        /*
         *DS18B20 = 1,DQ總線由10K的上拉電阻拉到高電平,
         *DS18B20在檢測(cè)到總線的上升沿之后,
         *等待15-60μs
         */
        DS18B20 = 1;
        i = 18;        
        while(i > 0)     
        i--;      
      
        /*
         *將DQ總線的狀態(tài)賦值給k,為1復(fù)位成功,為0復(fù)位失敗
         *發(fā)出一個(gè)60-240μs低電平信號(hào)構(gòu)成的存在脈沖
         */  
        k = DS18B20;        
        i = 91;        
        while(i > 0)      
        i--;         
        return k;//返回DS18B20是否復(fù)位成功標(biāo)志
}
//---------------------------------------
//名稱:讀一字節(jié)函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
unsigned char ReadByte(void)
{
        unsigned int i;//定義無符號(hào)整型變量,用于下面的時(shí)序延時(shí)
        unsigned char j,buf = 0;
        for(j = 0;j < 8;j++)   //接收8次還原一個(gè)字節(jié)數(shù)據(jù)
        {
                buf = buf >> 1;//接收前,先將接收緩沖區(qū)右移
                DS18B20 = 0;//將DQ總線拉低并保持1μs-15μs,當(dāng)總線控制器把數(shù)據(jù)線從高電平拉到低電平時(shí),讀時(shí)序開始。   
                _nop_(); //保持至少1μs-15μs       
                _nop_(); //保持至少1μs-15μs        
                _nop_(); //保持至少1μs-15μs       
                _nop_(); //保持至少1μs-15μs 
                 
                DS18B20 = 1;//總線被釋放,被10K的上拉電阻拉高,在總線控制器發(fā)出讀時(shí)序后,
                //DS18B20通過拉高或拉低總線上來傳輸1或0。當(dāng)傳輸邏輯0結(jié)束后,總線將被釋放,通過上拉電阻回到上升沿狀態(tài)。
                //從DS18B20輸出的數(shù)據(jù)在讀時(shí)序的下降沿出現(xiàn)后15μs內(nèi)有效。
                _nop_();         //保持至少1μs-15μs
                _nop_();         //保持至少1μs-15μs
                _nop_();         //保持至少1μs-15μs
                _nop_();         //保持至少1μs-15μs
                _nop_();         //保持至少1μs-15μs
                _nop_();         //保持至少1μs-15μs
                _nop_();         //保持至少1μs-15μs
                _nop_();         //保持至少1μs-15μs
                _nop_();         //保持至少1μs-15μs
                _nop_();         //保持至少1μs-15μs
                _nop_();         //保持至少1μs-15μs
                _nop_();         //保持至少1μs-15μs
                if(DS18B20 == 1) buf |= 0x80;//如果接收到數(shù)據(jù)為1,從最高位往右移
                i = 12; //保持至少60μs
                while(i > 0)//保持至少60μs
                i--;      //保持至少60μs
        }
        return buf;  //接收緩沖區(qū)參數(shù)返回
}
//---------------------------------------
//名稱:寫一字節(jié)函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
void WriteByte(unsigned char dat)
{
        unsigned int i;//定義無符號(hào)整型變量,用于下面的時(shí)序延時(shí)
        unsigned char j;//定義一個(gè)無符號(hào)的字符型變量j
        for(j = 0;j < 8;j++)//一個(gè)字節(jié)為8位,所以循環(huán)八次寫操作
        {       
                //傳過來的要寫的數(shù)據(jù)dat(這里的dat為形參,實(shí)際調(diào)用該函數(shù)時(shí)會(huì)發(fā)送來實(shí)參)
                //與0x01做與運(yùn)算,可以獲得數(shù)據(jù)的最低位,如果if的表達(dá)式為真,說明數(shù)據(jù)的最低
                //位為1,則進(jìn)行寫1操作,否則進(jìn)行寫0操作。 
                if(dat & 0x01)//進(jìn)行寫1操作
                {    
                        DS18B20 =0;//將DQ總線拉低并保持1μs-15μs  
                        _nop_();   //保持至少1μs-15μs 
                        _nop_();   //保持至少1μs-15μs  
                        _nop_();   //保持至少1μs-15μs  
                        _nop_();   //保持至少1μs-15μs
                          
                        DS18B20 = 1;//總線被釋放,被10K的上拉電阻拉高     
                        i = 14;     //延時(shí)操作,使DQ總線保持至少60μs的低電平
                        while(i > 0)//延時(shí)操作,使DQ總線保持至少60μs的低電平
                        i--;      //延時(shí)操作,使DQ總線保持至少60μs的低電平
                }
                else   //進(jìn)行寫0操作
                {          
                        DS18B20 = 0;//將DQ總線拉低并保持至少60μs      
                        i = 14;  //延時(shí)操作,使DQ總線保持至少60μs的低電平  
                        while(i > 0)//延時(shí)操作,使DQ總線保持至少60μs的低電平  
                        i--;     //延時(shí)操作,使DQ總線保持至少60μs的低電平
                               
                        DS18B20 = 1;//總線被釋放,被10K的上拉電阻拉高       
                        _nop_();    //保持至少1μs
                        _nop_();    //保持至少1μs
                        _nop_();    //保持至少1μs
                        _nop_();    //保持至少1μs
                }
                dat = dat >> 1;//傳過來的要寫的數(shù)據(jù)dat做右移一位運(yùn)算,
                //之后循環(huán)上面的程序8次,8次之后就可以將一個(gè)字節(jié)的數(shù)據(jù)寫入DS18B20中
        }
}
//---------------------------------------
//名稱:DS18B20溫度轉(zhuǎn)換函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
bit Convert(void)
{  
        if(Reset() == 1)          //復(fù)位DS18B20
        { 
                WriteByte(0xcc);  //寫入跳過序列號(hào)命令字 Skip Rom
                WriteByte(0x44);  //寫入溫度轉(zhuǎn)換命令字 Convert T
                return 1;            //啟動(dòng)溫度轉(zhuǎn)換成功
        }
        else
        { 
                return 0;            //啟動(dòng)溫度轉(zhuǎn)換失敗
        }
}
//---------------------------------------
//名稱:轉(zhuǎn)換結(jié)束處理函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
void ReadFlash(void)
{  
        unsigned char Lsb,Msb;
        if(Reset() == 1)          //復(fù)位DS18B20
        {
                WriteByte(0xcc);  //寫入跳過序列號(hào)命令字 Skip Rom
                WriteByte(0xbe);  //寫入讀取數(shù)據(jù)令字 Read Scratchpad
                Lsb = ReadByte();  //讀出第一個(gè)字節(jié)暫存于LSB
                Msb = ReadByte();  //讀出第二個(gè)字節(jié)暫存于MSB
                temp1 = Lsb & 0x0f;  //temp1內(nèi)裝溫度參數(shù)的小數(shù)部分
                temp2 = (Lsb >> 4) | (Msb << 4);//temp2內(nèi)裝溫度參數(shù)的整數(shù)部
        }
        else
        {
                temp1 = 0;     //復(fù)位失敗,溫度參數(shù)清零
                temp2 = 0;     //復(fù)位失敗,溫度參數(shù)清零
        }
}
//---------------------------------------
//名稱:1602液晶忙檢測(cè)函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
void LCD1602_busy(void)
{
        P0_7 = 1;              //將P0.7置1,為讀狀態(tài)做準(zhǔn)備
        RS = 0;                //RS=0、RW=1、E=1時(shí),忙信號(hào)輸出到DB7,由P0.7讀入
        RW = 1;                //RS=0、RW=1、E=1時(shí),忙信號(hào)輸出到DB7,由P0.7讀入
        E = 1;                 //RS=0、RW=1、E=1時(shí),忙信號(hào)輸出到DB7,由P0.7讀入
        while(P0_7 == 1);      //由P0.7讀入1,表示1602液晶忙,需要等待
        E = 0;                 //讀完以后,恢復(fù)E的電平
}
//---------------------------------------
//名稱:1602寫命令函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
void LCD1602_Write_com(unsigned char combuf)
{
        RS = 0;                //選擇指令寄存器
        RW = 0;                //選擇寫狀態(tài)
        P0 = combuf;           //將命令字通過P0口送至DB
        E = 1;                 //E高電平將命令字寫入1602液晶
        E = 0;                 //寫完以后,恢復(fù)E的電平
}
//---------------------------------------
//名稱:1602寫命令函數(shù)(帶忙檢測(cè))
//作者:XD
//日期:2014-04-03
//---------------------------------------
void LCD1602_Write_com_busy(unsigned char combuf)
{
        LCD1602_busy();            //調(diào)用忙檢測(cè)函數(shù)
        LCD1602_Write_com(combuf); //調(diào)用忙檢測(cè)函數(shù)
}
//---------------------------------------
//名稱:1602寫數(shù)據(jù)函數(shù)(帶忙檢測(cè))
//作者:XD
//日期:2014-04-03
//---------------------------------------
void LCD1602_Write_data_busy(unsigned char databuf)
{
        LCD1602_busy();      //調(diào)用忙檢測(cè)函數(shù)
        RS = 1;                //選擇數(shù)據(jù)寄存器
        RW = 0;                //選擇寫狀態(tài)
        P0 = databuf;          //將命令字通過P0口送至DB
        E = 1;                 //E高電平將命令字寫入1602液晶
        E = 0;                 //寫完以后,恢復(fù)E的電平
}
//---------------------------------------
//名稱:1602液晶顯示地址寫函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
void LCD1602_Write_address(unsigned char x,unsigned char y)
{
        x &= 0x0f;             //列地址限制在0-15間
        y &= 0x01;             //行地址限制在0-1間
        if(y == 0)             //如果是第一行
        LCD1602_Write_com_busy(x | 0x80);        //將列地址寫入
        else                 //如果是第二行
        LCD1602_Write_com_busy((x + 0x40) | 0x80); //將列地址寫入
}
//---------------------------------------
//名稱:1602液晶初始化函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
void LCD1602_init(void)
{
        Delay(150);               //調(diào)用延時(shí)函數(shù)
        LCD1602_Write_com(0x38);       //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
        Delay(50);                //調(diào)用延時(shí)函數(shù)
        LCD1602_Write_com(0x38);       //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
        Delay(50);                //調(diào)用延時(shí)函數(shù)
        LCD1602_Write_com(0x38);       //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
        LCD1602_Write_com_busy(0x38);  //8位數(shù)據(jù)總線,兩行顯示模式,5*7點(diǎn)陣顯示
        LCD1602_Write_com_busy(0x08);  //顯示功能關(guān),無光標(biāo)
        LCD1602_Write_com_busy(0x01);  //清屏
        LCD1602_Write_com_busy(0x06);  //寫入新的數(shù)據(jù)后,光標(biāo)右移,顯示屏不移動(dòng)
        LCD1602_Write_com_busy(0x0C);  //顯示功能開,無光標(biāo)
}
//---------------------------------------
//名稱:1602液晶指定地址顯示函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
void LCD1602_Disp(unsigned char x,unsigned char y,unsigned char buf)
{
        LCD1602_Write_address(x,y);    //先將地址信息寫入
        LCD1602_Write_data_busy(buf);  //再寫入要顯示的數(shù)據(jù)
}
//---------------------------------------
//名稱:串口發(fā)送函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
void UARTSendbyte(unsigned char bytebuf)
{
        SBUF = bytebuf;//緩沖區(qū)裝載要發(fā)送的字節(jié)
        while(TI == 0);//等待發(fā)送完畢,TI標(biāo)志位會(huì)置1
        TI = 0;//清零發(fā)送完成標(biāo)志位
 
}
//---------------------------------------
//名稱:主函數(shù)
//作者:XD
//日期:2014-04-03
//---------------------------------------
void main(void) //主函數(shù),單片機(jī)啟動(dòng)后就是從這個(gè)函數(shù)開始運(yùn)行的
{
        LCD1602_init();        //調(diào)用1602液晶初始化函數(shù)
        //*****USART串口初始化*****
        /*
         * 串行口控制寄存器SCON
         * D7--SM0 = 0;SM0 = 0;SM1 = 1;工作方式1
         * D6--SM1 = 1;SM0 = 0;SM1 = 1;工作方式1
         * D5--SM2 = 0;接收到單個(gè)字節(jié),RI就置位
         * D4--REN = 1;允許串行口接收
         * D3--TB8 = 0;方式2和方式3時(shí),為發(fā)送的第9位數(shù)據(jù),也可以做奇偶校驗(yàn)位
         * D2--RB8 = 0;方式2和方式3時(shí),為發(fā)送的第9位數(shù)據(jù);方式1時(shí),為接收到的停止位
         * D1--TI = 0;發(fā)送中斷標(biāo)志位,必須由軟件清零
         * D0--RI = 0;接收中斷標(biāo)志位,必須由軟件清零
         */
        SCON = 0x50;
        TMOD|= 0x20;//定時(shí)器工作方式2                 
        PCON|= 0x80;//波特率=定時(shí)器1溢出率/16                                                        
        TH1 = 0xFD;//10位異步通信方式、1位起始位0、8位數(shù)據(jù)位和1位停止位1
        TL1 = 0xF3;//波特率19200、11.0592MHz
        TR1 = 1;                                                           
        //**************************
      
        while(1)//死循環(huán)
        {                  
                if(Convert() == 1)//啟動(dòng)轉(zhuǎn)換
                { 
                        ReadFlash();//讀取溫度    
                        if(temp2 > 99) temp2 = 99;//當(dāng)溫度超過99℃時(shí),temp2被賦值99,限制最高測(cè)量溫度為99攝氏度  
                        if(temp1 > 15) temp1=0;      
                        LCD1602_Disp(0,1,temp2 / 10 + '0');  //溫度整數(shù)部分十位   
                        LCD1602_Disp(1,1,temp2 % 10 + '0');  //溫度整數(shù)部分個(gè)位
                        LCD1602_Disp(2,1,'.');  //. 
                        LCD1602_Disp(3,1,table[temp1] + '0');  //溫度小數(shù)A部分
                        LCD1602_Disp(4,1,0xdf);   //.
                        LCD1602_Disp(5,1,0x43);   //C
                }
                UARTSendbyte(temp2);   
        }
}

關(guān)閉窗口

相關(guān)文章

主站蜘蛛池模板: 性视频一区| 国产乱码精品一区二区三区忘忧草 | 伊人中文网| 亚洲精品一区二区三区四区高清 | 国产伦精品一区二区三区精品视频 | 国产精品视频免费播放 | 日韩精品在线一区 | 欧美成人猛片aaaaaaa | 国产精品99久久久久久www | 亚洲免费毛片 | 欧美日韩精品中文字幕 | 欧美性精品 | 色接久久 | 久久se精品一区精品二区 | 国产伦精品一区二区三区在线 | 亚洲国产成人精品久久 | 国产日批 | 日韩精品一区二 | 草草视频在线观看 | 欧美日韩一本 | 天天影视亚洲综合网 | 欧美日韩综合一区 | 91精品久久久久久久久中文字幕 | 国产色片在线 | 久久国产精品视频 | 欧州一区 | 亚洲永久| 久久久久久亚洲精品 | 涩涩导航 | 精品国产一区一区二区三亚瑟 | 国产成人免费视频网站高清观看视频 | 国产日产精品一区二区三区四区 | 91久久精品国产91久久 | 综合精品在线 | 成人网av| 欧美国产精品一区二区三区 | 亚洲精品一区二区三区蜜桃久 | 成人网址在线观看 | 亚洲久久久 | 在线中文视频 | 精品国产第一区二区三区 |