找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 991|回复: 7
收起左侧

有大佬 帮帮忙解读一下这段程序吗(单片机智能空气净化系统)

[复制链接]
ID:1071327 发表于 2023-4-12 19:06 | 显示全部楼层 |阅读模式
#include<reg52.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int


sbit RS = P2^0;   //定义端口 lcd1602

sbit RW = P2^1;
sbit EN = P2^2;

sbit CS2  = P1^5;        //0832接口定义
sbit CLK = P1^6;
sbit DIO = P1^7;


#define RS_CLR RS=0
#define RS_SET RS=1

#define RW_CLR RW=0
#define RW_SET RW=1

#define EN_CLR EN=0
#define EN_SET EN=1

#define DataPort P0        





sbit led=P3^0;
sbit led1=P3^2;           
sbit led2=P3^3;         
sbit bee=P3^1;                         //蜂鸣器

sbit key1=P3^4;                        //4个按键
sbit key2=P3^5;
sbit key3=P3^6;                        
sbit key4=P3^7;

sbit key5=P1^0;

uchar h=75;           //初始上限值
uchar l=50;

sbit motor=P3^2;   //风扇
sbit xia=P3^3;                //喷洒

uint i,d;         //烟雾值检测
uint time=0;
unsigned long S;

uchar safe=10;

uchar dis1[6];

bit flag=0;                  //标志位
uint flag1;
bit flag2=0;
uchar flag3=0;
uchar re=0;
void delay_100us()
{
uchar j;
        for(j=0;j<31;j++)
                {
                ;
                }

}



          /*------------------------------------------------
                    延时程序
                        ------------------------------------------------*/
                         void delay_ms(uint j)
                         {
                                  uint i;
                                  for(;j>0;j--)
                                     {
                                                  for(i=0;i<113;i++)
                                             {
                                                         ;
                                                 }
                                          }
                          }




           /*------------------------------------------------
                         写入命令函数
            ------------------------------------------------*/


        void LCD_Write_Com(uchar com)
         {  
        delay_ms(5);
        RS_CLR;
        RW_CLR;
        EN_SET;
         DataPort=com;
        _nop_();
         EN_CLR;
         }
          /*------------------------------------------------
                          写入数据函数
          ------------------------------------------------*/

            void LCD_Write_Data(uchar Data)
             {
        delay_ms(5);
        RS_SET;
         RW_CLR;
         EN_SET;
        DataPort= Data;
        _nop_();
       EN_CLR;
       }


         /*------------------------------------------------
                         写入字符串函数
           ------------------------------------------------*/
            void LCD_Write_String(uchar x,uchar y,uchar *s)
            {     
        if (y == 0)
               {     


                LCD_Write_Com(0x80 + x);     //表示第一行
               }
       else
              {      
             LCD_Write_Com(0xC0 + x);      //表示第二行         
              }
                          
                                 
       while (*s)
               {     
       LCD_Write_Data( *s);     
      s ++;   
         
              }


        }


                /*------------------------------------------------
                         写入慢速字符串函数
           ------------------------------------------------*/
            void LCD_Write_SlowString(uchar x,uchar y,uchar *s)
            {     
        if (y == 0)
               {     


                LCD_Write_Com(0x80 + x);     //表示第一行
               }
       else
              {      
             LCD_Write_Com(0xC0 + x);      //表示第二行         
              }
                          
                                 
       while (*s)
               {     
       LCD_Write_Data( *s);     
      s ++;
         
           delay_ms(200);   
         
              }


        }


         /*------------------------------------------------
                        写入字符函数

          ------------------------------------------------*/
          void LCD_Write_Char(uchar x,uchar y,uchar Data)
          {     
      if (y == 0)
              {     
               LCD_Write_Com(0x80 + x);     
               }   
        else
               {     
               LCD_Write_Com(0xC0 + x);     
              }        
      LCD_Write_Data( Data);  
       }


           /*------------------------------------------------
                         初始化函数
          ------------------------------------------------*/
           void LCD_Init(void)
           {
                  

                        delay_ms(15);
                 LCD_Write_Com(0x38);    /*显示模式设置*/
                           LCD_Write_Com(0x38);    /*显示模式设置*/
                  LCD_Write_Com(0x38);    /*显示模式设置*/


                        LCD_Write_Com(0x0c);    /*显示开及光标设置 */                    
                 LCD_Write_Com(0x06);    /*显示光标移动设置 */
                        LCD_Write_Com(0x01);    /*显示清屏 */  

                  
                  }









void display()                  //显示处理子程序
{




dis1[3]=i/100;          //提取安全值的十位数,赋值给dis1[12]
dis1[4]=i/10%10;           //提取安全值的个位数,赋值给dis1[13]
dis1[5]=i%10;           //提取安全值的个位数,赋值给dis1[13]






LCD_Write_Char(0,1,'Y');                   //液晶显示数据
LCD_Write_Char(1,1,':');
LCD_Write_Char(2,1,dis1[3]+0x30);
LCD_Write_Char(3,1,dis1[4]+0x30);
LCD_Write_Char(4,1,dis1[5]+0x30);



LCD_Write_Char(9,1,'J');                   //液晶显示
LCD_Write_Char(10,1,':');
LCD_Write_Char(11,1,d/100+0x30);
LCD_Write_Char(12,1,d/10%10+0x30);
LCD_Write_Char(13,1,d%10+0x30);

dis1[0]=h/100;         //提取百位数,赋值给dis1[0]
dis1[1]=h/10%10;         //提取十位数,赋值给dis1[1]
dis1[2]=h%10;         //提取个位数,赋值给dis1[2]
LCD_Write_Char(8,0,dis1[0]+0x30);
LCD_Write_Char(9,0,dis1[1]+0x30);
LCD_Write_Char(10,0,dis1[2]+0x30);





delay_ms(1);
}




