基于STM32F407的智慧农业系统

news2025/2/23 13:38:45

文章目录

  • 一、设备平台
  • 二、功能说明
  • 三、硬件系统设计实现与图表
  • 四、软件系统设计实现与流程图
  • 五、调试过程中出现的问题及相应解决办法
  • 六、程序设计
    • 1. 开始任务函数
    • 2. LED任务函数
    • 3. KEY任务函数
    • 4. UART任务函数
    • 5. OLED任务函数
    • 6. DHT11任务函数
    • 7. BEEP任务函数
    • 8. ADC任务函数
    • 9. PWM任务函数
    • 10. ESP8266任务函数


一、设备平台

在这里插入图片描述

二、功能说明

利用stm32开发板实现智慧农业的设计,基于STM32F407FreeRTOS实现如下九个功能模块:

  • 智慧农业定时系统:根据智慧农业的定时系统通过led灯的翻转现象变现系统的定时警告,具体利用定时器time4实现led2的每秒翻转。
  • 智慧农业PWM模块:根据脉冲调制实现呼吸灯led0的效果。
  • 智慧农业按键模块:通过按键key2实现led3的翻转效果。
  • 智慧农业显示系统:通过oled屏幕显示智慧农业的中文信息。
  • 智慧农业的串口打印模块:利用uart串口通信协议实现无线收发功能。
  • 智慧农业光照采集系统:利用ADC通过光敏电阻采集光照强度。
  • 智慧农业湿度采集系统:利用DHTL1采集温湿度,当温度大于30摄氏度使,蜂鸣器报警。
  • 智慧农业ESP8622模块:通过QT制图实现可视化的智慧农业系统。
  • 智慧农业风扇模块:通过电机驱动风扇,实现智慧农业的风扇降温系统。
    在这里插入图片描述

三、硬件系统设计实现与图表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、软件系统设计实现与流程图

