51单片机温度监控系统 电机转动 汇编与C源程序注释很详细

[复制链接]
查看1 | 回复0 | 2021-6-11 02:44:31 | 显示全部楼层 |阅读模式
完整单片机程序源码和proteus仿真文件在本文尾部附件中
1.png
C语言部分代码:

  1. #include<reg51.h>                                //预处理命令,定义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引脚,转向选择位
  12. uchar t[2],speed,temperature;  //用来存放温度值,测温程序就是通过这个数组与主函数通信的
  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函数*/
  19. {
  20.    uchar i,temp;               //声明变量i,temp
  21.    for(i = 20;i > 0;i--)       //循环
  22.    {
  23.     temp = 248;                //给temp赋值248
  24.     while(--temp);             //temp减1是否等于0,否则继续执行该行
  25.     temp = 248;                //给temp赋值248
  26.     while(--temp);             //temp减1是否等于0,否则继续执行该行
  27.     }
  28. }
  29. void delay_38us(void)          /*延时38us函数*/
  30. {   uchar temp;                //声明变量temp
  31.     temp = 18;                 //给temp赋值
  32.     while(--temp);             //temp减1是否等于0,否则继续执行该行
  33. }
  34. void delay_1520us(void)         /*延时1520us函数*/
  35. {  uchar i,temp;                //声明变量i,temp
  36.    for(i = 3;i > 0;i--)         //循环
  37.    {
  38.     temp = 252;                 //给temp赋值
  39.     while(--temp);              //temp减1是否等于0,否则继续执行该行
  40.     }
  41. }
  42. uchar lcd_rd_status( )          /*读取lcd1602的状态,主要用于判断忙*/
  43. {
  44. uchar tmp_sts;                 //声明变量tmp_sts
  45. lcd_data = 0xff;               //初始化P3口
  46. lcd_RW = 1;                    //RW =1  读      
  47. lcd_RS = 0;                    //RS =0  命令,合起来表示读命令(状态)
  48. lcd_EN = 1;                    //EN=1,打开EN,LCD1602开始输出命令数据,100nS之后命令数据有效
  49. tmp_sts = lcd_data;            //读取命令到tmp_sts
  50. lcd_EN = 0;                    //关掉LCD1602
  51. lcd_RW = 0;                    //把LCD1602设置成写
  52. return tmp_sts;                //函数返回值tmp_sts
  53. }
  54. void lcd_wr_com(uchar command )  /*写一个命令到LCD1602*/
  55. {
  56.   while(0x80&lcd_rd_status()); //写之前先判断LCD1602是否忙,看读出的命令的最高位是否为1,为1表示忙,继续读,直到不忙
  57.   lcd_RW = 0;
  58.   lcd_RS = 0;                  //RW=0,RS=0 写命令
  59.   lcd_data = command;          //把需要写的命令写到数据线上
  60.   lcd_EN = 1;  
  61.   lcd_EN = 0;                  //EN输出高电平脉冲,命令写入
  62. }
  63. void lcd_wr_data(uchar sjdata )  /*写一个显示数据到lcd1602*/
  64. {
  65. while(0x80&lcd_rd_status());  //写之前先判断lcd1602是否忙,看读出的命令的最高位是否为1,为1表示忙,继续读,直到不忙
  66. lcd_RW = 0;
  67. lcd_RS = 1;                   //RW=0,RS=1 写显示数据
  68. lcd_data = sjdata ;            //把需要写的显示数据写到数据线上
  69. lcd_EN = 1;
  70. lcd_EN = 0;                   //EN输出高电平脉冲,命令写入
  71. lcd_RS = 0;                 
  72. }
  73. void Init_lcd(void)            /*初始化lcd1602*/
  74. {
  75.   delay_20ms();                //调用延时
  76.   lcd_wr_com(0x38);            //设置16*2格式,5*8点阵,8位数据接口
  77.   delay_38us();                //调用延时
  78.   lcd_wr_com(0x0c);            //开显示,不显示光标
  79.   delay_38us();                //调用延时
  80.   lcd_wr_com(0x01);            //清屏
  81.   delay_1520us();              //调用延时
  82.   lcd_wr_com(0x06);            //显示一个数据后光标自动+1
  83. }        
  84. void GotoXY(uchar x, uchar y)  //设定位置,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)                   //显示字符串函数
  92. {
  93.         while(*str!='\0')                   //判断字符串是否显示完
  94.         {
  95.                 lcd_wr_data(*str);           //写数据
  96.                 str++;                                   
  97.         }
  98. }
  99. void LCD_Print(uchar x, uchar y, uchar *str)//x为行值,y为列值,str是要显示的字符串   
  100. {
  101.   GotoXY(x,y);                                   //设定显示位置
  102.   Print(str);                                   //显示字符串
  103. }
  104.                                                    
  105. /*****************系统显示子函数*****************/

  106. void covert1()                       //温度转化程序
  107. {
  108.    uchar x=0x00;                           //变量初始化
  109.    if(t[1]>0x07)               //判断正负温度
  110.    {
  111.     TempBuffer1[0]=0x2d;           //0x2d为"-"的ASCII码
  112.         t[1]=~t[1];                               //负数的补码
  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;                           //将高字节左移4位
  122.     t[1]=t[1]&0x70;                       //取出高字节的3个有效数字位
  123.     x=t[0];                                           //将t[0]暂存到X,因为取小数部分还要用到它
  124.     x>>=4;                                           //右移4位
  125.     x=x&0x0f;                                   //和前面两句就是取出t[0]的高四位        
  126.     t[1]=t[1]|x;                           //将高低字节的有效值的整数部分拼成一个字节
  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;         //百位数消隐
  131.     TempBuffer1[2]=(t[1]%100)/10+0x30;//分离出十位
  132.     TempBuffer1[3]=(t[1]%100)%10+0x30;//分离出个位                                                                        
  133. }                        
  134. /*******************DS18B20函数**********************/

  135. void delay_18B20(uint i)                        //延时程序
  136. {
  137.         while(i--);
  138. }
  139. void Init_DS18B20(void)                          //ds18b20初始化函数
  140. {
  141.          uchar x=0;
  142.          DQ = 1;                                          //DQ复位
  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读一个字节函数
  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);                                     //返回数据
  165. }
  166. void WriteOneChar(uchar dat1)                 //ds18b20写一个字节函数
  167. {
  168.          uchar i=0;
  169.          for (i=8; i>0; i--)
  170.          {
  171.                   DQ = 0;                                                 //开始写入DS18B20总线要处于复位(低)状态
  172.                  DQ = dat1&0x01;                                 //写入下一位
  173.             delay_18B20(5);
  174.                  DQ = 1;                                                 //重新释放总线
  175.             dat1>>=1;                                         //把一个字节分成8个BIT环移给DQ
  176. }
  177. }
  178. void ReadTemperature()                            //读取ds18b20当前温度
  179. {        
  180.         delay_18B20(80);                //延时一段时间
  181.         Init_DS18B20();        
  182.         WriteOneChar(0xCC);                // 跳过读序号列号的操作
  183.         WriteOneChar(0x44);           // 启动温度转换
  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)           //延时函数
  193. {
  194.         uchar j,k;                           //变量i、k为无符号字符数据类型
  195.         for(j=i;j>0;j--)                     //循环延时
  196.         for(k=200;k>0;k--);                 //循环延时
  197. }
  198. /*******************电机转动程序*******************/
  199. void motor(uchar tmp)            
  200. {   
  201.         uchar x;
  202.            if(TempBuffer1[0]==0x2b)                //温度为正数
  203.         {
  204.             if(tmp<25)                                    //温度小于25度
  205.                 {
  206.                  D=0;                                                //电机停止转动
  207.                  PWM=0;
  208.                 }
  209.                 else if(tmp>50)                                //温度大于50度,全速转动
  210.                 {
  211.                  D=0;                                                  //D置0
  212.                  PWM=1;                                    //正转,PWM=1
  213.               x=250;                                   //时间常数为x
  214.               delay_motor(x);            //调延时函数
  215.                  PWM=0;                                   // PWM=0
  216.               x=5;                                        //时间常数为x
  217.              delay_motor(x);            //调延时函数
  218.                 }
  219.                 else
  220.                 {
  221.                  D=0;                                                  //D置0
  222.                  PWM=1;                                    //正转,PWM=1
  223.               x=5*tmp;                           //时间常数为x
  224.               delay_motor(x);                //调延时函数
  225.                  PWM=0;                                   // PWM=0
  226.               x=255-5*tmp;                       //时间常数为255-x
  227.              delay_motor(x);                   //调延时函数
  228.             }
  229.         }
  230.            else if (TempBuffer1[0]==0x2d)  //温度小于0,反转
  231.         {
  232.                   D=1;                                                
  233.                  PWM=0;                                   // PWM=0
  234.              x=5*tmp;                                    //时间常数为tmp
  235.                 delay_motor(x);                        //调延时函数
  236.                 PWM=1;                                   // PWM=1
  237.              x=255-5*tmp;                               //时间常数为255- tmp
  238.                 delay_motor(x);                        //调延时函数
  239.           }
  240. }        
  241.   
  242. void delay(unsigned int x)     //延时函数名
  243. {
  244.   unsigned char i;             //定义变量i的类型
  245.   while(x--)                         //x自减1
  246.     {
  247.       for(i=0;i<123;i++){;}    //控制延时的循环
  248.     }
  249. }                                                                                   

  250. /*************************main主程序*********************/
  251. void main(void)
  252. {
  253.     delay_20ms();                      //系统延时20ms启动
  254.         ReadTemperature();                                   //启动DS18B20
  255.            Init_lcd();                        //调用LCD初始化函数
  256.         LCD_Print(0,0,tab);                                   //液晶初始显示
  257.         delay(1000);                                           //延时一段时间
  258.         while(1)
  259.     {        
  260.                   ReadTemperature();                           //读取温度,温度值存放在一个两个字节的数组中,
  261.             delay_18B20(100);
  262.             covert1();                                           //数据转化
  263.             LCD_Print(4,1,TempBuffer1);   //显示温度
  264.                 motor(temperature);                   //电机转动
  265.         }
  266. }
