找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2742|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

單片機溫度監(jiān)控系統(tǒng) 電機轉(zhuǎn)動 匯編與C語言源程序注釋很詳細(xì) Proteus仿真圖

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:766947 發(fā)表于 2021-6-10 22:06 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
一個溫度監(jiān)控系統(tǒng)


單片機源程序如下:
  1. #include<reg51.h>                                //預(yù)處理命令,定義SFR的頭
  2. #include <math.h>
  3. #define uchar unsigned char            //定義縮寫字符uchar
  4. #define uint   unsigned int                //定義縮寫字符uint
  5. #define lcd_data P0            //定義LCD1602接口 P0
  6. sbit DQ =P1^7;                             //將DQ位定義為P1.7引腳
  7. sbit lcd_RS=P2^0;                           //將RS位定義為P2.0引腳
  8. sbit lcd_RW=P2^1;                           //將RW位定義為P2.1引腳
  9. sbit lcd_EN=P2^2;                           //將EN位定義為P2.2引腳        

  10. sbit PWM=P3^7;                 //將PWM定義為P3.7引腳
  11. sbit  D=P3^6;                  //將d定義為P3.6引腳,轉(zhuǎn)向選擇位
  12. uchar t[2],speed,temperature;  //用來存放溫度值,測溫程序就是通過這個數(shù)組與主函數(shù)通信的
  13. uchar DS18B20_is_ok;
  14. uchar TempBuffer1[12]={0x20,0x20,0x20,0x20,0xdf,0x43,'\0'};
  15. uchar tab[16]={0x20,0x20,0x20,0x54,0x20,0x4d,0x6f,0x6e,0x69,0x74,0x6f,0x72,'\0'};
  16.                                                                 //顯示"T Monitor"        
  17. /**********lcd顯示子程序************/

  18. void delay_20ms(void)          /*延時20ms函數(shù)*/
  19. {
  20.    uchar i,temp;               //聲明變量i,temp
  21.    for(i = 20;i > 0;i--)       //循環(huán)
  22.    {
  23.     temp = 248;                //給temp賦值248
  24.     while(--temp);             //temp減1是否等于0,否則繼續(xù)執(zhí)行該行
  25.     temp = 248;                //給temp賦值248
  26.     while(--temp);             //temp減1是否等于0,否則繼續(xù)執(zhí)行該行
  27.     }
  28. }
  29. void delay_38us(void)          /*延時38us函數(shù)*/
  30. {   uchar temp;                //聲明變量temp
  31.     temp = 18;                 //給temp賦值
  32.     while(--temp);             //temp減1是否等于0,否則繼續(xù)執(zhí)行該行
  33. }
  34. void delay_1520us(void)         /*延時1520us函數(shù)*/
  35. {  uchar i,temp;                //聲明變量i,temp
  36.    for(i = 3;i > 0;i--)         //循環(huán)
  37.    {
  38.     temp = 252;                 //給temp賦值
  39.     while(--temp);              //temp減1是否等于0,否則繼續(xù)執(zhí)行該行
  40.     }
  41. }
  42. uchar lcd_rd_status( )          /*讀取lcd1602的狀態(tài),主要用于判斷忙*/
  43. {
  44. uchar tmp_sts;                 //聲明變量tmp_sts
  45. lcd_data = 0xff;               //初始化P3口
  46. lcd_RW = 1;                    //RW =1  讀      
  47. lcd_RS = 0;                    //RS =0  命令,合起來表示讀命令(狀態(tài))
  48. lcd_EN = 1;                    //EN=1,打開EN,LCD1602開始輸出命令數(shù)據(jù),100nS之后命令數(shù)據(jù)有效
  49. tmp_sts = lcd_data;            //讀取命令到tmp_sts
  50. lcd_EN = 0;                    //關(guān)掉LCD1602
  51. lcd_RW = 0;                    //把LCD1602設(shè)置成寫
  52. return tmp_sts;                //函數(shù)返回值tmp_sts
  53. }
  54. void lcd_wr_com(uchar command )  /*寫一個命令到LCD1602*/
  55. {
  56.   while(0x80&lcd_rd_status()); //寫之前先判斷LCD1602是否忙,看讀出的命令的最高位是否為1,為1表示忙,繼續(xù)讀,直到不忙
  57.   lcd_RW = 0;
  58.   lcd_RS = 0;                  //RW=0,RS=0 寫命令
  59.   lcd_data = command;          //把需要寫的命令寫到數(shù)據(jù)線上
  60.   lcd_EN = 1;  
  61.   lcd_EN = 0;                  //EN輸出高電平脈沖,命令寫入
  62. }
  63. void lcd_wr_data(uchar sjdata )  /*寫一個顯示數(shù)據(jù)到lcd1602*/
  64. {
  65. while(0x80&lcd_rd_status());  //寫之前先判斷l(xiāng)cd1602是否忙,看讀出的命令的最高位是否為1,為1表示忙,繼續(xù)讀,直到不忙
  66. lcd_RW = 0;
  67. lcd_RS = 1;                   //RW=0,RS=1 寫顯示數(shù)據(jù)
  68. lcd_data = sjdata ;            //把需要寫的顯示數(shù)據(jù)寫到數(shù)據(jù)線上
  69. lcd_EN = 1;
  70. lcd_EN = 0;                   //EN輸出高電平脈沖,命令寫入
  71. lcd_RS = 0;                 
  72. }
  73. void Init_lcd(void)            /*初始化lcd1602*/
  74. {
  75.   delay_20ms();                //調(diào)用延時
  76.   lcd_wr_com(0x38);            //設(shè)置16*2格式,5*8點陣,8位數(shù)據(jù)接口
  77.   delay_38us();                //調(diào)用延時
  78.   lcd_wr_com(0x0c);            //開顯示,不顯示光標(biāo)
  79.   delay_38us();                //調(diào)用延時
  80.   lcd_wr_com(0x01);            //清屏
  81.   delay_1520us();              //調(diào)用延時
  82.   lcd_wr_com(0x06);            //顯示一個數(shù)據(jù)后光標(biāo)自動+1
  83. }        
  84. void GotoXY(uchar x, uchar y)  //設(shè)定位置,x為行,y為列
  85. {
  86.         if(y==0)                                   //如果y=0,則顯示位置為第一行
  87.                 lcd_wr_com(0x80|x);
  88.         if(y==1)
  89.                 lcd_wr_com(0xc0|x);           //如果y=1,則顯示位置為第二行
  90. }

  91. void Print(uchar *str)                   //顯示字符串函數(shù)
  92. {
  93.         while(*str!='\0')                   //判斷字符串是否顯示完
  94.         {
  95.                 lcd_wr_data(*str);           //寫數(shù)據(jù)
  96.                 str++;                                   
  97.         }
  98. }
  99. void LCD_Print(uchar x, uchar y, uchar *str)//x為行值,y為列值,str是要顯示的字符串   
  100. {
  101.   GotoXY(x,y);                                   //設(shè)定顯示位置
  102.   Print(str);                                   //顯示字符串
  103. }
  104.                                                    
  105. /*****************系統(tǒng)顯示子函數(shù)*****************/

  106. void covert1()                       //溫度轉(zhuǎn)化程序
  107. {
  108.    uchar x=0x00;                           //變量初始化
  109.    if(t[1]>0x07)               //判斷正負(fù)溫度
  110.    {
  111.     TempBuffer1[0]=0x2d;           //0x2d為"-"的ASCII碼
  112.         t[1]=~t[1];                               //負(fù)數(shù)的補碼
  113.         t[0]=~t[0];                        //換算成絕對值
  114.         x=t[0]+1;                                   //加1
  115.         t[0]=x;                                           //把x的值送入t[0]
  116.         if(x>255)                  //如果x大于255
  117.         t[1]++;                                           //t[1]加1
  118.    }
  119.    else
  120.     TempBuffer1[0]=0x2b;           //0xfe為變"+"的ASCII碼
  121.     t[1]<<=4;                           //將高字節(jié)左移4位
  122.     t[1]=t[1]&0x70;                       //取出高字節(jié)的3個有效數(shù)字位
  123.     x=t[0];                                           //將t[0]暫存到X,因為取小數(shù)部分還要用到它
  124.     x>>=4;                                           //右移4位
  125.     x=x&0x0f;                                   //和前面兩句就是取出t[0]的高四位        
  126.     t[1]=t[1]|x;                           //將高低字節(jié)的有效值的整數(shù)部分拼成一個字節(jié)
  127.     temperature=t[1];
  128.     TempBuffer1[1]=t[1]/100+0x30;//加0x30 為變 0~9 ASCII碼
  129.     if(TempBuffer1[1]==0x30)          //如果百位為0
  130.     TempBuffer1[1]=0xfe;         //百位數(shù)消隱
  131.     TempBuffer1[2]=(t[1]%100)/10+0x30;//分離出十位
  132.     TempBuffer1[3]=(t[1]%100)%10+0x30;//分離出個位                                                                        
  133. }                        
  134. /*******************DS18B20函數(shù)**********************/

  135. void delay_18B20(uint i)                        //延時程序
  136. {
  137.         while(i--);
  138. }
  139. void Init_DS18B20(void)                          //ds18b20初始化函數(shù)
  140. {
  141.          uchar x=0;
  142.          DQ = 1;                                          //DQ復(fù)位
  143.          delay_18B20(8);                                  //稍做延時
  144.          DQ = 0;                                          //單片機將DQ拉低
  145.          delay_18B20(80);                                 //精確延時大于480us
  146.          DQ = 1;                                          //拉高總線
  147.          delay_18B20(14);
  148.          x=DQ;                                            //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
  149.          delay_18B20(20);
  150. }
  151. uchar ReadOneChar(void)                                 //ds18b20讀一個字節(jié)函數(shù)
  152. {
  153.         unsigned char i=0;
  154.         unsigned char dat0 = 0;
  155.         for (i=8;i>0;i--)
  156.          {
  157.                   DQ = 0;                    //讀前總線保持為低
  158.                   dat0>>=1;
  159.                   DQ = 1;                    //開始讀總線釋放
  160.                   if(DQ)                                         //從DS18B20總線讀得一位
  161.                   dat0|=0x80;
  162.                   delay_18B20(4);                         //延時一段時間
  163.          }
  164.          return(dat0);                                     //返回數(shù)據(jù)
  165. }
  166. void WriteOneChar(uchar dat1)                 //ds18b20寫一個字節(jié)函數(shù)
  167. {
  168.          uchar i=0;
  169.          for (i=8; i>0; i--)
  170.          {
  171.                   DQ = 0;                                                 //開始寫入DS18B20總線要處于復(fù)位(低)狀態(tài)
  172.                  DQ = dat1&0x01;                                 //寫入下一位
  173.             delay_18B20(5);
  174.                  DQ = 1;                                                 //重新釋放總線
  175.             dat1>>=1;                                         //把一個字節(jié)分成8個BIT環(huán)移給DQ
  176. }
  177. }
  178. void ReadTemperature()                            //讀取ds18b20當(dāng)前溫度
  179. {        
  180.         delay_18B20(80);                //延時一段時間
  181.         Init_DS18B20();        
  182.         WriteOneChar(0xCC);                // 跳過讀序號列號的操作
  183.         WriteOneChar(0x44);           // 啟動溫度轉(zhuǎn)換
  184.         delay_18B20(80);              // 延時一段時間
  185.         Init_DS18B20();                                //DS18B20初始化
  186.         WriteOneChar(0xCC);                 //跳過讀序號列號的操作
  187.         WriteOneChar(0xBE);                 //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
  188.         delay_18B20(80);                            //延時一段時間
  189.     t[0]=ReadOneChar();                //讀取溫度值低位
  190.         t[1]=ReadOneChar();               //讀取溫度值高位
  191. }
  192. void delay_motor(uchar i)           //延時函數(shù)
  193. {
  194.         uchar j,k;                           //變量i、k為無符號字符數(shù)據(jù)類型
  195.         for(j=i;j>0;j--)                     //循環(huán)延時
  196.         for(k=200;k>0;k--);                 //循環(huán)延時
  197. }
  198. /*******************電機轉(zhuǎn)動程序*******************/
  199. void motor(uchar tmp)            
  200. {   
  201.         uchar x;
  202.            if(TempBuffer1[0]==0x2b)                //溫度為正數(shù)
  203.         {
  204.             if(tmp<25)                                    //溫度小于25度
  205.                 {
  206.                  D=0;                                                //電機停止轉(zhuǎn)動
  207.                  PWM=0;
  208.                 }
  209.                 else if(tmp>50)                                //溫度大于50度,全速轉(zhuǎn)動
  210.                 {
  211.                  D=0;                                                  //D置0
  212.                  PWM=1;                                    //正轉(zhuǎn),PWM=1
  213.               x=250;                                   //時間常數(shù)為x
  214.               delay_motor(x);            //調(diào)延時函數(shù)
  215.                  PWM=0;                                   // PWM=0
  216.               x=5;                                        //時間常數(shù)為x
  217.              delay_motor(x);            //調(diào)延時函數(shù)
  218.                 }
  219.                 else
  220.                 {
  221.                  D=0;                                                  //D置0
  222.                  PWM=1;                                    //正轉(zhuǎn),PWM=1
  223.               x=5*tmp;                           //時間常數(shù)為x
  224.               delay_motor(x);                //調(diào)延時函數(shù)
  225.                  PWM=0;                                   // PWM=0
  226.               x=255-5*tmp;                       //時間常數(shù)為255-x
  227.              delay_motor(x);                   //調(diào)延時函數(shù)
  228.             }
  229.         }
  230.            else if (TempBuffer1[0]==0x2d)  //溫度小于0,反轉(zhuǎn)
  231.         {
  232.                   D=1;                                                
  233.                  PWM=0;                                   // PWM=0
  234.              x=5*tmp;                                    //時間常數(shù)為tmp
  235.                 delay_motor(x);                        //調(diào)延時函數(shù)
  236.                 PWM=1;                                   // PWM=1
  237.              x=255-5*tmp;                               //時間常數(shù)為255- tmp
  238.                 delay_motor(x);                        //調(diào)延時函數(shù)
  239.           }
  240. }        
  241.   
  242. void delay(unsigned int x)     //延時函數(shù)名
  243. {
  244.   unsigned char i;             //定義變量i的類型
  245.   while(x--)                         //x自減1
  246.     {
  247.       for(i=0;i<123;i++){;}    //控制延時的循環(huán)
  248.     }
  249. }                                                                                   

  250. /*************************main主程序*********************/
  251. void main(void)
  252. {
  253.     delay_20ms();                      //系統(tǒng)延時20ms啟動
  254.         ReadTemperature();                                   //啟動DS18B20
  255.            Init_lcd();                        //調(diào)用LCD初始化函數(shù)
  256.         LCD_Print(0,0,tab);                                   //液晶初始顯示
  257.         delay(1000);                                           //延時一段時間
  258.         while(1)
  259.     {        
  260.                   ReadTemperature();                           //讀取溫度,溫度值存放在一個兩個字節(jié)的數(shù)組中,
  261.             delay_18B20(100);
  262.             covert1();                                           //數(shù)據(jù)轉(zhuǎn)化
  263.             LCD_Print(4,1,TempBuffer1);   //顯示溫度
  264.                 motor(temperature);                   //電機轉(zhuǎn)動
  265.         }
  266. }
