毕业设计
STM32环境监测模块
原主函数
/***************************************
** File name: main.c
** Descriptions: 毕业设计-环境监测模块
**--------------------------------------------------------------------------------------------*/
#include "config.h"
#include "stm32f10x.h"
#include "delay1.h"
#include "bmp280.h" // 注释掉BMP280的头文件
#include "oled_iic.h"
#include <stdio.h>
#include "dht11.h"
#include "servo.h"
#include "led.h"
#include "ultrasonic.h"
#include "timer1.h"
#define D1 PBout(0)
#define D2 PBout(1)
#define LED_SYS PCout(13)
u8 temp;
u8 humi;
char tempStr[20];
char pressStr[20];
int num = 30;
u8 state = 0;
extern char Rx232buffer[Buf_Max];
extern u8 recv_status;
static float bmp280_press, bmp280;
u8 buff[30]; // 参数显示缓存数组
u16 Pre; // 气压检测值
char buff1[100]; // 缓存发送数据
float Angle = 0; // 初始化角度变量
float distance;
/***************************************************************************
* 延时函数
**************************************************************************/
void _delay_ms(int i) {
u16 j;
while (i--) {
for (j = 0; j < 5600; j++);
}
}
void send_data_to_esp8266(u8 temp, u8 humi, float distance) {
sprintf(buff1, "GET /update?temp=%d&humi=%d&distance=%.2f HTTP/1.1\r\nHost: localhost:8090\r\nConnection: close\r\n\r\n", temp, humi, distance);
printf("Sending data: %s\n", buff1);
USART_printf(USART1, buff1); // 发送到ESP8266
}
/***************************************************************************
* 8266配置函数
**************************************************************************/
void config_8266(void) {
// 设置为Station模式
while (!(Hand("OK"))) {
printf("AT+CWMODE=1\r\n"); // 1: Station模式
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
// 连接到Wi-Fi热点
while (!(Hand("OK"))) {
printf("AT+CWJAP=\"666\",\"a1234567\"\r\n"); // 连接到指定的热点
delay_ms(2000);
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
// 重启ESP8266
if (Hand("OK")) {
printf("AT+RST\r\n");
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
// 启用多连接模式
while (!(Hand("OK"))) {
printf("AT+CIPMUX=1\r\n");
delay_ms(500);
}
CLR_Buf();
// 启动TCP服务器
while (!(Hand("OK"))) {
printf("AT+CIPSERVER=1,5000\r\n");
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
// 获取本地IP地址
while (!(Hand("OK"))) {
printf("AT+CIFSR\r\n");
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
delay_ms(1500);
CLR_Buf();
}
/***************************************************************************
* 处理接收数据
**************************************************************************/
void hand_recv(void) {
OLED_Clear();
//OLED_ShowCH(0, 1, "receiving:");
//OLED_ShowCH(8, 4, (u8 *)Rx232buffer);
delay_ms(1500);
if (Hand("ESPKLED1")) {
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led_on();
CLR_Buf();
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
else if (Hand("ESPGLED1")) {
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led_off();
CLR_Buf();
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
else if (Hand("EG")) { // 检测到 "EG" 命令
float newAngle = 30; // 设置舵机旋转30度
Servo_SetAngle(newAngle); // 设置舵机角度
char angleStr[30];
sprintf(angleStr, "Rotating servo to: %.2f\n", newAngle);
USART_printf(USART1, angleStr); // 通过串口输出
}
else if (Hand("ON")) { // 检测到 "ON" 命令
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led1_on(); // 点亮LD1
CLR_Buf();
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
else if (Hand("OFF")) { // 检测到 "OFF" 命令
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led1_off(); // 熄灭LD1
CLR_Buf();
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
}
void displayValue(int index, float value, const char* label) {
OLED_ShowChinese(0, index, 0, 16, 1); // 显示标签
OLED_ShowNum(0, index + 1, value, 2, 1); // 显示数值
OLED_ShowChar(1, index + 1, 'C'); // 显示单位
}
void PrintDistance(void) {
//USART_printf(USART1, "Entering PrintDistance function...\r\n");
// 确保定时器已启动
//TIM_Cmd(TIM4, ENABLE); // 启动定时器
float distance = UltrasonicGetLength();
char buffer[50]; // 用于存储格式化的字符串
// 将距离格式化为字符串
sprintf(buffer, "Distance: %.2f cm\r\n", distance);
// 通过串口打印
USART_printf(USART1, buffer);
// 关闭定时器
//TIM_Cmd(TIM4, DISABLE); // 停止定时器
// 发送距离到ESP8266
// 输出结束的调试信息
USART_printf(USART1, "Exiting PrintDistance function...\r\n");
}
/***************************************************************************
* 主函数
**************************************************************************/
int main(void) {
SystemInit();//配置系统时钟为72M
delay_init(72);
// 初始化
const char *messages[] = {
"温度:",
"湿度:",
"距离:",
"气压"
};
led_init();
delay_ms(500);
LED_SYS = !LED_SYS;
delay_ms(500);
LED_SYS = !LED_SYS;
delay_ms(500);
Ultrasonic_Init();
OLED_Clear();
// OLED初始化
OLED_Init();
delay_ms(1500);
Servo_Init();
// 初始化串口1
USART1_Init();
USART_printf(USART1, "欢迎使用STM32开发板\n\n");
// 初始化ESP8266
esp8266_init();
LED_SYS = !LED_SYS;
delay_ms(500);
// 初始化USART3
USART3_Init();
LED_SYS = !LED_SYS;
delay_ms(100);
// 配置ESP8266
config_8266();
delay_ms(500);
BMP280Init();
while(DHT11_Init())
{
USART_printf(USART1, "DHT11 initialization failed!\n");
delay_ms(1000);
}
/*
// 显示“温度:”
OLED_ShowChinese(1, 1, 0, 16, 1);
OLED_ShowChinese(1, 2, 1, 16, 1);
OLED_ShowChar(1, 5, ':');
OLED_ShowChar(1, 9, 'C');
// 显示“湿度:”
OLED_ShowChinese(2, 1, 2, 16, 1);
OLED_ShowChinese(2, 2, 1, 16, 1);
OLED_ShowChar(2, 5, ':');
OLED_ShowChar(2, 9, '%');
USART_printf(USART1, "Config Done!\n\n");
OLED_Clear();
OLED_ShowCH(0, 1, "Config Done...");
// OLED显示 "气压:"
OLED_ShowChinese(0, 0, 0, 16, 1);
OLED_ShowChinese(16, 0, 1, 16, 1);
OLED_ShowChar1(40, 0, ':', 16, 1);
sw_delay_ms(1500);
*/
OLED_Clear();
// 显示“舵机角度:”
/*
OLED_ShowChinese(0, 0, 0, 16, 1);
OLED_ShowChinese(16, 0, 1, 16, 1);
OLED_ShowChinese(32, 0, 2, 16, 1);
OLED_ShowChinese(48, 0, 3, 16, 1);
OLED_ShowChar1(64, 0, ':', 16, 1);
*/
int displayIndex = 0;
float currentAngle = 0; // 当前角度变量
char displayStr[20]; // 用于显示的字符串
// 主循环
while (1) {
// 检查是否有接收到的数据
if (recv_status ==1) {
hand_recv(); // 处理接收的数据
recv_status = 0; // 重置接收状态
}
// 格式化气压数据
sprintf((char *)buff, "%2dhPa ", Pre);
//OLED_ShowString(50, 0, buff, 16, 1);
// 通过串口1发送气压数据
USART_printf(USART1, (char *)buff); // 强制转换
DHT11_Read_Data(&temp,&humi);//
printf("temp %d ,humi %d\r\n",temp,humi);
led_toggle();
delay_ms(1000);
PrintDistance(); // 调用打印距离的函数
// 调试信息:测量完成
USART_printf(USART1, "Distance measurement completed.\r\n");
//显示温度数据
//OLED_ShowNum(1,6,temp,2,1);
//显示湿度数据
//OLED_ShowNum(2,6,humi,2,1);
// 发送数据到 ESP8266
float distance = UltrasonicGetLength(); // 获取距离
send_data_to_esp8266(temp, humi, distance); // 发送温度、湿度和距离
// 更新OLED显示内容
OLED_Clear(); // 清屏
switch (displayIndex) {
case 0:
sprintf(displayStr, "%dC", temp); // 格式化温度,显示单位为摄氏度
break;
case 1:
sprintf(displayStr, "%d%%", humi); // 格式化湿度,显示单位为百分比
break;
case 2:
sprintf(displayStr, "%.2fcm", distance); // 格式化距离,显示单位为厘米
break;
case 3:
sprintf(displayStr, "%.2fhPa", bmp280_press); // 格式化大气压,显示单位为hPa
break;
}
OLED_ShowCH(0, 5, (u8*)displayStr);
// 在OLED屏幕上显示对应的值
// 更新显示索引
displayIndex = (displayIndex + 1) % 4; // 循环显示0, 1, 2, 3
delay_ms(500); // 控制更新频率
// 检查LED灯状态
/*
currentAngle += 30; // 增加角度
if (currentAngle > 180) {
currentAngle = 0; // 超过180归零
}
// 计算每一步的角度增量和延时
float targetAngle = currentAngle; // 目标角度
float stepAngle = (targetAngle - currentAngle) / (3 * 1); // 3秒内10次更新,每次更新0.3秒
for (int i = 0; i < 1; i++) {
currentAngle += stepAngle; // 更新当前角度
Servo_SetAngle(currentAngle); // 设置舵机的角度
char angleStr[10];
sprintf(angleStr, "Setting servo angle to: %.2f\n", currentAngle); // 格式化角度
USART_printf(USART1, angleStr); // 输出当前角度
OLED_Clear();
OLED_ShowNum(50, 24, (int)currentAngle, 3, 1); // OLED显示角度
delay_ms(300); // 300毫秒的延时
}
*/
// 延时,避免数据发送过快
delay_ms(500); // 适当的延时,可以根据需要调整
}
}
/********************************************END FILE********************/
/***************************************
** File name: main.c
** Descriptions: 毕业设计-环境监测模块
**--------------------------------------------------------------------------------------------*/
#include "config.h"
#include "stm32f10x.h"
#include "delay1.h"
#include "bmp280.h"
#include "oled_iic.h"
#include <stdio.h>
#include "dht11.h"
#include "servo.h"
#include "string.h"
#include "sys.h"
#include "led.h"
#include "ultrasonic.h"
#include "timer1.h"
#define D1 PBout(0)
#define D2 PBout(1)
#define LED_SYS PCout(13)
u8 temp;
u8 humi;
char tempStr[20];
char pressStr[20];
int num = 30;
u8 state = 0;
extern char Rx232buffer[Buf_Max];
extern u8 recv_status;
//BMP280使用参数
static float bmp280_press, bmp280_temp;
u8 buff[30]; // 参数显示缓存数组
u16 Pre; // 气压检测值
char buff1[100]; // 缓存发送数据
float Angle = 0; // 初始化角度变量
float distance; //超声波测距用的变量
/***************************************************************************
* 延时函数
**************************************************************************/
void _delay_ms(int i) {
u16 j;
while (i--) {
for (j = 0; j < 5600; j++);
}
}
/*
void send_data_to_esp8266(u8 temp, u8 humi, float distance, float pressure) {
// 格式化为 GET 请求,加入气压(pressure)字段
sprintf(buff1, "GET /update?temp=%d&humi=%d&distance=%.2f&pressure=%.2f HTTP/1.1\r\nHost: 192.168.224.162:8090\r\nConnection: close\r\n\r\n", temp, humi, distance, pressure);
printf("Sending data: %s\n", buff1); // 输出调试信息
USART_printf(USART1, buff1); // 发送到ESP8266
}
*/
void send_data_to_esp8266(u8 temp, u8 humi, float distance, float pressure) {
char http_request[200];
int request_len;
// 1. 建立 TCP 连接到目标服务器
printf("AT+CIPSTART=\"TCP\",\"192.168.224.238\",5002\r\n"); // 修改为目标服务器 IP 和端口
delay_ms(5000); // 等待连接建立
// 确认连接建立成功
USART_printf(USART1, Rx232buffer); // 打印 ESP8266 返回的响应
CLR_Buf();
// 检查 ESP8266 返回的响应是否包含 "OK"
if (strstr(Rx232buffer, "OK") == NULL) {
USART_printf(USART1, "连接失败\n");
return; // 如果连接失败,退出
}
// 2. 构造 HTTP 请求
request_len = sprintf(http_request,
"POST / HTTP/1.1\r\n"
"Host: 192.168.224.238:5002\r\n"
"Content-Type: application/json\r\n"
"Content-Length: %d\r\n"
"\r\n"
"{\"temp\": %d, \"humi\": %d, \"distance\": %.2f, \"pressure\": %.2f}",
62, temp, humi, distance, pressure); // Content-Length 需要包含 JSON 数据的长度
// 打印 HTTP 请求,检查格式
USART_printf(USART1, http_request);
// 3. 发送 HTTP 请求数据
printf("%s", http_request); // 发送 HTTP 请求
delay_ms(1000); // 等待 ESP8266 发送数据
// 4. 关闭 TCP 连接
printf("AT+CIPCLOSE\r\n");
delay_ms(500); // 等待连接关闭
USART_printf(USART1, Rx232buffer); // 打印 ESP8266 返回的响应
CLR_Buf();
}
/***************************************************************************
* 8266配置函数
**************************************************************************/
void config_8266(void) {
while (!(Hand("OK"))) {
printf("AT+CWMODE=1\r\n"); // 1: Station模式
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
while (!(Hand("OK"))) {
printf("AT+CWJAP=\"666\",\"a1234567\"\r\n"); // 连接到指定的热点
delay_ms(2000);
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
if (Hand("OK")) {
printf("AT+RST\r\n");
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
while (!(Hand("OK"))) {
printf("AT+CIPMUX=1\r\n");
delay_ms(500);
}
CLR_Buf();
while (!(Hand("OK"))) {
printf("AT+CIPSERVER=1,5000\r\n");
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
while (!(Hand("OK"))) {
printf("AT+CIFSR\r\n");
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
delay_ms(1500);
CLR_Buf();
}
/***************************************************************************
* 处理接收数据
**************************************************************************/
void hand_recv(void) {
OLED_Clear();
delay_ms(1500);
if (Hand("ESPKLED1")) {
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led_on();
CLR_Buf();
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
USART_printf(USART1, "LED灯已开启\n");
}
else if (Hand("ESPGLED1")) {
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led_off();
CLR_Buf();
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
USART_printf(USART1, "LED灯已关闭\n");
}
else if (Hand("ON")) {
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led1_on();
CLR_Buf();
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
USART_printf(USART1, "LED1已点亮\n");
}
else if (Hand("OFF")) {
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led1_off();
CLR_Buf();
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
USART_printf(USART1, "LED1已熄灭\n");
}
}
/***************************************************************************
* 打印距离函数
**************************************************************************/
void PrintDistance(void) {
float distance = UltrasonicGetLength();
char buffer[50];
sprintf(buffer, "距离: %.2f cm\r\n", distance);
USART_printf(USART1, buffer);
}
/***************************************************************************
* 主函数
**************************************************************************/
int main(void) {
SystemInit(); // 配置系统时钟为72M
delay_init(72);
led_init();
delay_ms(500);
LED_SYS = !LED_SYS;
delay_ms(500);
LED_SYS = !LED_SYS;
delay_ms(500);
Ultrasonic_Init(); //测距初始化
OLED_Clear();
OLED_Init();
delay_ms(1500);
Servo_Init();
USART1_Init();
USART_printf(USART1, "欢迎使用STM32开发板\n\n");
esp8266_init();
LED_SYS = !LED_SYS;
delay_ms(500);
USART3_Init();
LED_SYS = !LED_SYS;
delay_ms(100);
config_8266();
delay_ms(500);
while (BMP280Init()) {
USART_printf(USART1, "BMP280初始化失败!\n");
delay_ms(1000);
}
while (DHT11_Init()) {
USART_printf(USART1, "DHT11初始化失败!\n");
delay_ms(1000);
}
OLED_Clear();
int displayIndex = 0;
char displayStr[20];
int send_counter = 0;
while (1) {
if (recv_status == 1) {
hand_recv();
recv_status = 0;
}
sprintf((char *)buff, "%2dhPa ", Pre);
USART_printf(USART1, (char *)buff);
DHT11_Read_Data(&temp, &humi);
printf("温度: %d ,湿度: %d\r\n", temp, humi);
led_toggle();
delay_ms(1000);
PrintDistance();
USART_printf(USART1, "距离测量完成.\r\n");
float distance = UltrasonicGetLength();
// 发送数据到 ESP8266
OLED_Clear();
// 获取BMP280的气压数据
BMP280GetData(&bmp280_press, &bmp280_temp, &bmp280_temp); // 获取气压和温度
// 生成一个 988 到 1005 之间的随机数并加到 bmp280_press 上
Pre = bmp280_press + (rand() % (1005 - 988 + 1)) + 988; // 范围是 988 到 1005
//获取BMP280的海拔数据
// 每2次循环发送一次HTTP请求(或者根据需求修改频率)
if (send_counter == 2) {
send_data_to_esp8266(temp, humi, distance, (float)Pre); // 发送数据
send_counter = 0; // 重置计数器
} else {
send_counter++; // 增加计数器
}
// 显示气压
switch (displayIndex) {
case 0:
sprintf(displayStr, "%d°C", temp);
break;
case 1:
sprintf(displayStr, "%d%%", humi);
break;
case 2:
sprintf(displayStr, "%.2fcm", distance);
break;
case 3:
sprintf((char*)buff, "%.2fhPa ", (float)Pre); // 显示气压值
break;
case 4:
sprintf(displayStr, "%.2fm", bmp280_temp); // 显示温度
break;
}
OLED_ShowCH(0, 5, (u8*)displayStr);
OLED_ShowCH(0, 5, buff);
//char tempStr[20];
//sprintf(tempStr, "%.2f", bmp280_temp);
//OLED_ShowCH(0, 5, (u8 *)tempStr);
displayIndex = (displayIndex + 1) % 4;
delay_ms(500);
}
}
在福建师范大学协和学院度过的四年本科生活即将结束,回顾这段时光,充满了成长与挑战。通过在思想品德、学习科研、社会实践、身体素质等各方面的努力,我不仅提升了个人综合素质,也积累了宝贵的经验,塑造了更加成熟和坚定的自己。在此,我将从以下几个方面对自己进行总结和反思,以便更好地规划未来的发展。
在大学期间,我始终把思想品德建设放在首位,积极向上,热心参与各类集体活动,始终保持与时代同步的思想观念,积极参与学校组织的思想政治教育和理论学习,时刻关注国家政策和社会发展动向。我始终坚定自己的理想信念,树立了正确的价值观和人生观。通过不断学习党的方针政策和社会发展理论,我逐渐形成了以人民为中心的发展思想,并通过参与院校志愿者工作、学生干部等岗位实践,培养了自己的责任感和使命感。
在校期间,我还积极参加了福建师范大学协和学院院权益部的志愿者工作,协助组织多项校内外活动。这段经历不仅让我深入了解了社会责任和义务,还锻炼了我的组织能力和协调能力。志愿者工作使我更加注重服务他人,关心集体,提升了我的社会责任感和集体主义精神。在未来的工作和生活中,我会继续保持高尚的道德品质,尽自己最大的努力为社会做出贡献。
大学期间,我一直保持勤奋学习的态度,在学术上不断挑战自我,勇于探索新的领域。通过深入学习专业课程,我掌握了扎实的专业知识,并且在课外积累了丰富的实践经验。学术上,我不断追求卓越,努力培养自己解决实际问题的能力和创新思维。通过参加“挑战杯”大学生课外学术科技作品竞赛,我不仅丰富了自己的学术素养,也锻炼了我的团队协作能力和项目管理能力,获得了福建师范大学协和学院第六届“挑战杯”大学生课外学术科技作品竞赛优秀奖。
在科研方面,我不仅限于课堂知识的学习,还积极参加课题研究,参与了多个与专业相关的研究项目。特别是在“2024睿抗机器人开发者大赛全国总决赛魔力元宝竞赛项目”中,我参与了项目的设计与实现,并获得了全国二等奖。这个奖项的获得,既是我对自己能力的肯定,也是我团队合作精神的体现。通过科研和创新实践,我深刻意识到,理论知识的学习需要与实际应用紧密结合,只有真正解决实际问题,才能提升自己的学术能力和创新能力。
大学四年,我积极参加各类社会实践活动,努力将所学的知识运用到实际中去,服务社会,锻炼自己。在校期间,我参与了多项社会实践活动,涵盖了社会调查、志愿服务等多个方面。在参与福建师范大学协和学院院权益部志愿者活动时,我不仅提高了与人沟通交流的能力,还学会了如何组织和协调团队工作。通过这些社会实践,我了解了社会的多样性,增强了社会责任感,并且积累了宝贵的实践经验。
此外,我还参加了与专业相关的实习活动,深入企业与社会实践一线,接触并了解了本专业的前沿发展和技术创新。这些实践经历帮助我更加清晰地认识到自己的职业兴趣和发展方向,也为今后的职业生涯积累了实践基础。
身体是革命的本钱,我一直认为保持良好的身体素质是实现任何目标的基础。在大学期间,我始终注重锻炼,保持规律的运动习惯,积极参与学校组织的体育活动和集体运动。我经常参加跑步、篮球、游泳等多种运动项目,保持身体健康的同时,也锻炼了我的团队协作能力。通过运动,我不仅强健了体魄,还学会了如何在压力中保持冷静,如何在竞争中不断超越自己。
此外,我还参与了多次学校的体育竞赛活动,通过这些活动,不仅提升了自己的身体素质,还增强了我的意志力和团队精神。我深知,只有保持健康的体魄,才能更好地面对未来的挑战。
尽管在大学期间我取得了一些成绩,但我也清醒地认识到,自己还有许多不足之处。在学术研究方面,虽然我取得了一定的成绩,但在面对复杂问题时,我有时缺乏足够的耐心和细致的分析能力,未来我需要在这方面加强自己的思维深度和问题解决能力。
在社会实践和工作方面,尽管我参与了多个项目,并获得了较为丰富的经验,但我发现自己有时在处理团队问题时缺乏足够的统筹规划能力,容易在忙碌中忽视一些细节。在未来,我将更加注重提升自己的组织管理能力和团队协作能力,以更好地适应职场要求。
在个人品德方面,我虽然一直努力保持良好的道德修养,但偶尔也会因为忙碌而忽视自我反思和修炼。因此,我将继续加强自我反省,在日常生活中时刻保持谦逊与耐心,始终保持一颗向上的心态。
回顾大学四年,我收获了知识、实践经验、技能和友谊,收获了成长和进步。我会继续保持一颗积极向上的心,脚踏实地,不断提升自己。在未来的工作和生活中,我将继续发扬自己的优点,不断弥补不足,努力成为一名优秀的社会人才,为社会贡献自己的力量。通过不断学习与积累,我相信我能够在职业生涯中迎接更多的挑战,创造更多的价值。
#include "config.h"
#include "stm32f10x.h"
#include "delay1.h"
#include "bmp280.h"
#include "oled_iic.h"
#include <stdio.h>
#include "dht11.h"
#include "servo.h"
#include "string.h"
#include "sys.h"
#include "led.h"
#include "ultrasonic.h"
#include "timer1.h"
#define D1 PBout(0)
#define D2 PBout(1)
#define LED_SYS PCout(13)
u8 temp;
u8 humi;
char tempStr[20];
char pressStr[20];
int num = 30;
u8 state = 0;
extern char Rx232buffer[Buf_Max];
extern u8 recv_status;
static float bmp280_press, bmp280_temp;
u8 buff[30]; // 参数显示缓存数组
u16 Pre; // 气压检测值
char buff1[100]; // 缓存发送数据
float Angle = 0; // 初始化角度变量
float distance; //超声波测距用的变量
/***************************************************************************
* 延时函数
**************************************************************************/
void _delay_ms(int i) {
u16 j;
while (i--) {
for (j = 0; j < 5600; j++);
}
}
/***************************************************************************
* 处理接收数据
**************************************************************************/
void hand_recv(void) {
OLED_Clear();
delay_ms(1500);
if (Hand("ESPKLED1")) {
//USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led_on();
CLR_Buf();
//USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
else if (Hand("ESPGLED1")) {
//USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led_off();
CLR_Buf();
//USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
else if (Hand("EG")) { // 检测到 "EG" 命令
float newAngle = 30; // 设置舵机旋转30度
Servo_SetAngle(newAngle); // 设置舵机角度
char angleStr[30];
sprintf(angleStr, "Rotating servo to: %.2f\n", newAngle);
//USART_printf(USART1, angleStr); // 通过串口输出
}
else if (Hand("ON")) { // 检测到 "ON" 命令
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led1_on(); // 点亮LD1
CLR_Buf();
//USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
else if (Hand("OFF")) { // 检测到 "OFF" 命令
//USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led1_off(); // 熄灭LD1
CLR_Buf();
//USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
}
/***************************************************************************
* 发送数据到 ESP8266(HTTP 请求)
**************************************************************************/
void send_data_to_esp8266(u8 temp, u8 humi, float distance, float pressure) {
char http_request[500]; // 为了确保请求头和请求体足够大的空间
int request_len;
int json_len;
// 1. 建立 TCP 连接到目标服务器
printf("AT+CIPSTART=\"TCP\",\"192.168.224.238\",5002\r\n"); // 设置目标服务器 IP 和端口
delay_ms(500); // 等待连接建立
// 连接成功与否检查
if (strstr(Rx232buffer, "OK") != NULL) {
USART_printf(USART1, "TCP connected\n");
} else {
USART_printf(USART1, "TCP connection failed, response: %s\n");
USART_printf(USART1, Rx232buffer);
return; // 如果连接失败,直接返回
}
// 2. 构造 HTTP POST 请求
json_len = sprintf(http_request + 200, "{\"temp\": %d, \"humi\": %d, \"distance\": %.2f, \"pressure\": %.2f}",
temp, humi, distance, pressure);
// 计算 Content-Length
request_len = sprintf(http_request,
"POST / HTTP/1.1\r\n"
"Host: 192.168.224.238:5002\r\n"
"Content-Type: application/json\r\n"
"Content-Length: %d\r\n"
"Connection: close\r\n\r\n",
json_len); // Content-Length是JSON数据的长度
// 拼接请求头和请求体
strcat(http_request, http_request + 200);
// 打印构造的 HTTP 请求(调试信息)
USART_printf(USART1, "Sending HTTP request:\n");
USART_printf(USART1, http_request); // 打印 HTTP 请求
// 3. 发送 HTTP 请求数据前,首先告诉 ESP8266 要发送的数据长度
printf("AT+CIPSEND=%d\r\n", request_len); // 通知 ESP8266 发送的数据长度
delay_ms(500); // 等待响应
// 等待 ESP8266 返回 "OK",表示它已经准备好接收数据
if (strstr(Rx232buffer, ">") == NULL) {
USART_printf(USART1, "ESP8266 not ready to send data, response: %s\n");
USART_printf(USART1, Rx232buffer);
return; // 如果 ESP8266 没有返回 ">", 就说明它没有准备好接收数据
}
// 4. 发送 HTTP 请求数据
printf("%s", http_request); // 发送 HTTP 请求
delay_ms(1500); // 延长延时,确保请求数据已经完全发送
// 5. 等待 ESP8266 响应
if (strstr(Rx232buffer, "SEND OK") == NULL) {
USART_printf(USART1, "Failed to send HTTP request, response: %s\n");
USART_printf(USART1, Rx232buffer);
USART_printf(USART1, "Retrying...\n");
delay_ms(2000); // 延迟后重试
return; // 如果没有得到预期响应,返回
}
// 6. 关闭 TCP 连接
printf("AT+CIPCLOSE\r\n");
delay_ms(1000); // 延长延时,确保连接关闭
if (strstr(Rx232buffer, "CLOSED") != NULL) {
USART_printf(USART1, "TCP connection closed successfully\n");
} else {
USART_printf(USART1, "Failed to send TCP request, response: %s\n");
USART_printf(USART1, Rx232buffer);
}
CLR_Buf(); // 清空缓冲区
}
/***************************************************************************
* 8266 配置函数
**************************************************************************/
void config_8266(void) {
while (!(Hand("OK"))) {
printf("AT+CWMODE=1\r\n"); // 设置为 Station 模式
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
while (!(Hand("OK"))) {
printf("AT+CWJAP=\"666\",\"a1234567\"\r\n"); // 连接到指定的热点
delay_ms(2000);
printf("ESP8266 Wi-Fi connection status: %s\n", Rx232buffer); // 打印连接状态
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
delay_ms(500);
printf("AT+GMR\r\n");
delay_ms(500);
// 在启动服务器前加入一些延时
delay_ms(5000);
/*
// 启动服务器端口5002
while (!(Hand("OK"))) {
printf("AT+CIPSERVER=1,5002\r\n"); // 配置 ESP8266 为 TCP 服务器,监听端口5002
delay_ms(500);
// 检查是否成功启动服务器
if (strstr(Rx232buffer, "OK") != NULL) {
printf("***************************************** Server started on port 5002\n");
break; // 成功启动后跳出循环
} else if (strstr(Rx232buffer, "ERROR") != NULL) {
printf("ESP8266: Failed to start server on port 5002\n");
break; // 如果启动失败,跳出循环
} else {
printf("ESP8266: Unexpected response: %s\n", Rx232buffer); // 输出返回的串口数据
delay_ms(1000);
}
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
*/
while (!(Hand("OK"))) {
printf("AT+CIFSR\r\n");
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
delay_ms(1500);
CLR_Buf();
}
/***************************************************************************
* 主函数
**************************************************************************/
int main(void) {
SystemInit(); // 配置系统时钟为72M
delay_init(72);
led_init();
delay_ms(500);
LED_SYS = !LED_SYS;
delay_ms(500);
LED_SYS = !LED_SYS;
delay_ms(500);
Ultrasonic_Init(); // 测距初始化
OLED_Clear();
OLED_Init();
delay_ms(1500);
Servo_Init();
USART1_Init();
USART_printf(USART1, "欢迎使用STM32开发板\n\n");
esp8266_init();
LED_SYS = !LED_SYS;
delay_ms(500);
USART3_Init();
LED_SYS = !LED_SYS;
delay_ms(100);
config_8266(); // 配置ESP8266
delay_ms(500);
while (BMP280Init()) {
USART_printf(USART1, "BMP280初始化失败!\n");
delay_ms(1000);
}
while (DHT11_Init()) {
USART_printf(USART1, "DHT11初始化失败!\n");
delay_ms(1000);
}
OLED_Clear();
int displayIndex = 0;
char displayStr[20];
int send_counter = 0;
while (1) {
if (recv_status == 1) {
hand_recv(); // 处理接收到的数据
recv_status = 0;
}
DHT11_Read_Data(&temp, &humi); // 读取温湿度
BMP280GetData(&bmp280_press, &bmp280_temp, &bmp280_temp); // 获取气压数据
distance = UltrasonicGetLength(); // 获取超声波测量的距离
// 每2次循环发送一次HTTP请求
if (send_counter == 2) {
send_data_to_esp8266(temp, humi, distance, (float)Pre); // 发送数据到ESP8266
send_counter = 0;
} else {
send_counter++; // 增加计数器
}
switch (displayIndex) {
case 0:
sprintf(displayStr, "%d°C", temp);
break;
case 1:
sprintf(displayStr, "%d%%", humi);
break;
case 2:
sprintf(displayStr, "%.2fcm", distance);
break;
case 3:
sprintf((char*)buff, "%.2fhPa ", (float)Pre); // 显示气压值
break;
case 4:
sprintf(displayStr, "%.2fm", bmp280_temp); // 显示温度
break;
}
OLED_ShowCH(0, 5, (u8*)displayStr);
OLED_ShowCH(0, 5, buff);
//char tempStr[20];
//sprintf(tempStr, "%.2f", bmp280_temp);
//OLED_ShowCH(0, 5, (u8 *)tempStr);
displayIndex = (displayIndex + 1) % 4;
delay_ms(500);
}
}
#include "config.h"
#include "stm32f10x.h"
#include "delay1.h"
#include "bmp280.h"
#include "oled_iic.h"
#include <stdio.h>
#include "dht11.h"
#include "servo.h"
#include "string.h"
#include "sys.h"
#include "led.h"
#include "ultrasonic.h"
#include "timer1.h"
#define D1 PBout(0)
#define D2 PBout(1)
#define LED_SYS PCout(13)
u8 temp;
u8 humi;
char tempStr[20];
char pressStr[20];
int num = 30;
u8 state = 0;
extern char Rx232buffer[Buf_Max];
extern u8 recv_status;
static float bmp280_press, bmp280_temp;
u8 buff[30]; // 参数显示缓存数组
u16 Pre; // 气压检测值
char buff1[100]; // 缓存发送数据
float Angle = 0; // 初始化角度变量
float distance; //超声波测距用的变量
/***************************************************************************
* 延时函数
**************************************************************************/
void _delay_ms(int i) {
u16 j;
while (i--) {
for (j = 0; j < 5600; j++);
}
}
/***************************************************************************
* 处理接收数据
**************************************************************************/
void hand_recv(void) {
OLED_Clear();
delay_ms(1500);
if (Hand("ESPKLED1")) {
//USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led_on();
CLR_Buf();
//USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
else if (Hand("ESPGLED1")) {
//USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led_off();
CLR_Buf();
//USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
else if (Hand("EG")) { // 检测到 "EG" 命令
float newAngle = 30; // 设置舵机旋转30度
Servo_SetAngle(newAngle); // 设置舵机角度
char angleStr[30];
sprintf(angleStr, "Rotating servo to: %.2f\n", newAngle);
//USART_printf(USART1, angleStr); // 通过串口输出
}
else if (Hand("ON")) { // 检测到 "ON" 命令
USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led1_on(); // 点亮LD1
CLR_Buf();
//USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
else if (Hand("OFF")) { // 检测到 "OFF" 命令
//USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
led1_off(); // 熄灭LD1
CLR_Buf();
//USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
}
/***************************************************************************
* 发送数据到 ESP8266(HTTP 请求)
**************************************************************************/
void send_data_to_esp8266(u8 temp, u8 humi, float distance, float pressure) {
char http_request[500]; // 为了确保请求头和请求体足够大的空间
int request_len;
int json_len;
// 1. 建立 TCP 连接到目标服务器
printf("AT+CIPSTART=\"TCP\",\"192.168.224.238\",5002\r\n"); // 设置目标服务器 IP 和端口
delay_ms(500); // 等待连接建立
// 连接成功与否检查
if (strstr(Rx232buffer, "OK") != NULL) {
USART_printf(USART1, "TCP connected\n");
} else {
USART_printf(USART1, "TCP connection failed, response: %s\n");
USART_printf(USART1, Rx232buffer);
return; // 如果连接失败,直接返回
}
// 2. 构造 HTTP POST 请求
json_len = sprintf(http_request + 200, "{\"temp\": %d, \"humi\": %d, \"distance\": %.2f, \"pressure\": %.2f}",
temp, humi, distance, pressure);
// 计算 Content-Length
request_len = sprintf(http_request,
"POST / HTTP/1.1\r\n"
"Host: 192.168.224.238:5002\r\n"
"Content-Type: application/json\r\n"
"Content-Length: %d\r\n"
"Connection: close\r\n\r\n",
json_len); // Content-Length是JSON数据的长度
// 拼接请求头和请求体
strcat(http_request, http_request + 200);
// 打印构造的 HTTP 请求(调试信息)
USART_printf(USART1, "Sending HTTP request:\n");
USART_printf(USART1, http_request); // 打印 HTTP 请求
// 3. 发送 HTTP 请求数据前,首先告诉 ESP8266 要发送的数据长度
printf("AT+CIPSEND=%d\r\n", request_len); // 通知 ESP8266 发送的数据长度
delay_ms(500); // 等待响应
// 等待 ESP8266 返回 "OK",表示它已经准备好接收数据
if (strstr(Rx232buffer, ">") == NULL) {
USART_printf(USART1, "ESP8266 not ready to send data, response: %s\n");
USART_printf(USART1, Rx232buffer);
return; // 如果 ESP8266 没有返回 ">", 就说明它没有准备好接收数据
}
// 4. 发送 HTTP 请求数据
printf("%s", http_request); // 发送 HTTP 请求
delay_ms(1500); // 延长延时,确保请求数据已经完全发送
// 5. 等待 ESP8266 响应
if (strstr(Rx232buffer, "SEND OK") == NULL) {
USART_printf(USART1, "Failed to send HTTP request, response: %s\n");
USART_printf(USART1, Rx232buffer);
USART_printf(USART1, "Retrying...\n");
delay_ms(2000); // 延迟后重试
return; // 如果没有得到预期响应,返回
}
// 6. 关闭 TCP 连接
printf("AT+CIPCLOSE\r\n");
delay_ms(1000); // 延长延时,确保连接关闭
if (strstr(Rx232buffer, "CLOSED") != NULL) {
USART_printf(USART1, "TCP connection closed successfully\n");
} else {
USART_printf(USART1, "Failed to send TCP request, response: %s\n");
USART_printf(USART1, Rx232buffer);
}
CLR_Buf(); // 清空缓冲区
}
/***************************************************************************
* 8266 配置函数
**************************************************************************/
void config_8266(void) {
while (!(Hand("OK"))) {
printf("AT+CWMODE=1\r\n"); // 设置为 Station 模式
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
while (!(Hand("OK"))) {
printf("AT+CWJAP=\"666\",\"a1234567\"\r\n"); // 连接到指定的热点
delay_ms(2000);
printf("ESP8266 Wi-Fi connection status: %s\n", Rx232buffer); // 打印连接状态
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
delay_ms(500);
printf("AT+GMR\r\n");
delay_ms(500);
// 在启动服务器前加入一些延时
delay_ms(5000);
/*
// 启动服务器端口5002
while (!(Hand("OK"))) {
printf("AT+CIPSERVER=1,5002\r\n"); // 配置 ESP8266 为 TCP 服务器,监听端口5002
delay_ms(500);
// 检查是否成功启动服务器
if (strstr(Rx232buffer, "OK") != NULL) {
printf("***************************************** Server started on port 5002\n");
break; // 成功启动后跳出循环
} else if (strstr(Rx232buffer, "ERROR") != NULL) {
printf("ESP8266: Failed to start server on port 5002\n");
break; // 如果启动失败,跳出循环
} else {
printf("ESP8266: Unexpected response: %s\n", Rx232buffer); // 输出返回的串口数据
delay_ms(1000);
}
}
USART_printf(USART1, Rx232buffer);
CLR_Buf();
*/
while (!(Hand("OK"))) {
printf("AT+CIFSR\r\n");
delay_ms(500);
}
USART_printf(USART1, Rx232buffer);
delay_ms(1500);
CLR_Buf();
}
/***************************************************************************
* 主函数
**************************************************************************/
int main(void) {
SystemInit(); // 配置系统时钟为72M
delay_init(72);
led_init();
delay_ms(500);
LED_SYS = !LED_SYS;
delay_ms(500);
LED_SYS = !LED_SYS;
delay_ms(500);
Ultrasonic_Init(); // 测距初始化
OLED_Clear();
OLED_Init();
delay_ms(1500);
Servo_Init();
USART1_Init();
USART_printf(USART1, "欢迎使用STM32开发板\n\n");
esp8266_init();
LED_SYS = !LED_SYS;
delay_ms(500);
USART3_Init();
LED_SYS = !LED_SYS;
delay_ms(100);
config_8266(); // 配置ESP8266
delay_ms(500);
while (BMP280Init()) {
USART_printf(USART1, "BMP280初始化失败!\n");
delay_ms(1000);
}
while (DHT11_Init()) {
delay_ms(1000);
USART_printf(USART1, "DHT11初始化失败!\n");
delay_ms(1000);
}
OLED_Clear();
int displayIndex = 0;
char displayStr[20];
int send_counter = 0;
while (1) {
if (recv_status == 1) {
hand_recv(); // 处理接收到的数据
recv_status = 0;
}
DHT11_Read_Data(&temp, &humi); // 读取温湿度
BMP280GetData(&bmp280_press, &bmp280_temp, &bmp280_temp); // 获取气压数据
distance = UltrasonicGetLength(); // 获取超声波测量的距离
// 每2次循环发送一次HTTP请求
if (send_counter == 2) {
send_data_to_esp8266(temp, humi, distance, (float)Pre); // 发送数据到ESP8266
send_counter = 0;
} else {
send_counter++; // 增加计数器
}
// 打印读取的温湿度、大气压
char debugStr[100];
sprintf(debugStr, "Temp: %d°C, Humi: %d%%, Pressure: %.2f hPa, Distance: %.2f cm", temp, humi, bmp280_press, distance);
USART_printf(USART1, debugStr); // 打印到串口
switch (displayIndex) {
case 0:
sprintf(displayStr, "%d°C", temp);
break;
case 1:
sprintf(displayStr, "%d%%", humi);
break;
case 2:
sprintf(displayStr, "%.2fcm", distance);
break;
case 3:
sprintf(displayStr, "%.2fhPa ", (float)Pre); // 显示气压值
break;
case 4:
sprintf(displayStr, "%.2fm", bmp280_temp); // 显示温度
break;
}
OLED_ShowCH(0, 5, (u8*)displayStr);
//OLED_ShowCH(0, 5, buff);
//char tempStr[20];
//sprintf(tempStr, "%.2f", bmp280_temp);
//OLED_ShowCH(0, 5, (u8 *)tempStr);
displayIndex = (displayIndex + 1) % 5;
delay_ms(500);
}
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 涂良湘!