哪位大神能帮我详细解释一下这段程序单片机是STC89C52的
#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++;
}
看来是沉了