復(fù)制代碼
  1. TEMPER_L  EQU   31H           ;用于保存讀出溫度的低字節(jié)
  2. TEMPER_H  EQU   30H           ;用于保存讀出溫度的高字節(jié)
  3. T_INTEGER EQU   32H           ;溫度的整數(shù)部分(integer)
  4. T_IN_BAI  EQU   35H                          ;溫度的百位
  5. T_IN_SHI  EQU        36H                          ;溫度的十位
  6. T_IN_GE   EQU   37H                          ;溫度的個位
  7. FLAG      BIT   33H           ;標(biāo)志位
  8. TEMPHC    EQU   34H           ;正、負(fù)溫度值標(biāo)記
  9. SPEED     EQU   45H                          ;電機的速度調(diào)節(jié)位
  10. RW        BIT   P2.1          ;LCD1602R/W引腳由P2.1引腳控制
  11. RS        BIT   P2.0          ;LCD1602RS引腳由P2.0引腳控制         
  12. E         BIT   P2.2          ;LCD1602E引腳由P2.2引腳控制
  13. DQ        BIT   P1.7          ;DS18B20數(shù)據(jù)線
  14. PWM       BIT   P3.6          ;定義速度控制位PWMP3.7
  15. D         BIT  P3.7           ;定義方向控制位P3.2
  16.         ORG   0000H                          ;在0000H單元存放轉(zhuǎn)移指令
  17.         SJMP  MAIN                          ;轉(zhuǎn)移到主程序
  18.                 ORG   0060H                          ;主程序從0060H開始
  19. MAIN:   LCALL DELAY20ms                  ;系統(tǒng)延時20ms啟動
  20.                 LCALL INIT                          ;調(diào)用LCD初始化函數(shù)
  21.                 LCALL MENU                          ;調(diào)用液晶初始界面
  22.                 LCALL READ_TEM                  ;開啟DS18B20
  23.               LCALL DELAY1S                  ;調(diào)用1s延時,使DS18B20能完全啟動
  24. LOOP:        LCALL READ_TEM                  ;讀取溫度,溫度值存放
  25.             LCALL CONVTEMP                  ;調(diào)用溫度轉(zhuǎn)化程序
  26.                 LCALL DISPLAY                  ;調(diào)用顯示程序
  27.                 LCALL MOTOR                          ;調(diào)用電機轉(zhuǎn)動程序
  28.                 LJMP LOOP                           ;循環(huán)調(diào)用
  29. DELAY1S:MOV   R5,#10                        ;1S延時程序,給R5賦值,外循環(huán)控制
  30. DEL1:   MOV   R6,#200              ;中循環(huán)控制
  31. DEL2:   MOV   R7,#250              ;內(nèi)循環(huán)控制
  32. DEL3:   DJNZ  R7,DEL3         ;內(nèi)循環(huán)體  
  33.         DJNZ  R6,DEL2         ;中循環(huán)體
  34.         DJNZ  R5,DEL1         ;外循環(huán)體
  35.         RET                                         ;子程序返回
  36. ;------------------------電機轉(zhuǎn)動程序----------------------
  37. MOTOR:        MOV A,T_INTEGER                  ;溫度轉(zhuǎn)化的整數(shù)暫存于A中
  38.               MOV B,#5                          ;給寄存器賦值立即數(shù)5
  39.                   MUL AB                                  ;整數(shù)*5,提高轉(zhuǎn)速的占空比
  40.                  MOV SPEED,A                                          
  41.               MOV A,TEMPHC                  ;把正、負(fù)溫度值標(biāo)記暫存于A中
  42.                   CJNE A,#0AH,NEG                  ;判斷溫度值標(biāo)記是正還是負(fù),如果是正,就順序執(zhí)行;否則,跳轉(zhuǎn)到NEG
  43.               CLR C                                  ;把進(jìn)位清零
  44. WIN:          MOV A,T_INTEGER                  ;溫度轉(zhuǎn)化的整數(shù)暫存于A中
  45.                   SUBB A,#25                          ;判斷溫度是否超過25度
  46.                   JNC POS                                  ;溫度大于25度,跳轉(zhuǎn)到POS
  47.                   SETB D                                  ;方向控制端置1
  48.                   SETB PWM                          ;PWM端置1,電機停止轉(zhuǎn)動
  49.               JMP REND                          ;子程序返回
  50. POS:          MOV A,T_INTEGER                  ;溫度轉(zhuǎn)化的整數(shù)暫存于A中
  51.                   SUBB A,#50                          ;判斷溫度是否大于50度
  52.                   JNC POS2                          ;溫度大于50度,跳轉(zhuǎn)到POS2
  53. POS1:        SETB D                                  ;方向控制端置1
  54.                   CLR PWM                        ;正轉(zhuǎn),PWM=0
  55.               MOV A, SPEED          ;時間常數(shù)為SPEED
  56.               LCALL  DELAY_MOTOR    ;調(diào)用電機轉(zhuǎn)動延時子程序
  57.               SETB  PWM                        ;電機停止轉(zhuǎn)動,PWM=1
  58.               MOV A, #255                     ;時間常數(shù)為255-TMP
  59.               SUBB A, SPEED
  60.               LCALL  DELAY_MOTOR    ;調(diào)用電機延時子程序
  61.               JMP REND                             ;子程序返回
  62. POS2:         MOV SPEED,#250                  ;SPEED賦值為250
  63.               JMP POS1                          ;跳轉(zhuǎn)到POS1
  64. NEG:          CLR   D                                  ;方向控制端置0
  65.                   SETB  PWM             ;反轉(zhuǎn),PWM=1
  66.               MOV A, SPEED              ;時間常數(shù)為SPEED
  67.               LCALL  DELAY_MOTOR    ;調(diào)用電機延時子程序
  68.               CLR PWM               ;PWM=0
  69.               MOV A, #255                     ;時間常數(shù)為255-TMP
  70.               SUBB A, SPEED
  71.                   LCALL  DELAY_MOTOR    ;調(diào)用延時子程序
  72. REND:   RET                                    ;子程序返回
  73. ;---------------------電機轉(zhuǎn)動延時子程序--------------------------
  74. DELAY_MOTOR:MOV R6, #5              ;設(shè)循環(huán)次數(shù)
  75. D1:                   DJNZ R6, D1     ;循環(huán)等待
  76.                       DJNZ ACC,D1     ;循環(huán)等待
  77.                       RET             ;子程序返回
  78. ;---------------------溫度轉(zhuǎn)化程序------------------------------  
  79. CONVTEMP: MOV  A,TEMPER_H       ;判溫度是否零下
  80.           ANL  A,#08H                        
  81.           JZ  TEMPC1                 ;溫度沒有零下,跳轉(zhuǎn)到TEMPC1
  82.           CLR  C                                ;進(jìn)位清零
  83.           MOV  A,TEMPER_L       ;溫度的低字節(jié)二進(jìn)制數(shù)求補
  84.           CPL  A                     ;取反
  85.           ADD  A,#01H                        ;加1
  86.           MOV  TEMPER_L,A               
  87.           MOV  A,TEMPER_H                ;溫度的高字節(jié)二進(jìn)制數(shù)求補(雙字節(jié))
  88.           CPL  A                                ;取反
  89.           ADDC  A,#00H                        
  90.           MOV  TEMPER_H,A
  91.                   MOV   TEMPHC,#0BH                ;負(fù)溫度標(biāo)志
  92.           LJMP  TEMPC11                        ;跳轉(zhuǎn)到TEMPC11
  93. TEMPC1:   MOV  TEMPHC,#0AH             ;正溫度標(biāo)志                          
  94. TEMPC11:  MOV  A,TEMPER_L      
  95.           ANL  A,#0F0H          ;取出高四位
  96.           SWAP  A
  97.           MOV  TEMPER_L,A
  98.           MOV  A,TEMPER_H       ;取出低四位
  99.           ANL  A,#0FH
  100.           SWAP  A
  101.           ORL  A,TEMPER_L       ;把溫度的高字節(jié)和低字節(jié)重新組合為一個字節(jié)
  102.           MOV  T_INTEGER,A                ;把組合成字節(jié)存于T_INTEGER
  103.           MOV B,#100                        ;把溫度整數(shù)部分化為BCD碼
  104.                   DIV AB
  105.                   MOV T_IN_BAI,A
  106.                   MOV A,B
  107.                   MOV B ,#10
  108.                   DIV AB
  109.                   MOV T_IN_SHI,A
  110.                   MOV T_IN_GE,B
  111.           RET
  112. ;----------------------讀溫度程序---------------------------------
  113. READ_TEM: LCALL   Set_18B20                  ;DS18B20初始化
  114.           MOV     A,#0CCH         ;跳過ROM匹配
  115.           LCALL   WRITE_1820          ;寫DS18B20的子程序
  116.           MOV     A,#44H          ;發(fā)出溫度轉(zhuǎn)換命令
  117.           LCALL   WRITE_1820          ;寫DS18B20的子程序
  118.           LCALL   Set_18B20       ;準(zhǔn)備讀溫度前先初始化
  119.           MOV     A,#0CCH         ;跳過ROM匹配
  120.           LCALL   WRITE_1820          ;寫DS18B20的子程序
  121.           MOV     A,#0BEH         ;發(fā)出讀溫度命令
  122.           LCALL   WRITE_1820          ;寫DS18B20的子程序
  123.           LCALL   READ_1820                  ;讀DS18B20的程序
  124.               RET                                          ;子程序返回
  125. ;--------------------------DS18B20初始化程序--------------------------
  126. Set_18B20:SETB    DQ                          ;數(shù)據(jù)線拉高
  127.           NOP
  128.           CLR     DQ                          ;賦值數(shù)據(jù)線低電平
  129.           MOV     R2,#255         ;主機發(fā)出延時500微秒的復(fù)位低脈沖
  130.           DJNZ    R2,$
  131.           SETB    DQ              ;拉高數(shù)據(jù)線
  132.           MOV     R2,#30
  133.           DJNZ    R2,[        DISCUZ_CODE_3        ]nbsp;           ;延時60us等待DS18B20回應(yīng)
  134.           JNB     DQ,INIT1
  135.           JMP     Set_18B20       ;超時而沒有響應(yīng),重新初始化
  136. INIT1:    MOV     R2,#120
  137.           DJNZ    R2,[        DISCUZ_CODE_3        ]nbsp;           ;延時240us
  138.           JB      DQ,INIT2        ;數(shù)據(jù)變高,初始化成功
  139.           JMP     Set_18B20                  ;初始化失敗,重新初始化
  140. INIT2:    MOV     R2,#240                  
  141.           DJNZ    R2,$
  142.           RET        
  143. ;-----------------寫DS18B20的子程序(有具體的時序要求)-----------------
  144. WRITE_1820:
  145.         MOV     R2,#8           ;一共8位數(shù)據(jù)
  146. WR0:    CLR     DQ                                ;開始寫入DS18B20總線要處于復(fù)位
  147.         MOV     R3,#6                        ;總線復(fù)位保持14微妙以上
  148.         DJNZ    R3,$
  149.         RRC     A                                ;把一個字節(jié)分成8個BIT環(huán)移給C
  150.         MOV     DQ,C
  151.         MOV     R3,#20                        ;等待40微妙
  152.         DJNZ    R3,$
  153.         SETB    DQ                            ;重新釋放總線
  154.         NOP
  155.         NOP
  156.         DJNZ    R2,WR0                        ;寫入下一位
  157.         SETB    DQ
  158.         RET
  159. ;------ 從DS18B20中讀出兩個字節(jié)的溫度數(shù)據(jù)--------
  160. READ_1820:
  161.         MOV     R4,#2           ;將溫度高位和低位從DS18B20中讀出
  162.         MOV     R1,#TEMPER_L    ;低位存入31H(TEMPER_L)
  163. RE0:    MOV     R2,#8
  164. RE1:    SETB    DQ                                ;數(shù)據(jù)總線拉高
  165.         NOP
  166.         NOP
  167.         CLR     DQ                                ;讀前總線保持為低
  168.         NOP
  169.         NOP
  170.         SETB    DQ                                ;開始讀總線釋放
  171.         MOV     R3,#4                        ;延時一段時間
  172.         DJNZ    R3,$
  173.         MOV     C,DQ                        ;從DS18B20總線讀得一位
  174.         RRC     A                                ;把讀得的位值環(huán)移給A
  175.         MOV     R3,#30                        ;延時一段時間
  176.         DJNZ    R3,$
  177.         DJNZ    R2,RE1                        ;讀下一位
  178.         MOV     @R1,A
  179.         DEC     R1              ;高位存入30H(TEMPER_H)
  180.         DJNZ    R4,RE0
  181.         RET        
  182. ;------------------------------顯示程序----------------------
  183. DISPLAY: MOV A,#0C4H                        ;設(shè)定顯示位置
  184.          LCALL WRC                                ;調(diào)用寫入命令程序
  185.                  MOV A, TEMPHC                        ;判斷溫度是正還是負(fù)
  186.                   CJNE A,#0BH,FZ                        ;如果溫度是負(fù),順序執(zhí)行;是正,跳轉(zhuǎn)到FZ
  187.                  MOV  A,#2DH                          ;"-"號顯示
  188.                  AJMP  WDA                                ;跳轉(zhuǎn)到WDA
  189. FZ:            MOV  A,#2BH                          ;"+"號不顯示
  190. WDA:     LCALL WRD                                ;寫數(shù)據(jù)
  191.          MOV R0,#35H                        ;顯示溫度的百位、十位、個位
  192. WDA1:         MOV A,@R0
  193.                  ADD A,#30H
  194.                  LCALL WRD                                ;寫數(shù)據(jù)
  195.                  INC R0
  196.                  CJNE R0,#38H,WDA1                ;判斷溫度是否顯示完
  197.                  MOV A,#0C9H                        ;設(shè)定顯示位置
  198.                  LCALL WRC                                ;寫入命令
  199.                  MOV A,#0DFH                    ;"。"的ASCII碼
  200.                  LCALL WRD                                ;寫數(shù)據(jù)
  201.                  MOV A,#043H                        ;"C"的ASCII碼
  202.                  LCALL WRD                            ;寫數(shù)據(jù)
  203.          RET                                    ;子程序返回
  204. ;******** 顯示正確信息子程序 ***************
  205. MENU:    MOV  DPTR,#M_1              ;指針指到顯示消息
  206. LINE1:   MOV  A,#80H            ;設(shè)置 LCD 的第一行地址
  207.          LCALL  WRC             ;寫入命令
  208. FILL:    CLR  A                 ;填入字符
  209.          MOVC  A,@A+DPTR        ;由消息區(qū)取出字符
  210.          CJNE  A,#0,LC1         ;判斷是否為結(jié)束碼
  211.          JMP RET_END                ;子程序返回                  
  212. LC1:     LCALL  WRD             ;寫入數(shù)據(jù)
  213.          INC  DPTR              ;指針加1
  214.          JMP  FILL              ;繼續(xù)填入字符
  215. RET_END: RET
  216. M_1:     DB   "   T Monitor   ",0

  217. ;---------------液晶初始化程序-----------------
  218. INIT: MOV A,#01H            ;清屏
  219.      LCALL WRC              ;調(diào)用寫命令子程序
  220.      MOV A,#38H             ;8位數(shù)據(jù),2行,5×8點陣
  221.      LCALL WRC              ;調(diào)用寫命令子程序
  222.      MOV A,#0cH             ;開顯示和光標(biāo),字符不閃爍
  223.      LCALL WRC              ;調(diào)用寫命令子程序
  224.      MOV A,#06H             ;字符不動,光標(biāo)自動右移1格
  225.      LCALL WRC              ;調(diào)用寫命令子程序
  226.      RET                    ;子程序返回
  227.   ;---------------忙檢查子程序-------------
  228. CBUSY: PUSH ACC             ;將A的值暫存于堆棧
  229.      PUSH DPH               ;將DPH的值暫存于堆棧
  230.      PUSH DPL               ;將DPL的值暫存于堆棧
  231.      PUSH PSW               ;將PSW的值暫存于堆棧
  232. WEIT: CLR RS                ;RS=0,選擇指令寄存器
  233.      SETB RW                ;RW=1,選擇讀模式
  234.      CLR E                  ;E=0,禁止讀/寫LCD
  235.      SETB E                 ;E=1,允許讀/寫LCD
  236.      NOP
  237.      MOV A,P0               ;讀操作
  238.      CLR E                  ;E=0,禁止讀/寫LCD
  239.      JB ACC.7,WEIT          ;忙碌循環(huán)等待
  240.      POP PSW                ;從堆棧取回PSW的值
  241.      POP DPL                ;從堆棧取回DPL的值
  242.      POP DPH                ;從堆棧取回DPH的值
  243.      POP ACC                ;從堆棧取回A的值
  244.      LCALL DELAY            ;延時
  245.      RET                    ;子程序返回
  246. ;---------------寫子程序-------------
  247. ……………………

  248. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼


所有資料51hei提供下載:
2溫度監(jiān)控系統(tǒng).zip (115.41 KB, 下載次數(shù): 43)


評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表