微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 哪位大神能帮我详细解释一下这段程序单片机是STC89C52的

哪位大神能帮我详细解释一下这段程序单片机是STC89C52的

时间:10-02 整理:3721RD 点击:
我是一个单片机方面的的新人最近正在学习这方面的知识,不过认识浅薄实在看不懂,1563165260@qq.com这是我邮箱同志们加油哦!

#include <reg52.h>     //包含52单片机的寄存器符号定义头文件teg52.h

#include <intrins.h>

#define LCD_DB P0    //并行数据端口

#define Keyboard P1

#define Coil_A1 {A1 = 1; B1 = 0; C1 = 0; D1 = 0;}

#define Coil_B1 {A1 = 0; B1 = 1; C1 = 0; D1 = 0;}

#define Coil_C1 {A1 = 0; B1 = 0; C1 = 1; D1 = 0;}

#define Coil_D1 {A1 = 0; B1 = 0; C1 = 0; D1 = 1;}

#define Coil_OFF {A1 = 0; B1 = 0; C1 = 0; D1 = 0;}

sbit DQ = P2^0;    //单总线端口定义

sbit BUZZER = P2^1;     //蜂鸣器端口定义

sbit HUMIDIFIER = P2^2;    //加湿器端口定义

sbit HEATER = P2^3;    //加热器端口定义

sbit LCD_RS = P2^4;    //数据/指令控制端口定义

sbit LCD_RW = P2^5;    //读/写 控制端口定义

sbit LCD_E = P2^6;    //使能控制端口定义

sbit BUZZER_LIGHTING = P2^7;     //蜂鸣器数据输出端口定义

sbit A1 = P3^4;    //步进电机端口定义

sbit B1 = P3^5;

sbit C1 = P3^6;

sbit D1 = P3^7;

void initial(void);    //初始化

void LCD_write_command(unsigned char com);    //写指令

void LCD_display_char(unsigned char x, unsigned char y, unsigned char dat);     //显示位置,x(0-16),y(1-2)

void LCD_display_screen(unsigned char screenNumber);

unsigned char keyScan(void);    //键盘扫描

unsigned char KeyPro(void);

void keyboardResponse(void);    //获取输入或输出

unsigned char read_DHT11_char(void);

void control_temperature_humidity(void);

void delay_xms(unsigned int time_xms);

void Delay_10us(void);

void COM(void);

void RH(void);

void controlPeripheral(void);

bit keyPressFlag = 0;  

unsigned char stop_system = 0;

unsigned char screenNumber = 0;

unsigned char keyNumber = 0;  

unsigned char code lineOne[] = "Grainbin T&H ACS";

unsigned char code lineTwo[] = "   Loading...   ";

unsigned char code lineThree[] = "Temperature:   C";

unsigned char code lineFour[] = "  Region:  -   >";

unsigned char code lineFive[] = "Humidity:    %RH";

unsigned char code lineSix[] = "< Region:  -   >";

unsigned char code lineSeven[] = "  Humidifier:   ";

unsigned char code lineEight[] = "< Heater:      >";

unsigned char code lineNine[] = "Window(0-90): 0 ";

unsigned char code lineTen[] = "<               ";

unsigned char code lineEleven[] = "Shutting down...";

unsigned int T1_number;  

unsigned char temperature = 15, humidity = 50;

unsigned char stepperNumber = 0;

unsigned int motorNumber = 2525;    //2525 * 5 ms步进电机转一周  

unsigned char ceilingTemperature = 25, floorTemperature = 10, ceilingHumidity = 75, floorHumidity = 35;

unsigned char windowState = 0, windowAngle = 0;

unsigned char U8FLAG, U8comdata, U8temp;

void initial(void)