复制代码
ASM汇编语言部分代码
  1. TEMPER_L  EQU   31H           ;用于保存读出温度的低字节
  2. TEMPER_H  EQU   30H           ;用于保存读出温度的高字节
  3. T_INTEGER EQU   32H           ;温度的整数部分(integer)
  4. T_IN_BAI  EQU   35H                          ;温度的百位
  5. T_IN_SHI  EQU        36H                          ;温度的十位
  6. T_IN_GE   EQU   37H                          ;温度的个位
  7. FLAG      BIT   33H           ;标志位
  8. TEMPHC    EQU   34H           ;正、负温度值标记
  9. SPEED     EQU   45H                          ;电机的速度调节位
  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数据线
  14. PWM       BIT   P3.6          ;定义速度控制位PWMP3.7
  15. D         BIT  P3.7           ;定义方向控制位P3.2
  16.         ORG   0000H                          ;在0000H单元存放转移指令
  17.         SJMP  MAIN                          ;转移到主程序
  18.                 ORG   0060H                          ;主程序从0060H开始
  19. MAIN:   LCALL DELAY20ms                  ;系统延时20ms启动
  20.                 LCALL INIT                          ;调用LCD初始化函数
  21.                 LCALL MENU                          ;调用液晶初始界面
  22.                 LCALL READ_TEM                  ;开启DS18B20
  23.               LCALL DELAY1S                  ;调用1s延时,使DS18B20能完全启动
  24. LOOP:        LCALL READ_TEM                  ;读取温度,温度值存放
  25.             LCALL CONVTEMP                  ;调用温度转化程序
  26.                 LCALL DISPLAY                  ;调用显示程序
  27.                 LCALL MOTOR                          ;调用电机转动程序
  28.                 LJMP LOOP                           ;循环调用
  29. DELAY1S:MOV   R5,#10                        ;1S延时程序,给R5赋值,外循环控制
  30. DEL1:   MOV   R6,#200              ;中循环控制
  31. DEL2:   MOV   R7,#250              ;内循环控制
  32. DEL3:   DJNZ  R7,DEL3         ;内循环体  
  33.         DJNZ  R6,DEL2         ;中循环体
  34.         DJNZ  R5,DEL1         ;外循环体
  35.         RET                                         ;子程序返回
  36. ;------------------------电机转动程序----------------------
  37. MOTOR:        MOV A,T_INTEGER                  ;温度转化的整数暂存于A中
  38.               MOV B,#5                          ;给寄存器赋值立即数5
  39.                   MUL AB                                  ;整数*5,提高转速的占空比
  40.                  MOV SPEED,A                                          
  41.               MOV A,TEMPHC                  ;把正、负温度值标记暂存于A中
  42.                   CJNE A,#0AH,NEG                  ;判断温度值标记是正还是负,如果是正,就顺序执行;否则,跳转到NEG
  43.               CLR C                                  ;把进位清零
  44. WIN:          MOV A,T_INTEGER                  ;温度转化的整数暂存于A中
  45.                   SUBB A,#25                          ;判断温度是否超过25度
  46.                   JNC POS                                  ;温度大于25度,跳转到POS
  47.                   SETB D                                  ;方向控制端置1
  48.                   SETB PWM                          ;PWM端置1,电机停止转动
  49.               JMP REND                          ;子程序返回
  50. POS:          MOV A,T_INTEGER                  ;温度转化的整数暂存于A中
  51.                   SUBB A,#50                          ;判断温度是否大于50度
  52.                   JNC POS2                          ;温度大于50度,跳转到POS2
  53. POS1:        SETB D                                  ;方向控制端置1
  54.                   CLR PWM                        ;正转,PWM=0
  55.               MOV A, SPEED          ;时间常数为SPEED
  56.               LCALL  DELAY_MOTOR    ;调用电机转动延时子程序
  57.               SETB  PWM                        ;电机停止转动,PWM=1
  58.               MOV A, #255                     ;时间常数为255-TMP
  59.               SUBB A, SPEED
  60.               LCALL  DELAY_MOTOR    ;调用电机延时子程序
  61.               JMP REND                             ;子程序返回
  62. POS2:         MOV SPEED,#250                  ;SPEED赋值为250
  63.               JMP POS1                          ;跳转到POS1
  64. NEG:          CLR   D                                  ;方向控制端置0
  65.                   SETB  PWM             ;反转,PWM=1
  66.               MOV A, SPEED              ;时间常数为SPEED
  67.               LCALL  DELAY_MOTOR    ;调用电机延时子程序
  68.               CLR PWM               ;PWM=0
  69.               MOV A, #255                     ;时间常数为255-TMP
  70.               SUBB A, SPEED
  71.                   LCALL  DELAY_MOTOR    ;调用延时子程序
  72. REND:   RET                                    ;子程序返回
  73. ;---------------------电机转动延时子程序--------------------------
  74. DELAY_MOTOR:MOV R6, #5              ;设循环次数
  75. D1:                   DJNZ R6, D1     ;循环等待
  76.                       DJNZ ACC,D1     ;循环等待
  77.                       RET             ;子程序返回
  78. ;---------------------温度转化程序------------------------------  
  79. CONVTEMP: MOV  A,TEMPER_H       ;判温度是否零下
  80.           ANL  A,#08H                        
  81.           JZ  TEMPC1                 ;温度没有零下,跳转到TEMPC1
  82.           CLR  C                                ;进位清零
  83.           MOV  A,TEMPER_L       ;温度的低字节二进制数求补
  84.           CPL  A                     ;取反
  85.           ADD  A,#01H                        ;加1
  86.           MOV  TEMPER_L,A               
  87.           MOV  A,TEMPER_H                ;温度的高字节二进制数求补(双字节)
  88.           CPL  A                                ;取反
  89.           ADDC  A,#00H                        
  90.           MOV  TEMPER_H,A
  91.                   MOV   TEMPHC,#0BH                ;负温度标志
  92.           LJMP  TEMPC11                        ;跳转到TEMPC11
  93. TEMPC1:   MOV  TEMPHC,#0AH             ;正温度标志                          
  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       ;把温度的高字节和低字节重新组合为一个字节
  102.           MOV  T_INTEGER,A                ;把组合成字节存于T_INTEGER
  103.           MOV B,#100                        ;把温度整数部分化为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          ;发出温度转换命令
  117.           LCALL   WRITE_1820          ;写DS18B20的子程序
  118.           LCALL   Set_18B20       ;准备读温度前先初始化
  119.           MOV     A,#0CCH         ;跳过ROM匹配
  120.           LCALL   WRITE_1820          ;写DS18B20的子程序
  121.           MOV     A,#0BEH         ;发出读温度命令
  122.           LCALL   WRITE_1820          ;写DS18B20的子程序
  123.           LCALL   READ_1820                  ;读DS18B20的程序
  124.               RET                                          ;子程序返回
  125. ;--------------------------DS18B20初始化程序--------------------------
  126. Set_18B20:SETB    DQ                          ;数据线拉高
  127.           NOP
  128.           CLR     DQ                          ;赋值数据线低电平
  129.           MOV     R2,#255         ;主机发出延时500微秒的复位低脉冲
  130.           DJNZ    R2,$
  131.           SETB    DQ              ;拉高数据线
  132.           MOV     R2,#30
  133.           DJNZ    R2,[        DISCUZ_CODE_3        ]nbsp;           ;延时60us等待DS18B20回应
  134.           JNB     DQ,INIT1
  135.           JMP     Set_18B20       ;超时而没有响应,重新初始化
  136. INIT1:    MOV     R2,#120
  137.           DJNZ    R2,[        DISCUZ_CODE_3        ]nbsp;           ;延时240us
  138.           JB      DQ,INIT2        ;数据变高,初始化成功
  139.           JMP     Set_18B20                  ;初始化失败,重新初始化
  140. INIT2:    MOV     R2,#240                  
  141.           DJNZ    R2,$
  142.           RET        
  143. ;-----------------写DS18B20的子程序(有具体的时序要求)-----------------
  144. WRITE_1820:
  145.         MOV     R2,#8           ;一共8位数据
  146. WR0:    CLR     DQ                                ;开始写入DS18B20总线要处于复位
  147.         MOV     R3,#6                        ;总线复位保持14微妙以上
  148.         DJNZ    R3,$
  149.         RRC     A                                ;把一个字节分成8个BIT环移给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中读出两个字节的温度数据--------
  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                                ;数据总线拉高
  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                                ;把读得的位值环移给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                        ;设定显示位置
  184.          LCALL WRC                                ;调用写入命令程序
  185.                  MOV A, TEMPHC                        ;判断温度是正还是负
  186.                   CJNE A,#0BH,FZ                        ;如果温度是负,顺序执行;是正,跳转到FZ
  187.                  MOV  A,#2DH                          ;"-"号显示
  188.                  AJMP  WDA                                ;跳转到WDA
  189. FZ:            MOV  A,#2BH                          ;"+"号不显示
  190. WDA:     LCALL WRD                                ;写数据
  191.          MOV R0,#35H                        ;显示温度的百位、十位、个位
  192. WDA1:         MOV A,@R0
  193.                  ADD A,#30H
  194.                  LCALL WRD                                ;写数据
  195.                  INC R0
  196.                  CJNE R0,#38H,WDA1                ;判断温度是否显示完
  197.                  MOV A,#0C9H                        ;设定显示位置
  198.                  LCALL WRC                                ;写入命令
  199.                  MOV A,#0DFH                    ;"。"的ASCII码
  200.                  LCALL WRD                                ;写数据
  201.                  MOV A,#043H                        ;"C"的ASCII码
  202.                  LCALL WRD                            ;写数据
  203.          RET                                    ;子程序返回
  204. ;******** 显示正确信息子程序 ***************
  205. MENU:    MOV  DPTR,#M_1              ;指针指到显示消息
  206. LINE1:   MOV  A,#80H            ;设置 LCD 的第一行地址
  207.          LCALL  WRC             ;写入命令
  208. FILL:    CLR  A                 ;填入字符
  209.          MOVC  A,@A+DPTR        ;由消息区取出字符
  210.          CJNE  A,#0,LC1         ;判断是否为结束码
  211.          JMP RET_END                ;子程序返回                  
  212. LC1:     LCALL  WRD             ;写入数据
  213.          INC  DPTR              ;指针加1
  214.          JMP  FILL              ;继续填入字符
  215. RET_END: RET
  216. M_1:     DB   "   T Monitor   ",0

  217. ;---------------液晶初始化程序-----------------
  218. INIT: MOV A,#01H            ;清屏
  219.      LCALL WRC              ;调用写命令子程序
  220.      MOV A,#38H             ;8位数据,2行,5×8点阵
  221.      LCALL WRC              ;调用写命令子程序
  222.      MOV A,#0cH             ;开显示和光标,字符不闪烁
  223.      LCALL WRC              ;调用写命令子程序
  224.      MOV A,#06H             ;字符不动,光标自动右移1格
  225.      LCALL WRC              ;调用写命令子程序
  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          ;忙碌循环等待
  240.      POP PSW                ;从堆栈取回PSW的值
  241.      POP DPL                ;从堆栈取回DPL的值
  242.      POP DPH                ;从堆栈取回DPH的值
  243.      POP ACC                ;从堆栈取回A的值
  244.      LCALL DELAY            ;延时
  245.      RET                    ;子程序返回
  246. ;---------------写子程序-------------
  247. ……………………

  248. …………限于本文篇幅 余下代码请下载附件…………
复制代码
温度监控系统.zip (115.41 KB, 售价: 3 工控币)
回复

使用道具 举报

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

本版积分规则