写一个基于STM32的智能灌溉系统程序要求: 检测1块农田的土壤湿度和周围环境情况。 单片机A检测土壤湿度2路,并将湿度值取平均通过串行通信送给单片机B。 单片机B检测环境湿度,并接受A的湿度值。 单片机B设置LED数码管,显示土壤湿度,温度。当土壤湿度低于20%时,启动滴灌水阀门,直到湿度值达到95%以上,持续滴灌2分钟,设置系统停止按键 进阶任务: 单片机B检测光照强度,当环境温度高于40摄氏度或光照过强时,无论土壤湿度如何,不能启动滴灌,其他控制任务同上,并设置系统启动按键,使用LCD对所有信息(湿度,温度,光照,水阀状态)集中显示
时间: 2023-12-12 09:02:26 浏览: 102
好的,我为你提供一份基于STM32的智能灌溉系统程序代码,包括基本任务和进阶任务的实现。以下是代码:
```
#include "stm32f10x.h"
#include <stdio.h>
// 定义串口通信相关参数
#define USARTx USART1
#define USARTx_IRQn USART1_IRQn
#define USARTx_IRQHandler USART1_IRQHandler
#define USARTx_CLK RCC_APB2Periph_USART1
#define USARTx_GPIO_CLK RCC_APB2Periph_GPIOA
#define USARTx_TX_PIN GPIO_Pin_9
#define USARTx_TX_GPIO_PORT GPIOA
#define USARTx_RX_PIN GPIO_Pin_10
#define USARTx_RX_GPIO_PORT GPIOA
// 定义LED数码管相关参数
#define LED_GPIO_CLK RCC_APB2Periph_GPIOC
#define LED_GPIO_PORT GPIOC
#define LED_PIN_1 GPIO_Pin_0
#define LED_PIN_2 GPIO_Pin_1
#define LED_PIN_3 GPIO_Pin_2
#define LED_PIN_4 GPIO_Pin_3
#define LED_PIN_5 GPIO_Pin_4
#define LED_PIN_6 GPIO_Pin_5
#define LED_PIN_7 GPIO_Pin_6
#define LED_PIN_8 GPIO_Pin_7
#define DIGIT_GPIO_CLK RCC_APB2Periph_GPIOB
#define DIGIT_GPIO_PORT GPIOB
#define DIGIT_PIN_1 GPIO_Pin_12
#define DIGIT_PIN_2 GPIO_Pin_13
#define DIGIT_PIN_3 GPIO_Pin_14
#define DIGIT_PIN_4 GPIO_Pin_15
// 定义电磁阀门控制相关参数
#define VALVE_GPIO_CLK RCC_APB2Periph_GPIOB
#define VALVE_GPIO_PORT GPIOB
#define VALVE_PIN GPIO_Pin_0
// 定义光敏电阻相关参数
#define LDR_GPIO_CLK RCC_APB2Periph_GPIOA
#define LDR_GPIO_PORT GPIOA
#define LDR_PIN GPIO_Pin_0
// 定义DHT11或DHT22传感器相关参数
#define DHT_GPIO_CLK RCC_APB2Periph_GPIOB
#define DHT_GPIO_PORT GPIOB
#define DHT_PIN GPIO_Pin_1
// 定义延时函数
void Delay(__IO uint32_t nCount) {
for (; nCount != 0; nCount--);
}
// 定义串口发送函数
void USART_SendString(char* s) {
while (*s) {
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USART_SendData(USARTx, *s++);
}
}
// 定义LED数码管显示函数
void DisplayLED(int value) {
int digit[] = {LED_PIN_1, LED_PIN_2, LED_PIN_3, LED_PIN_4,
LED_PIN_5, LED_PIN_6, LED_PIN_7, LED_PIN_8};
int num[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
int i;
for (i = 0; i < 8; i++) {
GPIO_ResetBits(DIGIT_GPIO_PORT, digit[i]);
GPIO_Write(LED_GPIO_PORT, num[value % 10]);
value /= 10;
Delay(1000);
GPIO_SetBits(DIGIT_GPIO_PORT, digit[i]);
}
}
// 定义电磁阀门控制函数
void ControlValve(int isOpen) {
if (isOpen) {
GPIO_SetBits(VALVE_GPIO_PORT, VALVE_PIN);
} else {
GPIO_ResetBits(VALVE_GPIO_PORT, VALVE_PIN);
}
}
// 定义读取光敏电阻函数
float ReadLDR() {
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// 使能GPIO和ADC时钟
RCC_APB2PeriphClockCmd(LDR_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// 配置GPIO为模拟输入
GPIO_InitStructure.GPIO_Pin = LDR_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(LDR_GPIO_PORT, &GPIO_InitStructure);
// 配置ADC
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
// 配置ADC通道
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
// 启动ADC转换
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
float value = ADC_GetConversionValue(ADC1);
value = value / 4095.0 * 3.3;
value = (1.0 / value - 1.0) * 10000.0;
return value;
}
// 定义读取DHT11或DHT22传感器函数
void ReadDHT(int* temperature, int* humidity) {
GPIO_InitTypeDef GPIO_InitStructure;
int i, j, checksum;
// 使能GPIO时钟
RCC_APB2PeriphClockCmd(DHT_GPIO_CLK, ENABLE);
// 配置GPIO为输出
GPIO_InitStructure.GPIO_Pin = DHT_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DHT_GPIO_PORT, &GPIO_InitStructure);
// 发送起始信号
GPIO_ResetBits(DHT_GPIO_PORT, DHT_PIN);
Delay(18000);
GPIO_SetBits(DHT_GPIO_PORT, DHT_PIN);
// 配置GPIO为输入
GPIO_InitStructure.GPIO_Pin = DHT_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(DHT_GPIO_PORT, &GPIO_InitStructure);
// 等待返回信号
i = 0;
while (GPIO_ReadInputDataBit(DHT_GPIO_PORT, DHT_PIN) == RESET) {
i++;
Delay(10);
if (i > 100) {
return;
}
}
i = 0;
while (GPIO_ReadInputDataBit(DHT_GPIO_PORT, DHT_PIN) == SET) {
i++;
Delay(10);
if (i > 100) {
return;
}
}
// 读取数据
for (i = 0; i < 5; i++) {
for (j = 0; j < 8; j++) {
while (GPIO_ReadInputDataBit(DHT_GPIO_PORT, DHT_PIN) == RESET);
Delay(30);
if (GPIO_ReadInputDataBit(DHT_GPIO_PORT, DHT_PIN) == SET) {
humidity[i] |= (1 << (7 - j));
}
while (GPIO_ReadInputDataBit(DHT_GPIO_PORT, DHT_PIN) == SET);
}
}
// 校验数据
checksum = humidity[0] + humidity[1] + humidity[2] + humidity[3];
if (humidity[4] != (checksum & 0xFF)) {
return;
}
// 计算温度和湿度
*humidity = humidity[0] * 10 + humidity[1];
*temperature = humidity[2] * 10 + humidity[3];
}
int main() {
int humidity1, humidity2, temperature, isOpen, isStop;
float ldr;
// 使能GPIO时钟
RCC_APB2PeriphClockCmd(LED_GPIO_CLK | DIGIT_GPIO_CLK | VALVE_GPIO_CLK | LDR_GPIO_CLK, ENABLE);
// 配置LED数码管为输出
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = LED_PIN_1 | LED_PIN_2 | LED_PIN_3 | LED_PIN_4 |
LED_PIN_5 | LED_PIN_6 | LED_PIN_7 | LED_PIN_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = DIGIT_PIN_1 | DIGIT_PIN_2 | DIGIT_PIN_3 | DIGIT_PIN_4;
GPIO_Init(DIGIT_GPIO_PORT, &GPIO_InitStructure);
// 配置电磁阀门控制引脚为输出
GPIO_InitStructure.GPIO_Pin = VALVE_PIN;
GPIO_Init(VALVE_GPIO_PORT, &GPIO_InitStructure);
// 配置光敏电阻引脚为模拟输入
GPIO_InitStructure.GPIO_Pin = LDR_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(LDR_GPIO_PORT, &GPIO_InitStructure);
// 配置串口通信
RCC_APB2PeriphClockCmd(USARTx_CLK | USARTx_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = USARTx_TX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USARTx, &USART_InitStructure);
USART_Cmd(USARTx, ENABLE);
// 主循环
while (1) {
// 读取土壤湿度和环境温度
humidity1 = humidity2 = 0;
ReadDHT(&temperature, &humidity2);
humidity1 = (ADC_GetConversionValue(ADC1) + ADC_GetConversionValue(ADC2)) / 2;
// 发送土壤湿度和环境湿度到单片机B
char str[64];
sprintf(str, "%d,%d\n", humidity1, humidity2);
USART_SendString(str);
// 控制LED数码管显示土壤湿度和环境温度
DisplayLED(humidity1);
Delay(500);
DisplayLED(temperature);
Delay(500);
// 控制电磁阀门
isOpen = 0;
isStop = 0;
if (humidity1 < 20) {
isOpen = 1;
} else if (humidity1 > 95) {
isStop = 1;
} else {
ldr = ReadLDR();
if (temperature > 40 || ldr > 1000) {
isStop = 1;
} else {
isOpen = 1;
}
}
if (isOpen) {
ControlValve(1);
} else {
ControlValve(0);
}
if (isStop) {
GPIO_SetBits(LED_GPIO_PORT, LED_PIN_8);
} else {
GPIO_Reset
阅读全文