{  

  DQ = 1;    //闲置状态下,传感器数据线处于高电平状态  

  HEATER = 0;    //关闭加热器  

  HUMIDIFIER = 0;    //关闭加湿器

  BUZZER = 0;    //关闭报警器

  BUZZER_LIGHTING = 1;

  TMOD = 0x11;     //定时器0工作方式1,16位计数器;定时器1工作方式1,16位计数器  

  TH1 = 0xFC;    //定时器1溢出周期1ms,延时   

  TH1 = 0x66;   

  TH0 = 0xED;    //定时器0中断周期5ms   

  TL0 = 0xFF;

  EA = 1;     //开启总中断

  ET1 = 1;    //开启定时/计数器1中断  

  ET0 = 1;    //开启定时/计数器0中断  

  EX0 = 1;    //开启外部中断0  

  IT0 = 1;    //外部中断0下降沿触发

  TR0 = 1;     //开启定时计数器0

  LCD_write_command(0x38); //设置8位格式,2行,5x7

  LCD_write_command(0x0c); //设置整体显示,关闭光标,且不闪烁

  LCD_write_command(0x06); //设置输入方式,增量不移位

  LCD_display_screen(screenNumber);  

  delay_xms(2000);

  LCD_display_screen(++screenNumber);

}

void LCD_display_screen(unsigned char screenNumber)

{  

  unsigned char i, j;

   if (screenNumber == 0)  

  {   

     LCD_write_command(0x01);    //清屏

      for (i = 0; i < 16; i++)

    {     

      LCD_display_char(i, 1, lineOne);

     }

    for (j = 0; j < 16; j++)   

  {     

    LCD_display_char(j, 2, lineTwo[j]);

  }

  }

  else if (screenNumber == 1)

  {      

LCD_write_command(0x01);    //清屏     

for (i = 0; i < 16; i++)   

{

      LCD_display_char(i, 1, lineThree);        

}     

     for (j = 0; j < 16; j++)   

{     

  LCD_display_char(j, 2, lineFour[j]);      

}      

LCD_display_char(14,1,0xDF);    //显示特殊符号

LCD_display_char(12, 1, temperature / 10 + 0x30);   

LCD_display_char(13, 1, temperature % 10 + 0x30);         

LCD_display_char(9, 2, floorTemperature / 10 + 0x30);   

LCD_display_char(10, 2, floorTemperature % 10 + 0x30);   

LCD_display_char(12, 2, ceilingTemperature  / 10 + 0x30);      

LCD_display_char(13, 2, ceilingTemperature % 10 + 0x30);  

  }

  else if (screenNumber == 2)  

  {

    LCD_write_command(0x01);    //清屏

    for (i = 0; i < 16; i++)   

    {     

  LCD_display_char(i, 1, lineFive);

    }

    for (j = 0; j < 16; j++)   

    {     

  LCD_display_char(j, 2, lineSix[j]);   

    }

    LCD_display_char(11, 1, humidity / 10 + 0x30);   

    LCD_display_char(12, 1, humidity % 10 + 0x30);

  LCD_display_char(9, 2, floorHumidity / 10 + 0x30);   

  LCD_display_char(10, 2, floorHumidity % 10 + 0x30);   

  LCD_display_char(12, 2, ceilingHumidity / 10 + 0x30);   

    LCD_display_char(13, 2, ceilingHumidity % 10 + 0x30);

  }

  else if (screenNumber == 3)  

  {   

    LCD_write_command(0x01);    //清屏

    for (i = 0; i < 16; i++)   

    {     

  LCD_display_char(i, 1, lineSeven);

    }

  for (j = 0; j < 16; j++)   

    {   

      LCD_display_char(j, 2, lineEight[j]);

     }

     if (HUMIDIFIER == 0)

    {     

      LCD_display_char(15, 1, 'F');     

  LCD_display_char(14, 1, 'F');   

  LCD_display_char(13, 1, 'O');   

    }   

    else   

    {     

      LCD_display_char(15, 1, 'N');     

      LCD_display_char(14, 1, 'O');      

    }      

    if (HEATER == 0)   

    {     

  LCD_display_char(13, 2, 'F');   

  LCD_display_char(12, 2, 'F');     

      LCD_display_char(11, 2, 'O');     

    }   

    else   

    {     

      LCD_display_char(13, 2, 'N');     

      LCD_display_char(12, 2, 'O');      

    }   

  }

  else if (screenNumber == 4)  

  {   

    LCD_write_command(0x01);    //清屏

    for (i = 0; i < 16; i++)   

    {     

  LCD_display_char(i, 1, lineNine);

    }

  for (j = 0; j < 16; j++)  

  {

    LCD_display_char(j, 2, lineTen[j]);      

  }      

  LCD_display_char(15,1,0xDF);    //显示特殊符号      

  LCD_display_char(13, 1, windowAngle + 0x30);   

  }   

  else if (screenNumber == 5)  

  {   

    LCD_write_command(0x01);    //清屏         

    for (i = 0; i < 16; i++)   

    {     

  LCD_display_char(i, 1, lineEleven);      

}   

  }

}