void key_process()
{


  if(key1==0)             //按键1
   {
    delay_ms(10);


        if(key1==0)
         {
          while(!key1);
          h++;
          if(h>=85) h=85;

          }
   }



   if(key2==0)                 //按键2
   {
    delay_ms(10);
        if(key2==0)
         {
          while(!key2);
           h--;
          if(h<=65) h=65;
          }
   }



}


unsigned char  A_D(bit flag)
{
        unsigned char i,dat;
        CS2=1;   //一个转换周期开始
        CLK=0;  //为第一个脉冲作准备
        CS2=0;  //CS2置0,片选有效
        
        DIO=1;    //DIO置1,规定的起始信号  
        CLK=1;   //第一个脉冲
        CLK=0;   //第一个脉冲的下降沿,此前DIO必须是高电平
        DIO=1;   //DIO置1, 通道选择信号  
        CLK=1;   //第二个脉冲,第2、3个脉冲下沉之前,DI必须跟别输入两位数据用于选择通道,这里选通道CH0
        CLK=0;   //第二个脉冲下降沿
        DIO=flag;   //DI置0,选择通道0
        CLK=1;    //第三个脉冲
        CLK=0;    //第三个脉冲下降沿
        DIO=1;    //第三个脉冲下沉之后,输入端DIO失去作用,应置1
        CLK=1;    //第四个脉冲
        for(i=0;i<8;i++)  //高位在前
        {
                CLK=1;         //第四个脉冲
                CLK=0;
                dat<<=1;       //将下面储存的低位数据向右移
                dat|=(unsigned char)DIO;          //将输出数据DIO通过或运算储存在dat最低位
        }                                 
        CS2=1;          //片选无效
        return dat;         //将读书的数据返回     
}



void main()
{

delay_ms(5);         //延时5ms
LCD_Init();          //液晶1602初始化
TMOD=0x01;
ET0=1;
EA=0;


LCD_Write_String(0,0,"ZNTL    ");
LCD_Write_String(6,0,"S:    ");

LCD_Write_Char(15,0,re+0x30);



while(1)
        {


         
                key_process();                //按键扫描

                display(); //1602液晶显示
               
                if(flag3==0)
                {
                i=A_D(0)/2;
                d=A_D(1)/2;
                }
                flag3++;
                if(flag3>=50) flag3=0;                //自加3次再检测          (甲烷)
                         if(i>=h&&flag==0) motor=0;
                 else motor=1;

                if(d>=50) bee=0;        //报警
                else bee=1;
                 if(key5==0)  //红外检测不到
                 {
                 flag=1;
                 motor=1;
                 xia=1;
                 re=1;
                 LCD_Write_Char(15,0,re+0x30);
                 while(!key5)
                 {
                 
                  display(); //1602液晶显示
                i=A_D(0)/2;
                 }

                 }

                 if(flag==1)
                 {
                 
                  if(i>=h)
                  {
                  motor=0;
                  xia=1;
                  flag2=1;
                  }
                 
                 if(i<h&&flag2==1)

                 {
                  xia=0;
                  motor=1;

                  flag1++;
                  if(flag1>=600)
                  {
                   flag1=0;
                   flag=0;
                   xia=1;
                   flag2=0;
                   re=0;
                   LCD_Write_Char(15,0,re+0x30);
                   }


                 
                 
                 }

        
                 
                 }

                delay_ms(1);
                 
               





        

               
                 
}
}

回复

使用道具 举报

ID:883242 发表于 2023-4-12 20:16 | 显示全部楼层
就是个按键处理和LCD显示,哪里看不懂?
回复

使用道具 举报

ID:1071327 发表于 2023-4-12 20:45 | 显示全部楼层
Hephaestus 发表于 2023-4-12 20:16
就是个按键处理和LCD显示,哪里看不懂?

能看懂一点   但是主程序流程图不知道该咋弄,他写的这个没有把模块分离出来  我看着有点晕
回复

使用道具 举报

ID:291668 发表于 2023-4-12 20:52 | 显示全部楼层
多看几遍就有感觉了。自己练练,加油吧
回复

使用道具 举报

ID:69038 发表于 2023-4-12 22:13 | 显示全部楼层
个人观点:
拿到一套代码,首先要知道这代码是用来做什么的,硬件电路都用了哪些器件,这些器件的控制原理或工作时序流程要清楚。如果以上都不了解,就算有人手把手,一对一地为你解说,你也掌握不了多少,等到换一个代码,你还是一头雾水。。
一个产品的工作流程你懂得了,画个流程图自然不在话下,再有一份确切的代码,学起来就快。
所以,做码农,还需要有电路、器件的基本知识。
楼主的这个代码都注释得差不多了,再结合0832、1602等器件的手册不难理解啊~
回复

使用道具 举报

ID:1071327 发表于 2023-4-12 22:18 | 显示全部楼层
zhuls 发表于 2023-4-12 22:13
个人观点:
拿到一套代码,首先要知道这代码是用来做什么的,硬件电路都用了哪些器件,这些器件的控制原理 ...

我确实小白了   这不在看b站  学学
回复

使用道具 举报

ID:1071327 发表于 2023-4-12 22:28 | 显示全部楼层
li64331218 发表于 2023-4-12 20:52
多看几遍就有感觉了。自己练练,加油吧

是的 打铁 还得看自己
回复

使用道具 举报

ID:69038 发表于 2023-4-12 22:31 | 显示全部楼层
加菲鱼 发表于 2023-4-12 22:18
我确实小白了   这不在看b站  学学

比如0832这块,你对照0832的手册、硬件电路的边接方式,一行行代码下来,真的不难。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表