找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

求助:采用485采集风速和温度只能采一样

查看数: 734 | 评论数: 8 | 收藏 1
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2026-3-18 18:27

正文摘要:

本帖最后由 小桥流水不 于 2026-3-18 18:33 编辑   使用stc15f2k48s2单片机,485接收温湿度和风速,如果把Task1_Run里的//        if (currentTime - lastWindTime >= ...

回复

ID:1170469 发表于 2026-4-27 11:52
不要同时采集
ID:1169141 发表于 2026-4-2 13:01
理论上485总线挂多个设备需要自己设计通讯协议的,采用轮询问答的方式获取数据,不阻塞的方式就定时器定时计数,1采集谁,2采集谁,3采集谁,多少毫秒触发一次计数,问答间隔数据不冲突就行了
ID:844772 发表于 2026-3-24 10:00
能用就行啦,优化要理解,为啥你共用COM2作缓存会冲突。
ID:384109 发表于 2026-3-20 09:23
这本身就是你自己在通讯过程中造成的设备间的冲突,找错问题方向了
ID:1151496 发表于 2026-3-19 12:20
现在我把风速和温湿度的函数拆分开来,在主函数里定时调用,可以显示风速和温湿度了。不知道还有没有更好的方法?

/**
* @brief 任务1运行 读取温湿度
*/
void Task1_TempHumi_Run(void)
{
    // ========== 所有变量在函数开头定义 ==========
    // 时间相关变量
    static u32 xdata lastWindQueryTime = 0;    // 上次风速查询时间
    static u32 xdata lastTempQueryTime = 0;    // 上次温湿度查询时间
    static u32 xdata lastDisplayTime = 0;      // 上次显示更新时间
   
    // 上次显示值(用于比较是否变化)
    static u16 xdata lastWindSpeed = 0;
    static u16 xdata lastWindLevel = 0;
    static int xdata lastTemp = 0;
    static u16 xdata lastHumi = 0;
   
    // 风速状态机变量
    static u8 xdata windStep = 0;        // 0:空闲, 1:等待响应
    static u32 xdata windStartTime = 0;   // 风速请求发送时间
   
    // 温湿度状态机变量
    static u8 xdata tempStep = 0;         // 0:空闲, 1:等待响应
    static u32 xdata tempStartTime = 0;    // 温湿度请求发送时间
   
    // 当前时间(非静态,每次调用重新获取)
    u32 currentTime;
   
    // ========== 函数体开始 ==========
    currentTime = GetSysTimeMs();
   
   
       
            // ========== 温湿度查询(每2000ms一次)==========
    if (tempStep == 0)  // 只在空闲状态才能发送新请求
    {
        if (currentTime - lastTempQueryTime >= 1000)
        {
            ModbusMasterSendTempHumiData();  // 发送温湿度查询码
            tempStep = 1;
            tempStartTime = currentTime;
            lastTempQueryTime = currentTime;  // 更新查询时间
            printf("发送温湿度请求...\n");
        }
    }
       
    // ========== 处理温湿度响应 ==========
    if (tempStep == 1)
    {
        ModbusMasterReceiveTempHumi();
        
        // 接收完成
        if (COM2.RX_TimeOut == 0 && COM2.RX_Cnt == 0)
        {
            tempStep = 0;  // 回到空闲状态
            printf("温湿度接收完成\n");
        }
        // 超时处理(500ms无响应)
        else if (currentTime - tempStartTime > 500)
        {
            printf("温湿度响应超时\n");
            tempStep = 0;
            COM2.RX_Cnt = 0;  // 清空接收计数器
        }
    }
   
    // ========== 更新LCD显示==========


        
        if (temp != lastTemp || humi != lastHumi)
        {
            Temperature_Display(temp, 3, 4);
            Humidity_Display(humi, 4, 4);
            printf("LCD更新 - 温度:%d.%d℃ 湿度:%u.%u%%\n",
                   temp/10, (temp<0 ? -(temp%10) : temp%10),
                   humi/10, humi%10);
            lastTemp = temp;
            lastHumi = humi;
        }

   

}




/**
* @brief 任务1运行  读取风速风力
*/
void Task1_Wind_Run(void)
{
    // ========== 所有变量在函数开头定义 ==========
    // 时间相关变量
    static u32 xdata lastWindQueryTime = 0;    // 上次风速查询时间

    static u32 xdata lastDisplayTime = 0;      // 上次显示更新时间
   
    // 上次显示值(用于比较是否变化)
    static u16 xdata lastWindSpeed = 0;
    static u16 xdata lastWindLevel = 0;

   
    // 风速状态机变量
    static u8 xdata windStep = 0;        // 0:空闲, 1:等待响应
    static u32 xdata windStartTime = 0;   // 风速请求发送时间
   
    // 温湿度状态机变量

   
    // 当前时间(非静态,每次调用重新获取)
    u32 xdata currentTime;
   
    // ========== 函数体开始 ==========
    currentTime = GetSysTimeMs();
   
    // ========== 风速查询(每1000ms一次)==========
    if (windStep == 0)  // 只在空闲状态才能发送新请求
    {
        if (currentTime - lastWindQueryTime >= 1000)
        {
            ModbusMasterSendWindData();  // 发送风速查询码
            windStep = 1;
            windStartTime = currentTime;
            lastWindQueryTime = currentTime;  // 更新查询时间
            printf("发送风速请求...\n");
        }
    }
   

   
    // ========== 处理风速响应 ==========
    if (windStep == 1)
    {
        ModbusMasterReceiveWind();
        
        // 接收完成(COM2接收超时且计数为0)
        if (COM2.RX_TimeOut == 0 && COM2.RX_Cnt == 0)
        {
            windStep = 0;  // 回到空闲状态
            printf("风速接收完成\n");
        }
        // 超时处理(500ms无响应)
        else if (currentTime - windStartTime > 500)
        {
            printf("风速响应超时\n");
            windStep = 0;
            COM2.RX_Cnt = 0;  // 清空接收计数器
        }
    }
   
       

   
    // ========== 更新LCD显示==========

        
        if (windSpeed != lastWindSpeed || windLevel != lastWindLevel)
        {
            WindSpeed_Display(windSpeed, 1, 4);
            WindLevel_Display(windLevel, 2, 4);
            printf("LCD更新 - 风速:%u(%.2f) 风级:%u\n",
                   windSpeed, windSpeed * 0.01f, windLevel);
            lastWindSpeed = windSpeed;
            lastWindLevel = windLevel;
        }
        
   

   
   
}


void main(void)
{
        u8        i;
    u8 key_val;
        u32 xdata  run_time;
        u32 xdata  run_time2;

       
       
        Timer_config();
        UART_config();
        GPIO_config();
        Lcd12864_Init();
        EA = 1;

        Task1_Init();
        printf("Init is finish\n");
        while (1)
        {
                run_time = GetSysTimeMs();
                if(run_time - run_time2 >= 1100)
                {
                        run_time2 = run_time;
                        P00 = ~P00;
                }
  
               
       if(P00 == 0)
           {
                        Task1_TempHumi_Run();
           }
        
           else
           Task1_Wind_Run();


        }
}

ID:1151496 发表于 2026-3-19 12:16
glinfei 发表于 2026-3-19 08:52
就应该删掉,因为就一个总线,它可能导致总线冲突

485总线本身就可以挂载多个设备,我还想再添加几个
ID:384109 发表于 2026-3-19 09:15
485总线冲突了,同一个总线上的数据不可能相互独立的
ID:844772 发表于 2026-3-19 08:52
就应该删掉,因为就一个总线,它可能导致总线冲突

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表