void LCD_write_command(unsigned char com)

{  

  LCD_DB = com;  

  LCD_RS = 0;  

  LCD_RW = 0;  

  LCD_E = 1;  

  delay_xms(1);  

  LCD_E = 0;  

  delay_xms(5);

}  

void LCD_display_char(unsigned char x, unsigned char y, unsigned char dat)

{  

  if (y == 1)  

{   

  LCD_write_command(0x80 + x);

}

else  

{   

  LCD_write_command(0xc0 + x);

}

    LCD_DB = dat;  

LCD_RS = 1;  

LCD_RW = 0;  

LCD_E = 1;  

delay_xms(1);  

LCD_E = 0;  delay_xms(5);

}

void delay_xms(unsigned int time_xms)

{  

  T1_number = 0;  

   TR1 = 1;   

  while (1)  

  {   

  if (time_xms == T1_number)   

  {   

  break;

   }

    }

TR1 = 0;

  }  

  void  Delay_10us(void)

  {

unsigned char i;

i--;  

i--;  

i--;

i--;  

i--;  

i--;

  }

  void COM(void)    //DHT11传输总线   

  {   

unsigned char i = 0;

for(i=0;i<8;i++)      

  {

       U8FLAG=2;

       _nop_();      

     _nop_();   

        while((!DQ) && U8FLAG++);   

Delay_10us();   

Delay_10us();

U8temp=0;   

if(DQ) U8temp=1;   

U8FLAG=2;

while((DQ) && U8FLAG++);

      

_nop_();      

_nop_();

if(U8FLAG==1)break;    //如果超时,退出循环         

U8comdata<<=1;    //判断数据位0或1     

U8comdata|=U8temp;   

  }   

}

void RH(void)

{  

  unsigned char humidity_H, humidity_L, temperature_H, temperature_L, checkData;  

  DQ = 0;    //主机拉低18ms  

  delay_xms(200);   

  DQ = 1;    //总线由上拉电阻拉高 主机延时20us

  Delay_10us();   

  Delay_10us();   

  Delay_10us();   

  Delay_10us();

  DQ = 1;    //主机设为输入 判断从机响应信号   

                 //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运

行   

if(!DQ)         

{      

  U8FLAG=2;  

  

    while((!DQ)&&U8FLAG++);    //判断从机是否发出 80us 的低电平响应信号是否结

束        

U8FLAG=2;

while((DQ)&&U8FLAG++);    //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态         

COM();

humidity_H = U8comdata;    //数据接收状态

COM();

humidity_L = U8comdata;   

COM();

temperature_H = U8comdata;      

COM();

temperature_L = U8comdata;      

COM();

checkData = U8comdata;        

DQ = 1;

  }

if ((unsigned char)(humidity_H + humidity_L + temperature_H + temperature_L)== checkData)  

  {   

humidity = humidity_H;   

temperature = temperature_H;   

  }

}

void controlPeripheral()

