实验五
- 实验名称
温室盆栽灌溉系统
软件设计:
1. 定义对应的引脚和端口的别名。
2. 编写延时函数,用于控制程序的执行速度。
3. 编写LCD控制函数,包括发送命令和发送数据两种操作。
4. 编写显示函数,用于在LCD上显示字符串。
5. 编写获取AD转换结果的函数,用于测量环境湿度。
6. 编写显示百分比的函数,用于在LCD上显示湿度百分比。
7. 编写按键扫描函数,用于检测按键的状态。
8. 在主函数中,初始化LCD显示屏,并显示初始界面。
9. 进入主循环,不断执行以下操作:
a. 扫描按键,根据按键的状态更新标准湿度值。
b. 根据当前选择的花卉类型,显示相应的花卉名称。
c. 获取环境湿度,并计算百分比。
d. 在LCD上显示当前湿度百分比和标准湿度。
e. 根据湿度与标准湿度的比较结果,控制水泵、风机和LED灯的状态。
具体:
- delay函数实现了一个简单的延迟函数,n为延迟的时间,具体延迟的时间可以通过调整循环的次数来实现。
- lcd_cmd函数用于发送命令到液晶显示屏。a为要发送的命令值,将它赋给P0端口,然后将RS置为0以表示发送命令,将EN置为1以启动命令传输,延迟一段时间后将EN置为0以停止传输。
- lcd_data函数用于向液晶显示屏发送数据。和lcd_cmd函数相似,不同之处在于将RS置为1以表示发送数据。
- display函数用于在液晶显示屏上显示字符串。通过指针ptr遍历字符串,对每个字符调用lcd_data函数进行显示。
- delay_10us函数用于微秒级别的延迟。通过循环次数来实现延迟。
- 利用`display_percentage`函数来将温度值转换成字符串,并显示百分比值。
1.将芯片代码进行编译测试,结果正确无任何错误
2.生成HEX文件,放入AT89C51芯片中运行硬件电路。
3.不同花卉的阈值湿度和土壤湿度:
六、软件源码
#include<reg51.h>
#include<intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;
sbit CS=P3^0;
sbit CLK=P3^1;
sbit DIO=P3^2;
sbit D_STD=P1^0;
sbit P_STD=P1^1;
sbit R_STD=P1^2;
sbit INC=P1^3;
sbit DEC=P1^7;
sbit FMQ=P2^3;
sbit LED_RED=P2^4;
sbit WATER=P2^5;
#define LCD P0
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
void delay(int n)
{
int i,j;
for(i=0;i<n;i++)
for(j=0;j<255;j++);
}
void lcd_cmd(char a)
{
LCD = a;
RS = 0;
EN = 1;
delay(10);
EN = 0;
}
void lcd_data(char a)
{
LCD = a;
RS = 1;
EN = 1;
delay(10);
EN = 0;
}
void display(char *ptr)
{
while(*ptr != '\0')
{
lcd_data(*ptr);
ptr++;
}
}
u8 getADRes()
{
u8 i, data1=0, data2=0;
CS=0;
CLK=0;DIO=1;_nop_();
CLK=1;_nop_();
CLK=0;DIO=1;_nop_();
CLK=1;_nop_();
CLK=0;DIO=0;_nop_();
CLK=1;_nop_();
CLK=0;DIO=1;_nop_();
for(i=0; i<8; i++)
{
CLK=1;_nop_();
CLK=0;_nop_();
data1=(data1<<1)|(u8)DIO;
}
for(i=0; i<8; i++)
{
data2=data2|(u8)DIO<<i;
CLK=1;_nop_();
CLK=0;_nop_();
}
CS=1;
return(data1==data2)?data1:0;
}
void display_percentage(u8 value)
{
u8 temp[3];
temp[0]=value/100+'0';
temp[1]=value%100/10+'0';
temp[2]=value%100%10+'0';
if(temp[0]=='1')lcd_data(temp[0]);
lcd_data(temp[1]);
lcd_data(temp[2]);
lcd_data('%');
}
u8 key_scan(u8 mode)
{
u8 key=1;
if(mode)key=1;
if(key==1&&(D_STD==0||P_STD==0||R_STD==0||INC==0||DEC==0))
{
delay_10us(1000);
key=0;
if(D_STD==0)
return 0;
else if(P_STD==0)
return 1;
else if(R_STD==0)
return 2;
else if(INC==0)
return 3;
else if(DEC==0)
return 4;
}
else if(D_STD==1&&P_STD==1&&R_STD==1&&INC==1&&DEC==1)
{
key=1;
}
return 5;
}
void main()
{
u8 value=0, index=0, key_value=0;
char standard[3]={40, 50, 30};
RW=0;
WATER=0;
FMQ=1;
LED_RED=0;
lcd_cmd(0x01); //clear screen
lcd_cmd(0x0E); //Display On, Cursor Blinking
lcd_cmd(0x38); //2 lines and 5*7 matrix
lcd_cmd(0x80); //Force Cursor to beginning of first
display("shuixianhua");
lcd_cmd(0xC0);
display("N:");
lcd_cmd(0xC8);
display("S:");
while(1)
{
key_value=key_scan(0);
if(key_value==3){
standard[index]++;
if(standard[index]>100)standard[index]=100;
}else if(key_value==4){
standard[index]--;
if(standard[index]<0)standard[index]=0;
}else if(key_value>=0&&key_value<=2){
index=key_value;
}
switch(index){
case 0: lcd_cmd(0x80);
display("shuixianhua");
break;
case 1: lcd_cmd(0x80);
display("mudanhua");
break;
case 2: lcd_cmd(0x80);
display("meiguihua");
break;
}
lcd_cmd(0xC2);
value=getADRes()*100/255;
display_percentage(value);
lcd_cmd(0xCA);
display_percentage(standard[index]);
if(value<standard[index]){
WATER=1;
FMQ=0;
LED_RED=1;
}else{
WATER=0;
FMQ=1;
LED_RED=0;
}
}
}
六、软件源码
#include<reg51.h>
#include<intrins.h>typedef unsigned char u8;
typedef unsigned int u16;sbit RS=P2^0;
sbit RW=P2^1;
sbit EN=P2^2;
sbit CS=P3^0;
sbit CLK=P3^1;
sbit DIO=P3^2;
sbit D_STD=P1^0;
sbit P_STD=P1^1;
sbit R_STD=P1^2;
sbit INC=P1^3;
sbit DEC=P1^7;
sbit FMQ=P2^3;
sbit LED_RED=P2^4;
sbit WATER=P2^5;#define LCD P0void delay_10us(u16 ten_us)
{while(ten_us--);
}void delay(int n)
{int i,j;for(i=0;i<n;i++)for(j=0;j<255;j++);
}void lcd_cmd(char a)
{LCD = a;RS = 0;EN = 1;delay(10);EN = 0;
}void lcd_data(char a)
{LCD = a;RS = 1;EN = 1;delay(10);EN = 0;
}void display(char *ptr)
{while(*ptr != '\0'){lcd_data(*ptr);ptr++;}
}u8 getADRes()
{u8 i, data1=0, data2=0;CS=0;CLK=0;DIO=1;_nop_();CLK=1;_nop_();CLK=0;DIO=1;_nop_(); CLK=1;_nop_();CLK=0;DIO=0;_nop_();CLK=1;_nop_();CLK=0;DIO=1;_nop_(); for(i=0; i<8; i++){CLK=1;_nop_();CLK=0;_nop_();data1=(data1<<1)|(u8)DIO; }for(i=0; i<8; i++){data2=data2|(u8)DIO<<i;CLK=1;_nop_();CLK=0;_nop_();}CS=1;return(data1==data2)?data1:0;
}void display_percentage(u8 value)
{u8 temp[3];temp[0]=value/100+'0';temp[1]=value%100/10+'0';temp[2]=value%100%10+'0';if(temp[0]=='1')lcd_data(temp[0]);lcd_data(temp[1]);lcd_data(temp[2]);lcd_data('%');
}u8 key_scan(u8 mode)
{u8 key=1;if(mode)key=1;if(key==1&&(D_STD==0||P_STD==0||R_STD==0||INC==0||DEC==0)){delay_10us(1000);key=0;if(D_STD==0)return 0;else if(P_STD==0)return 1;else if(R_STD==0)return 2;else if(INC==0)return 3;else if(DEC==0)return 4;}else if(D_STD==1&&P_STD==1&&R_STD==1&&INC==1&&DEC==1){key=1;}return 5;
}void main()
{u8 value=0, index=0, key_value=0;char standard[3]={40, 50, 30};RW=0;WATER=0;FMQ=1;LED_RED=0;lcd_cmd(0x01); //clear screenlcd_cmd(0x0E); //Display On, Cursor Blinkinglcd_cmd(0x38); //2 lines and 5*7 matrixlcd_cmd(0x80); //Force Cursor to beginning of firstdisplay("shuixianhua");lcd_cmd(0xC0);display("N:");lcd_cmd(0xC8);display("S:");while(1){key_value=key_scan(0);if(key_value==3){standard[index]++;if(standard[index]>100)standard[index]=100;}else if(key_value==4){standard[index]--;if(standard[index]<0)standard[index]=0;}else if(key_value>=0&&key_value<=2){index=key_value;}switch(index){case 0: lcd_cmd(0x80);display("shuixianhua");break;case 1: lcd_cmd(0x80);display("mudanhua");break;case 2: lcd_cmd(0x80);display("meiguihua");break;}lcd_cmd(0xC2);value=getADRes()*100/255;display_percentage(value);lcd_cmd(0xCA);display_percentage(standard[index]);if(value<standard[index]){WATER=1;FMQ=0;LED_RED=1;}else{WATER=0;FMQ=1;LED_RED=0;}}
}