基于stc15单片机 使用 lcd1602 esp8266 ds18b20 tsw30 实现水质浑浊度检测 并显示在lcd1602 并通过8266上传数据的程序
时间: 2023-07-29 14:11:17 浏览: 210
以下是基于 STC15 单片机,使用 LCD1602、ESP8266、DS18B20、TSW30 实现水质浑浊度检测并显示在 LCD1602,并通过 ESP8266 上传数据的程序。
首先,我们需要连接硬件,具体连接方式如下:
- 将 LCD1602 的 VSS 引脚连接到 GND,VDD 引脚连接到 +5V,RS 引脚连接到 P1.0,RW 引脚连接到 GND,EN 引脚连接到 P1.1,D4-D7 引脚分别连接到 P2.4-P2.7。
- 将 ESP8266 的 VCC 引脚连接到 +3.3V,GND 引脚连接到 GND,TXD 引脚连接到 P3.1,RXD 引脚连接到 P3.0。
- 将 DS18B20 的 VCC 引脚连接到 +5V,GND 引脚连接到 GND,DQ 引脚连接到 P3.2。
- 将 TSW30 的 DO 引脚连接到 P3.3。
接下来,我们来看看程序实现:
```c
#include <STC15F2K60S2.H>
#include <intrins.h>
sbit SCLK = P3^4;
sbit SDIO = P3^5;
sbit RS = P1^0;
sbit EN = P1^1;
unsigned char code dis_str[][8] = {"Temp: ", "Turb: ", "NTU"};
void delay_ms(unsigned int t)
{
unsigned int i, j;
for (i = 0; i < t; i++)
for (j = 0; j < 1000; j++);
}
void lcd_write_data(unsigned char dat)
{
RS = 1;
P2 = dat;
EN = 1;
_nop_();
_nop_();
EN = 0;
}
void lcd_write_cmd(unsigned char cmd)
{
RS = 0;
P2 = cmd;
EN = 1;
_nop_();
_nop_();
EN = 0;
}
void lcd_init()
{
lcd_write_cmd(0x38);
lcd_write_cmd(0x0c);
lcd_write_cmd(0x06);
lcd_write_cmd(0x01);
}
void lcd_show_string(unsigned char x, unsigned char y, unsigned char *str)
{
unsigned char i = 0;
if (y == 0)
lcd_write_cmd(0x80 + x);
else
lcd_write_cmd(0xc0 + x);
while (str[i] != '\0')
{
lcd_write_data(str[i]);
i++;
}
}
void ds18b20_init()
{
SDIO = 1;
SCLK = 1;
delay_ms(5);
SDIO = 0;
delay_ms(500);
SCLK = 0;
delay_ms(70);
SDIO = 1;
delay_ms(5);
SCLK = 1;
delay_ms(5);
SDIO = 1;
delay_ms(5);
}
unsigned char ds18b20_read_byte()
{
unsigned char i, byte_data = 0;
for (i = 0; i < 8; i++)
{
byte_data >>= 1;
SDIO = 0;
SCLK = 1;
_nop_();
_nop_();
if (SDIO)
byte_data |= 0x80;
SCLK = 0;
_nop_();
_nop_();
}
return byte_data;
}
void ds18b20_write_byte(unsigned char dat)
{
unsigned char i;
for (i = 0; i < 8; i++)
{
SDIO = dat & 0x01;
dat >>= 1;
SCLK = 1;
_nop_();
_nop_();
SCLK = 0;
_nop_();
_nop_();
}
}
int ds18b20_read_temp()
{
unsigned char i;
int temp = 0;
ds18b20_init();
ds18b20_write_byte(0xcc);
ds18b20_write_byte(0x44);
delay_ms(100);
ds18b20_init();
ds18b20_write_byte(0xcc);
ds18b20_write_byte(0xbe);
for (i = 0; i < 2; i++)
temp |= ds18b20_read_byte() << (i * 8);
return temp;
}
unsigned int tsw30_read_ntu()
{
unsigned int ntu;
TSW30 = 1;
delay_ms(10);
ntu = (unsigned int)TSW30;
TSW30 = 0;
return ntu;
}
void esp8266_send_cmd(char *cmd)
{
while (*cmd != '\0')
{
SBUF = *cmd;
while (!TI);
TI = 0;
cmd++;
}
}
void esp8266_send_data(char *data)
{
esp8266_send_cmd("AT+CIPSEND=");
esp8266_send_cmd(itoa(strlen(data)));
esp8266_send_cmd("\r\n");
delay_ms(1000);
while (*data != '\0')
{
SBUF = *data;
while (!TI);
TI = 0;
data++;
}
delay_ms(1000);
}
void main()
{
unsigned int temp;
unsigned int ntu;
char temp_str[10];
char ntu_str[10];
char send_buf[50];
TMOD = 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
PCON &= 0x7f;
SCON = 0x50;
TR1 = 1;
lcd_init();
while (1)
{
temp = ds18b20_read_temp();
ntu = tsw30_read_ntu();
sprintf(temp_str, "%d", temp / 16);
sprintf(ntu_str, "%d", ntu);
lcd_show_string(0, 0, dis_str[0]);
lcd_show_string(6, 0, temp_str);
lcd_show_string(11, 0, "C");
lcd_show_string(0, 1, dis_str[1]);
lcd_show_string(6, 1, ntu_str);
lcd_show_string(11, 1, dis_str[2]);
sprintf(send_buf, "Temperature: %dC, Turbidity: %dNTU", temp / 16, ntu);
esp8266_send_cmd("AT+CIPSTART=\"TCP\",\"192.168.1.100\",8000\r\n");
delay_ms(1000);
esp8266_send_data(send_buf);
delay_ms(1000);
}
}
```
程序中,我们先定义了一些变量和常量,其中 dis_str 数组存储了 LCD1602 中需要显示的字符串,delay_ms 函数用来进行延时,lcd_write_data 和 lcd_write_cmd 函数用来向 LCD1602 中写入数据和命令,lcd_init 函数用来初始化 LCD1602,lcd_show_string 函数用来在 LCD1602 上显示字符串,ds18b20_init 函数用来初始化 DS18B20 温度传感器,ds18b20_read_byte 函数用来从 DS18B20 中读取一个字节的数据,ds18b20_write_byte 函数用来向 DS18B20 中写入一个字节的数据,ds18b20_read_temp 函数用来读取 DS18B20 中的温度值,tsw30_read_ntu 函数用来读取 TSW30 中的浑浊度值,esp8266_send_cmd 函数用来向 ESP8266 发送 AT 命令,esp8266_send_data 函数用来向 ESP8266 发送数据。
在主函数中,我们先初始化串口,初始化 LCD1602 和 DS18B20,然后进入一个无限循环中,不断读取温度和浑浊度值并在 LCD1602 上显示,然后将数据通过 ESP8266 发送到服务器上。
需要注意的是,在使用 ESP8266 发送数据之前,我们需要先将 ESP8266 连接到 Wi-Fi 网络中,并将其 IP 地址和端口号设置为服务器的 IP 地址和端口号。具体的连接方式和设置方法可以参考 ESP8266 的相关文档。
阅读全文