{   

  if (temperature < floorTemperature)  

  {

   windowState = 0;   

  }   

  else if (temperature > ceilingTemperature)  

  {   windowState = 9;  

  }  

  else  

  {

windowState = (unsigned char)(10 * (temperature - floorTemperature) /(ceilingTemperature - floorTemperature));   

  }

  if (temperature > ceilingTemperature | temperature < floorTemperature)     //蜂鸣器调控

  {   

  BUZZER = 1;

  BUZZER_LIGHTING = 0;

   }

   else if (humidity > ceilingHumidity | humidity < floorHumidity)  

  {   

  BUZZER = 1;

   BUZZER_LIGHTING = 0;  

  }

  else   

  {   

  BUZZER = 0;   

  BUZZER_LIGHTING = 1;  

  }   

  if (temperature <= floorTemperature)     //加热器调控  

  {   

  HEATER = 1;   

  }   else if (temperature >= (ceilingTemperature - 3))  

  {   

  HEATER = 0;  

  }

  if (humidity <= floorHumidity)    //加湿器调控

  {   

  HUMIDIFIER = 1;

   }

   else if (humidity >= ceilingHumidity)  

  {   

  HUMIDIFIER = 0;

   }

}

void main(void)

{  

  unsigned int DHT11Timer = 200;   

  initial();   

  while(!stop_system)  

  {   

    keyboardResponse();     

    if (DHT11Timer-- == 0)   

    {   

  DHT11Timer = 200;      

  RH();

  if (screenNumber == 1)   

  {     

    LCD_display_char(12, 1, temperature / 10 + 0x30);     

    LCD_display_char(13, 1, temperature % 10 + 0x30);

      }

  else if (screenNumber == 2)   

  {     

    LCD_display_char(11, 1, humidity / 10 + 0x30);     

    LCD_display_char(12, 1, humidity % 10 + 0x30);   

  }

    }

    else   

    {   

      delay_xms(10);

     }

  if (screenNumber == 4)   

    {  

  LCD_display_char(13, 1, windowAngle + 0x30);

    }     

    controlPeripheral();   

  }     

  LCD_display_screen(5);    //关闭系统   

  windowState = 0;  

  delay_xms(3000);   

  LCD_write_command(0x01);  

  delay_xms(60000);  

}

void keyboardResponse()

{   

  Keyboard = 0xf0;    // 赋值用于中断检测

    if(keyPressFlag == 1)   

  {      

    keyPressFlag = 0;    //按键标志清零,以便下次检测

       keyNumber = KeyPro();         

    if(keyNumber != 0xff)   

    {     

      if (screenNumber != 1 & keyNumber == 0)     

      {      

        LCD_display_screen(--screenNumber);

      }

      else if (screenNumber != 4 & keyNumber == 4)     

      {      

        LCD_display_screen(++screenNumber);     

      }      

      else if (keyNumber == 1)     

      {      

        floorTemperature--;      

        LCD_display_screen(screenNumber);         

      }

      else if (keyNumber == 5)     

      {      

        floorTemperature++;      

        LCD_display_screen(screenNumber);      

      }      

      else if (keyNumber == 9)     

      {      

        ceilingTemperature--;      

        LCD_display_screen(screenNumber);     

      }

      else if (keyNumber == 13)     

      {      

        ceilingTemperature++;      

        LCD_display_screen(screenNumber);     

      }      

      else if (keyNumber == 3)     //加热器开关      

      {      

        if (HEATER == 0)      

      {      

        HEATER = 1;      

      }      

      else

      {      

        HEATER = 0;   

      }

         if (screenNumber == 3)      

      {      

        LCD_display_screen(screenNumber);

      }

}

else if (keyNumber == 2)     

{      

  floorHumidity--;

      LCD_display_screen(screenNumber);

    }      

    else if (keyNumber == 6)     

    {      

      floorHumidity++;      

      LCD_display_screen(screenNumber);      

    }      

    else if (keyNumber == 10)     

{      

ceilingHumidity--;      

    LCD_display_screen(screenNumber);     

}

else if (keyNumber == 14)     

{      

  ceilingHumidity++;

    LCD_display_screen(screenNumber);     

}

else if (keyNumber == 7)    //加湿器开关

{      

  if (HUMIDIFIER == 0)      

  {      

    HUMIDIFIER = 1;

  }

  else      

  {      

    HUMIDIFIER = 0;         

  }

        

  if (screenNumber == 3)      

  {      

    LCD_display_screen(screenNumber);      

  }      

}      

else if (keyNumber == 11)     

{           

  stop_system = 1;

}

  }

}

}

void INT_0(void) interrupt 0

