STM32智慧农业系统开发实战教程:基于uC/OS-II系统实战解析

一、项目概述与设计思路

1.1 智慧农业系统需求分析

本智慧农业监测系统基于STM32F4系列微控制器开发,主要实现以下核心功能:

  • 环境参数采集(温湿度、光照强度、烟雾浓度)
  • 执行机构控制(PWM调速风扇、LED补光灯)
  • 异常状态报警(蜂鸣器、OLED显示)
  • 人机交互(按键控制、OLED界面)
  • 通信功能(LoRa无线模块)
  • 系统采用模块化设计思想,将传感器采集、执行机构控制、用户界面等模块进行解耦,通过uC/OS-II实时操作系统实现多任务调度。

    1.2 硬件架构设计

    系统硬件组成框架:

    [传感器层]
    ├─ DHT11温湿度传感器
    ├─ 光敏电阻(PF7 ADC)
    ├─ MQ-2烟雾传感器(PA6 ADC + PE6中断)
    ├─ 按键模块
    
    [控制层]
    ├─ STM32F407主控
    ├─ PWM风扇(PC7 TIM3-CH2)
    ├─ LED补光灯(PC6 TIM3-CH1)
    
    [交互层]
    ├─ OLED显示屏(I2C:PB8-PB9)
    ├─ 蜂鸣器模块
    
    [通信层]
    └─ LoRa模块(USART1)
    

    1.3 软件架构设计

    基于uC/OS-II的多任务系统:

    https://i3.wp.com/img-blog.csdnimg.cn/20210320161536932.png

    主要任务划分:

  • 传感器采集任务
  • 环境控制任务
  • 用户界面任务
  • 通信处理任务
  • 报警处理任务
  • 二、硬件接口配置详解

    2.1 GPIO功能分配

    根据文档1配置关键引脚:

    c

    Copy

    /* 引脚功能映射表 */
    typedef struct {
        GPIO_TypeDef* GPIOx;
        uint16_t GPIO_Pin;
        GPIOMode_TypeDef Mode;
    } PinConfig;
    
    const PinConfig pinConfig[] = {
        {GPIOB, GPIO_Pin_8,  GPIO_Mode_AF},  // I2C1_SCL
        {GPIOB, GPIO_Pin_9,  GPIO_Mode_AF},  // I2C1_SDA
        {GPIOE, GPIO_Pin_6,  GPIO_Mode_IN},  // 烟雾中断
        {GPIOA, GPIO_Pin_6,  GPIO_Mode_AN},   // 烟雾ADC
        {GPIOF, GPIO_Pin_7,  GPIO_Mode_AN},   // 光敏ADC
        {GPIOC, GPIO_Pin_6,  GPIO_Mode_AF},  // TIM3_CH1
        {GPIOC, GPIO_Pin_7,  GPIO_Mode_AF}   // TIM3_CH2
    };
    

    2.2 外设时钟配置

    外设时钟使能顺序:

    c

    Copy

    void RCC_Configuration(void)
    {
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
                              RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOE, ENABLE);
        
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    }
    

    三、关键外设驱动实现

    3.1 OLED显示模块

    3.1.1 I2C驱动层

    采用软件模拟I2C协议(文档7):

    c

    Copy

    void I2C_Start(void)
    {
        SDA_HIGH();
        SCL_HIGH();
        delay_us(5);
        SDA_LOW();
        delay_us(5);
        SCL_LOW();
    }
    
    void I2C_WriteByte(uint8_t data)
    {
        for(uint8_t i=0;i<8;i++){
            (data & 0x80) ? SDA_HIGH() : SDA_LOW();
            SCL_HIGH();
            delay_us(5);
            SCL_LOW();
            data <<= 1;
        }
    }
    
    3.1.2 显示应用层

    实现多级菜单系统:

    c

    Copy

    typedef struct {
        uint8_t currentMenu;
        void (*DisplayFunc)(void);
    } MenuSystem;
    
    void OLED_DisplayTask(void *pdata)
    {
        MenuSystem menu;
        while(1){
            switch(menu.currentMenu){
                case 0: ShowMainPage(); break;
                case 1: ShowEnvData(); break;
                case 2: ShowSettings(); break;
            }
            OSTimeDlyHMSM(0,0,0,500);
        }
    }
    

    3.2 PWM控制模块

    TIM3通道配置(文档10):

    c

    Copy

    void PWM_Init(void)
    {
        TIM_TimeBaseInitTypeDef TIM_BaseStruct;
        TIM_OCInitTypeDef TIM_OCStruct;
    
        // 时基配置:1kHz PWM频率
        TIM_BaseStruct.TIM_Prescaler = 84-1; 
        TIM_BaseStruct.TIM_Period = 1000-1;
        TIM_TimeBaseInit(TIM3, &TIM_BaseStruct);
    
        // 输出比较配置
        TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM1;
        TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCStruct.TIM_Pulse = 0; // 初始占空比0%
        
        TIM_OC1Init(TIM3, &TIM_OCStruct); // PC6
        TIM_OC2Init(TIM3, &TIM_OCStruct); // PC7
        
        TIM_Cmd(TIM3, ENABLE);
    }
    

    3.3 烟雾传感器驱动

    双重检测机制实现(ADC+中断):

    c

    Copy

    void Smoke_Init(void)
    {
        // ADC配置
        ADC_CommonInitTypeDef ADC_CommonInitStruct;
        ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;
        ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div2;
        ADC_CommonInit(&ADC_CommonInitStruct);
    
        // 中断配置
        EXTI_InitTypeDef EXTI_InitStruct;
        EXTI_InitStruct.EXTI_Line = EXTI_Line6;
        EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
        EXTI_Init(&EXTI_InitStruct);
    }
    

    四、实时操作系统整合

    4.1 uC/OS-II任务创建

    系统任务初始化流程(文档2):

    c

    Copy

    void main(void)
    {
        OSInit();
        
        // 创建系统任务
        OSTaskCreate(AppTask_Init, (void*)0, &init_stk[TASK_STK_SIZE-1], TASK_PRIO_INIT);
        OSTaskCreate(AppTask_Sensor, (void*)0, &sensor_stk[TASK_STK_SIZE-1], TASK_PRIO_SENSOR);
        OSTaskCreate(AppTask_Control, (void*)0, &control_stk[TASK_STK_SIZE-1], TASK_PRIO_CTRL);
        
        OSStart();
    }
    

    4.2 任务间通信设计

    使用事件标志组实现传感器数据同步:

    c

    Copy

    OS_FLAG_GRP *SensorFlagGrp;
    
    void Sensor_Task(void *pdata)
    {
        while(1){
            // 采集所有传感器数据
            ReadDHT11();
            ReadLightSensor();
            ReadSmokeSensor();
            
            // 设置数据就绪标志
            OSFlagPost(SensorFlagGrp, DATA_READY_FLAG, OS_FLAG_SET, &err);
            
            OSTimeDlyHMSM(0,0,2,0); // 2秒采集周期
        }
    }
    
    void Control_Task(void *pdata)
    {
        while(1){
            // 等待数据就绪
            OSFlagPend(SensorFlagGrp, DATA_READY_FLAG, OS_FLAG_WAIT_SET_ALL, 0, &err);
            
            // 执行控制逻辑
            EnvControlLogic();
        }
    }
    

    五、系统控制逻辑实现

    5.1 环境自适应控制算法

    实现模糊PID控制:

    c

    Copy

    typedef struct {
        float Kp, Ki, Kd;
        float integral_max;
        float last_error;
        float integral;
    } FuzzyPID;
    
    float FuzzyPID_Calculate(FuzzyPID *pid, float setpoint, float actual)
    {
        float error = setpoint - actual;
        pid->integral += error;
        
        // 积分限幅
        if(pid->integral > pid->integral_max) pid->integral = pid->integral_max;
        if(pid->integral < -pid->integral_max) pid->integral = -pid->integral_max;
        
        float derivative = error - pid->last_error;
        float output = pid->Kp*error + pid->Ki*pid->integral + pid->Kd*derivative;
        
        pid->last_error = error;
        return output;
    }
    

    5.2 异常处理机制

    烟雾浓度三级报警策略:

    c

    Copy

    void Smoke_Handler(void)
    {
        float smoke_level = GetSmokeLevel();
        
        if(smoke_level > WARNING_THRESHOLD){
            OSFlagPost(AlarmFlagGrp, SMOKE_ALARM_FLAG, OS_FLAG_SET, &err);
            SetFanSpeed(MAX_SPEED);
        }
        else if(smoke_level > NOTICE_THRESHOLD){
            Beep_Alert(INTERMITTENT_BEEP);
            AdjustFanSpeed(smoke_level);
        }
        else{
            OSFlagPost(AlarmFlagGrp, SMOKE_ALARM_FLAG, OS_FLAG_CLR, &err);
        }
    }
    

    六、开发经验与调试技巧

    6.1 常见问题解决

    问题1:PWM输出不稳定

  • 检查TIM分频系数设置
  • 验证GPIO重映射是否正确
  • 使用示波器观察波形
  • 问题2:OLED显示花屏

  • 检查I2C时序是否满足器件要求
  • 确认显示缓冲区正确清零
  • 验证电源稳定性
  • 6.2 性能优化建议

    1. ADC采样优化

    c

    Copy

    #define SAMPLE_NUM 32
    uint16_t ADC_AverageFilter(ADC_TypeDef* ADCx)
    {
        uint32_t sum = 0;
        for(uint8_t i=0; i<SAMPLE_NUM; i++){
            sum += ADC_GetConversionValue(ADCx);
        }
        return sum / SAMPLE_NUM;
    }
    
    1. 任务优先级分配原则
  • 传感器采集任务 > 控制任务 > 界面任务
  • 中断服务任务保持最高优先级
  • 七、项目扩展方向

    7.1 功能扩展建议

    1. 增加土壤湿度监测
    2. 集成WiFi/4G远程监控
    3. 添加太阳能供电模块
    4. 实现Android端APP控制

    7.2 物联网集成方案

    构建MQTT通信框架:

    c

    Copy

    void MQTT_Publish(const char *topic, float data)
    {
        char payload[50];
        sprintf(payload, "{\"value\":%.1f}", data);
        
        Lora_SendData(topic);
        Lora_SendData(payload);
    }
    
    void Lora_Callback(char *msg)
    {
        // 解析云平台指令
        if(strstr(msg, "FAN_CTRL")){
            uint8_t speed = atoi(msg+9);
            SetFanSpeed(speed);
        }
    }
    

    八、总结与学习资源

    8.1 项目总结

    本系统完整实现了智慧农业的环境监测与控制功能,关键技术点包括:

  • 多传感器数据融合
  • 实时操作系统应用
  • 闭环控制算法实现
  • 低功耗设计思想
  • 8.2 推荐学习资料

    1. 《STM32F4xx中文参考手册》
    2. uC/OS-II官方文档
    3. 《嵌入式实时操作系统原理与应用》

    作者:四代目 水门

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32智慧农业系统开发实战教程:基于uC/OS-II系统实战解析

    发表回复