本智慧农业系统模块,一共涉及9个模块(智慧农业定时系统、智慧农业PWM模块、智慧农业按键模块、智慧农业显示系统、智慧农业的串口打印模块、智慧农业光照采集系统、智慧农业湿度采集系统、智慧农业ESP8622模块、智慧农业风扇模块)。具体如下:

  • 1. 利用定时器time4实现led2的每秒翻转,LED2每隔1s闪烁一次,采用定时器TIM2计数功能实现,计数值到的时候产生溢出中断,灯的状态发送切换(RCC、NVIC,TIM2,GPIO,位操作,定时器2中断处理函数)
  • 2. 根据脉冲调制实现呼吸灯的效果,脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。 STM32F4 的定时器除了 TIM6 和 TIM7。其他的定时器都可以用来产生 PWM 输出。通过查看我们开发板的原理图发现,PF9引脚连接的是LED0,而且同时也是作TIM14_CH1的复用输出端口,这时候,我们可以使用PF9引脚,输出PWM波,来控制我们的LED0,使得LED0的亮灭有了更加美妙的呼吸状态。
  • 3. 通过按键key2实现led3的翻转效果,通过检测按键的按下的情况控制小灯的翻转
  • 4. 通过oled屏幕显示智慧农业的中文信息,通过对字符串s的取指操作,判断当前字节是否大于127,大于127说明对应的是汉字,将接下来的两个字节取出组合为汉字内码,通过内码查询字模数组中是否包含该字,查找到之后再将数据写入,显示到屏幕上。如果当前的字节小于128,则对应的是英文字符,直接使用例程的OLED_ShowChar函数写数据,就可以显示出来。
  • 5. 利用uart串口通信协议实现无线收发功能,通用异步收发器 UART是一种串行、异步、全双工的通信协议,将所需传输的数据一位接一位地传输,在UART通讯协议中信号线上的状态位高电平代表’1’,低电平代表’0’。其特点是通信线路简单,只要一对传输线就可以实现双向通信,大大降低了成本,但传送速度较慢。在串口通信中,尤其需要关注的是数据流以及波特率。一个数据流由10个数据位组成,包含1位起始位,7位有效数据位,1位奇偶校验位,1位停止位。uart串口信号线上空闲时常驻高电平,当检测到低电平下降沿时认为数据传输开始,到停止位时数据传输结束,一共10位数据位组成一个数据包。起始位:通信线路上空闲时为“1”,当检测到“0”即下降沿时,认为数据传输开始。有效数据位:传输开始后传递的需要接收和发送的数据值,可以表示指令或数据。奇偶校验位:奇偶校验,通过来校验传输数据中“1”的个数为奇数个(奇校验)或偶数个(偶校验)来指示传输数据是否正确。停止位:数据传输结束,传输线恢复常“1”状态。串口时钟使能 GPIO 时钟使能
    串口复位、GPIO 端口模式设置、串口参数初始化、开启中断 并且初始化 NVIC(如果需要开启中断才需要这个步骤)、使能串口、编写中断处理函数。程序功能是STM32通过 串口1 和上位机(PC)对话,STM32收到上位机发送的数据(字符串)后,将数据原原本本的返回给上位机。采用USART1的全双工异步串行收发模式。
  • 6. 利用ADC通过光敏电阻采集光照强度。
    光敏电阻内部就是一个PN结,光的强弱会引起其导通的变化,从而会引起电流的变化;电路设计方面,主要是利用电流的变化,然后在串联一个电阻,就可以转换成电压的变化,然后在利用ADC来采集电压的变化进行处理。同时光线与电压值成反比。ADC采集:电路上选择某个ADC和使用相应的通道选择。ADC的使用步骤:
    (1)第一步:开启相关ADC的时钟,设置分频因子。ADC_CCR寄存器。
    (2)第二步:ADC的工作模式设置,主要是:转换模式、触发方式、数据对齐等,
    ADCx_CR1,ACDx_CR2。
    (3)第三步:ADC规则序列通道设置规则序列中的通道数、和通道的采样周期,ADCx_SQR,ADCx_SMPR。
    (4)第四步:开启AD转换器,ADC_CRx寄存器。
    (5)第五步:读取ADC的值,ADC_DR寄存器的值
    具体过程是:转换序列设置,选择相应的规则序列,并添加要开启的通道。通过ADCx_CR来启动规则转换通道。通过ADCx_SR状态标志位,循环等待转换完成,直接还回ADCx_DR数据寄存器即可。
  • 7. 利用DHTL1采集温湿度,当温度大于30摄氏度使,蜂鸣器报警。HT11是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。通过单片机等微处理器简单的电路连接就能够实时的采集本地湿度和温度。DHT11与单片机之间能采用简单的单总线进行通信,仅仅需要一个1/0口。传感器内部湿度和温度数据40Bit的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。DHT11功耗很低, 5V电源电压下,工作平均最大电流0.5mA。DHT11数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向传输。其数据包由SByte (40Bit)组成。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。DHT11的数据格式为: 8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验和。其中校验和数据为前四个字节相加。传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开处理。
  • 8. 基于QT现象ESP8266无线连接,RXD、TXD、GND、VCC,分别和USB转TTL模块的TXD、RXD、GND、VCC相连接。ESP8266的RXD(数据的接收端)需要连接USB转TTL模块的TXD,TXD(数据的发送端)需要连接USB转TTL模块的RXD,在USB转TTL模块上有3.3V和5V两个引脚可以作为VCC,选取5V作为VCC。AT指令在使用USB转TTL模块与电脑连接之后,就可以使用串口调试助手进行WIFI模块的调试了。可将用户的物理设备连接到Wi-Fi 无线网络上,进行互联网或局域网通信,实现联网功能,使用AT指令进行控制。两个模组通过TCP/UDP相互通信。其中Server端为AP模式,Client端为Station模式。
    项目通过下位机采集数据,传输到电脑,所以下位机WIFI模块为Client端,电脑WIFI模块为Server端。
  • 9. 通过电机驱动风扇,实现智慧农业的风扇降温系统,利用电机控制风扇的转动,选择合适的电压控制电机的转动。
    在这里插入图片描述
    在这里插入图片描述

五、调试过程中出现的问题及相应解决办法

在本次项目过程中我们出现的问题有:

  1. 程序代码反复核对没有出现问题但实验板没有出现实验现象,最后经过更换实验板和更换电脑进行对比发现是实验板和模块之间的连接出现接触不良的问题,更换了实验板后调试成功。

  2. 通信串口无法建立连接,我们通过串口调试功能,实现了串口通信。

  3. 温湿度数据有误,通过串口调试,实现温湿度精准读取。

六、程序设计

1. 开始任务函数