{  

  keyPressFlag = 1;

}  

unsigned char keyScan()  

{  

  unsigned char Val;   

  Keyboard=0xf0;    //高四位置高,低四位拉低

  if(Keyboard != 0xf0)    //表示有按键按下

{      

  delay_xms(10);      //去抖

     if(Keyboard != 0xf0)

    {                     //表示有按键按下

         Keyboard = 0xfe;       //检测第一行   

      if(Keyboard != 0xfe)     

      {

        Val=Keyboard & 0xf0;

        Val += 0x0e;        

        while(Keyboard != 0xfe);      

        delay_xms(10);     //去抖

        while(Keyboard != 0xfe);        

         return Val;

      }

      Keyboard = 0xfd;    //检测第二行

       if(Keyboard != 0xfd)  

        {

        Val=Keyboard & 0xf0;            

        Val += 0x0d;        

        while(Keyboard != 0xfd);      

        delay_xms(10);    //去抖         

        while(Keyboard != 0xfd);           

        return Val;            

      }        

      Keyboard = 0xfb;   //检测第三行      

      if(Keyboard != 0xfb)      

      {         

        Val=Keyboard & 0xf0;            

        Val += 0x0b;        

        while(Keyboard != 0xfb);      

        delay_xms(10);    //去抖         

        while(Keyboard != 0xfb);           

        return Val;            

      }        

      Keyboard = 0xf7;   //检测第四行      

      if(Keyboard != 0xf7)      

      {         

        Val=Keyboard & 0xf0;            

        Val += 0x07;        

        while(Keyboard != 0xf7);      

        delay_xms(10);    //去抖         

        while(Keyboard != 0xf7);         

        return Val;         

      }      

    }   

  }

  return 0xff;

}

unsigned char KeyPro()

{  

  switch(keyScan()

  {     

    case 0x7e:return 0;break; //0 按键返回响应值     

    case 0x7d:return 1;break; //1     

case 0x7b:return 2;break; //2     

case 0x77:return 3;break; //3     

case 0xbe:return 4;break; //4     

case 0xbd:return 5;break; //5     

case 0xbb:return 6;break; //6     

case 0xb7:return 7;break; //7     

case 0xde:return 8;break; //8     

case 0xdd:return 9;break; //9     

case 0xdb:return 10;break; //a     

case 0xd7:return 11;break; //b     

case 0xee:return 12;break; //c     

case 0xed:return 13;break; //d     

case 0xeb:return 14;break; //e     

case 0xe7:return 15;break; //f     

default:return 0xff;break;

    }

}

void Timer_0(void) interrupt 1

{  

  TR0 = 0;

  TH0 = 0xED;     //定时器0中断周期5ms

  TL0 = 0xFF;  

   if (windowState < windowAngle)  

  {   

    if (motorNumber >= 1)  

{   

  motorNumber--;   

      switch (stepperNumber)  

      {

      case 0: Coil_A1; stepperNumber++; break;     

      case 1: Coil_B1; stepperNumber++; break;     

      case 2: Coil_C1; stepperNumber++; break;     

      case 3: Coil_D1; stepperNumber++; break;     

      default: stepperNumber = 0; break;

    }

  }

  else   

  {   

    motorNumber = 2525;   

    windowAngle--;

   }

}

else if (windowState > windowAngle)  

{   

  if (motorNumber >= 1)   

  {   

    motorNumber--;   

    switch (stepperNumber)   

    {     

      case 0: Coil_D1; stepperNumber++; break;     

      case 1: Coil_C1; stepperNumber++; break;     

      case 2: Coil_B1; stepperNumber++; break;     

      case 3: Coil_A1; stepperNumber++; break;     

      default: stepperNumber = 0; break;     

    }   

  }

  else   

  {   

    motorNumber = 2525;   

    windowAngle++;   

  }

  }  

  else  

  {

    Coil_OFF;

   }

   TR0 = 1;

}  

void Timer_1(void) interrupt 3

{  

  TH1 = 0xFC;    //定时器1溢出周期1ms,延时

  TL1 = 0x66;   

  T1_number++;

}



看来是沉了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top