void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区

    //创建TASK1任务
    xTaskCreate((TaskFunction_t )LED_task,             
                (const char*    )"LED_task",           
                (uint16_t       )LED_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )LED_TASK_PRIO,        
                (TaskHandle_t*  )&LED_Handler);  

xTaskCreate((TaskFunction_t )KEY_task,             
                (const char*    )"KEY_task",           
                (uint16_t       )KEY_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )KEY_TASK_PRIO,        
                (TaskHandle_t*  )&KEY_Handler);   

xTaskCreate((TaskFunction_t )UART1_task,             
                (const char*    )"UART1_task",           
                (uint16_t       )UART1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )UART1_TASK_PRIO,        
                (TaskHandle_t*  )&UART1_Handler); 

xTaskCreate((TaskFunction_t )OLED_task,             
                (const char*    )"OLED_task",           
                (uint16_t       )OLED_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )OLED_TASK_PRIO,        
                (TaskHandle_t*  )&OLED_Handler); 

xTaskCreate((TaskFunction_t )DHT11_task,             
                (const char*    )"DHT11_task",           
                (uint16_t       )DHT11_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )DHT11_TASK_PRIO,        
                (TaskHandle_t*  )&DHT11_Handler); 

xTaskCreate((TaskFunction_t )BEEP_task,             
                (const char*    )"BEEP_task",           
                (uint16_t       )BEEP_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )BEEP_TASK_PRIO,        
                (TaskHandle_t*  )&BEEP_Handler); 

xTaskCreate((TaskFunction_t )ADC_task,             
                (const char*    )"ADC_task",           
                (uint16_t       )ADC_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )ADC_TASK_PRIO,        
                (TaskHandle_t*  )&ADC_Handler); 

xTaskCreate((TaskFunction_t )PWM_task,             
                (const char*    )"PWM_task",           
                (uint16_t       )PWM_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )PWM_TASK_PRIO,        
                (TaskHandle_t*  )&PWM_Handler);
                
xTaskCreate((TaskFunction_t )ESP8266_task,             
                (const char*    )"ESP8266_task",           
                (uint16_t       )ESP8266_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )ESP8266_TASK_PRIO,        
                (TaskHandle_t*  )&ESP8266_Handler);

    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

2. LED任务函数

void LED_task(void *pvParameters)
{
    while(1)
    {
//LED1=!LED1; 
        vTaskDelay(500);
    }
}

3. KEY任务函数

void KEY_task(void *pvParameters)
{
    while(1)
    {
        vTaskDelay(500);
    }
}

4. UART任务函数

void UART1_task(void *pvParameters)
{
    while(1)
    {
		m=Rece_Data();
		if(!strncmp(m,"LED_ON",6))
		{
			LED0=0; 
			LED1=0; 
			LED2=0;
			printf("LED_ON success!\r\n");
			memset(m, 0, 8);
		}
		if(!strncmp(m,"LED_OFF",7))
		{
			LED0=1; 
			LED1=1; 
			LED2=1;
			printf("LED_OFF success!\r\n");
			memset(m, 0, 8);
		}
		if(!strncmp(m,"BEEP_ON",8))
		{
			BEEP=1;
			printf("BEEP_ON success!\r\n");
			memset(m, 0, 8);
		}
		if(!strncmp(m,"BEEP_OFF",9))
		{
			BEEP=0;
			printf("BEEP_OFF success!\r\n");
			memset(m, 0, 8);
		}

		printf("ADC  光照强度:%ld LUX\r\n",guangzhao);
		printf("DHT11  温度:%d.%d °C, 湿度:%d.%d %%rh\r\n",(int)temp,(int)tx,(int)humi,(int)hx);
		printf(" \r\n");
	    vTaskDelay(500);
    }
}

5. OLED任务函数

void OLED_task(void *pvParameters)
{
    while(1)
    {
		//在屏幕上打印结果
		Oled_print(50, 2,"IOT");
		Oled_print(0, 4,"  Intelligent  ");
		Oled_print(0, 6,"  Agriculture  ");
		//第1行显示重量
		OLed_ShowChina(50,0,HZ12);
		OLed_ShowChina(66,0,HZ13);
		//OLed_Fill(0x00);//描点清屏函数;
        vTaskDelay(500000);
    }
}

6. DHT11任务函数

void DHT11_task(void *pvParameters)
{
    while(1)
    {
		DHT_Recevice_Data(&humi,&temp,&hx,&tx);
        vTaskDelay(500);
    }
}

7. BEEP任务函数

void BEEP_task(void *pvParameters)
{
    while(1)
    {
		if(temp>=30)
		{
			BEEP=!BEEP;
			delay_ms(50);
		}
		else{
			BEEP=0; 
		}
        vTaskDelay(200);
    }
}

8. ADC任务函数

void ADC_task(void *pvParameters)
{
    while(1)
    {
		guangzhao=getAdcAverage(4); 
        vTaskDelay(500);
    }
}

9. PWM任务函数

void PWM_task(void *pvParameters)
{
    while(1)
    {
		int i=0;
		for(i=0;i<=1000;i=i+10)
		{ 
			TIM_SetCompare1(TIM1,i);
			delay_ms(20);
		}
        vTaskDelay(500);
    }
}

10. ESP8266任务函数

void ESP8266_task(void *pvParameters)
{
    while(1)
    {
    	ESP8266_test();
        vTaskDelay(500);
    }
}

若需完整工程联系下方wx即可👇👇👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/693685.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

写一个简单的静态html页面demo,包含幻灯片

效果图&#xff1a; 代码如下&#xff0c;图片文件可自行更换&#xff1a; <!DOCTYPE html> <html> <head><title>公司网站</title><style>/* 样式定义 */body {font-family: Arial, sans-serif;margin: 0;padding: 0;}header {backgrou…

什么是Session

1、web中什么是会话 &#xff1f; 用户开一个浏览器&#xff0c;点击多个超链接&#xff0c;访问服务器多个web资源&#xff0c;然后关闭浏览器&#xff0c;整个过程称之为一个会话。 2、什么是Session &#xff1f; Session:在计算机中&#xff0c;尤其是在网络应用中&…

Linux学习之进程概念和ps命令

进程概念和启动关闭进程 进程就是运行中的程序 在C语言中进程只能只能从main()函数开始运行。 进程终止的方式有两种&#xff1a; 正常终止&#xff1a;从main()函数返回、调用exit()等方式 异常终止&#xff1a;调用abort、接收信号等。有可能 ps ps是“process status”的缩…

华为OD机试真题 Python 实现【光伏场地建设规划】【2023Q1 100分】

一、题目描述 祖国西北部有一片大片荒地&#xff0c;其中零星的分布着一些湖泊&#xff0c;保护区&#xff0c;矿区&#xff1b;整体上常年光照良好&#xff0c;但是也有一些地区光照不太好。某电力公司希望在这里建设多个光伏电站&#xff0c;生产清洁能源。对每平方公里的土…

React入门(B站李立超老师)

视频地址&#xff1a;https://www.bilibili.com/video/BV1bS4y1b7NV/ 课程第一部分代码&#xff1a; https://pan.baidu.com/s/16hEN7j4hLDpd7NoFiS8dHw?pwd4gxv 提取码: 4gxv 课程第二部分代码&#xff1a;https://pan.baidu.com/s/1mDkvLqYVz1QGTV1foz5mQg?pwd5zir 提取码&…

NCV2903DR2G 低偏移电压比较器

NCV2903DR2G安森美深力科是一款双独立精密电压比较器&#xff0c;能够进行单电源或分电源操作。这些设备被设计为允许在单电源操作的情况下实现共模范围到地电平。低至2.0 mV的输入偏移电压规格使该设备成为消费类汽车和工业电子中许多应用的绝佳选择。 特性&#xff1a; 1.宽…

从密码学了解如何确定物联网信息安全

一.物联网安全概述 1.信息安全的主要内容 2.密码学 编码学和分析学的关系&#xff1a;相互对立、相互依存、相互促进 3.密码学历史 1.第一阶段&#xff1a;几千年前到1949年&#xff0c;此时还没有形成一门科学&#xff0c;靠密码分析者的直觉和经验来进行 代表&#xff1a;C…

DAY35——贪心part4

1. class Solution {public boolean lemonadeChange(int[] bills) {int five 0;int ten 0;for (int i 0; i < bills.length; i) {if (bills[i] 5) {five;} else if (bills[i] 10) {five--;ten;} else if (bills[i] 20) {if (ten > 0) { //贪心 优先使用面值为10的…

8.2 PowerBI系列之DAX函数专题-进阶-实现切片器筛选之间的or逻辑

需求 两个切片器之间都被选中的情况下&#xff0c;实现符合切片器条件的并集的结果呈现&#xff0c;而非交集的结果呈现&#xff0c; 实现 or #1 var occupations values(customer[occupation]) --获取到当前切片器选中的值 var bands values(product[brand]) return s…

Node环境中调用Python脚本

今天遇到一个需要在Node服务中调用Python脚本的需求&#xff0c;这里就把这个场景单独抽离出来汇总一下方法 在node中的child_process中有execSync, exec两个方法来创建一个子进程&#xff0c;然后在子进程里执行对应的python命令&#xff0c;这两个命令可以让我们执行一个脚本…

蓝桥杯专题-试题版-【完美的代价】【芯片测试】【序列求和】【杨辉三角形】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

Jmeter分布式压测配置

目录 前置条件 环境部署并使用 前置条件 电脑A&#xff0c;电脑B&#xff0c;电脑C均安装相同版本的JMeter 和JDK。其中电脑A作为控制机&#xff0c;电脑B和电脑C作为施压机 电脑A IP&#xff1a;172.16.0.114 电脑B IP&#xff1a;172.16.0.115 电脑C IP&#xff1a;172…

PLC通讯协议【三菱】FX协议的报文格式和读写示例

通过编程口通讯协议,具体可操作的软元件有:X/Y/M/S/T/C/D。 通讯设置 必须设置为:波特率9600,偶校验,7位数据位,1停止位。否则无法通讯。 一、报文结构 注意: 通讯协议中的所有字符是用它们的十六进制ASCII码表示。如果有十进制数据,要先转化为十六进制数,再把十六进制…

数据挖掘算法常用四大类

一、常用算法有哪四大类 既然我们知道数据挖掘的算法是为了寻找数据中潜在的知识&#xff0c;那么数据挖掘的算法通常都有哪些类型呢&#xff1f;如果说按照这些算法所解决的问题来进行划分&#xff0c;大致可以分为分类问题、聚类问题、回归问题和关联分析问题。下面我们就来…

chatgpt赋能python:如何使用Python读取手机短信

如何使用Python读取手机短信 在现代社会&#xff0c;短信已成为人们生活中不可或缺的一部分。那么&#xff0c;如何利用Python读取手机短信呢&#xff1f;本文将介绍如何使用Python读取手机短信&#xff0c;并提出一些相关的建议。 什么是Python Python是一种高级的、开源的…

高并发系统设计40问

01 | 高并发系统&#xff1a;它的通用设计方法是什么&#xff1f; 三种方法&#xff1a; Scale-out&#xff08;横向扩展&#xff09;&#xff1a;分而治之是一种常见的高并发系统设计方法&#xff0c;采用分布式部署的方式把流量分流开&#xff0c;让每个服务器都承担一部分并…

隐藏cobaltstrike服务器-nginx反向代理

隐藏nginx版本 编辑/etc/nginx/nginx.conf 取消server_tokens off 前面的注释 http转发80端口 编辑/etc/nginx/sites-enabled/default ## # You should look at the following URLs in order to grasp a solid understanding # of Nginx configuration files in order to …

【kubernetes系列】Kubernetes之RC、RS和Deployment

在实际的工作中&#xff0c;我们使用Kubernetes 通常不会直接创建 Pod&#xff0c;而是通过 各种 Controller 来管理 Pod 的。Controller 中定义了 Pod 的部署特性&#xff0c;比如有几个副本&#xff0c;在什么样的 Node 上运行等。为了满足不同的业务场景&#xff0c;Kuberne…

C++之thread的简单使用示例

1、全局函数传入thread #include <iostream> #include <thread> #include <string>void threadWork(std::string content, int counts) {for (int i 0; i < counts; i) {std::cout << content << i << std::endl;} }int main() {std:…

node-sass报错

我们安装vue项目时&#xff0c;经常遇到nade-sass报错。然后切换到某个node版本后不再报错&#xff0c;原因见下文 一&#xff1a;报错内容 二&#xff1a;保存原因 本地nodejs版本跟安装的node-sass版本不一致 三&#xff1a;解决办法 1、查看本地node版本 node -v 2、查…