当前位置:首页 > 嵌入式 > 程序员小哈
[导读]风向变送器有8方位风向和360度风向两种; 外壳分为铝合金和聚碳两种; 风向传感器/变速器测量方式分为: 模拟量(4-20mA/0-5V/0-10V) RS485 由于风速和风向变送器是分开的,所以我们选择了RS485总线的测量方式,这样我们将两个模块并到一起,设为不同的地址



风向变送器有8方位风向和360度风向两种;


外壳分为铝合金和聚碳两种;


风向传感器/变速器测量方式分为:

  • 模拟量(4-20mA/0-5V/0-10V)
  • RS485


由于风速和风向变送器是分开的,所以我们选择了RS485总线的测量方式,这样我们将两个模块并到一起,设为不同的地址,这样就可以只占用一个串口资源就可以获取风速和风向的数据了。

应用场景

广泛适用于气象、海洋、环境、机场、港口、实验室、工农业及交通等领域的风速和风向测量。

数据帧格式定义

采用Modbus-RTU 通讯规约,格式如下: 

初始结构 ≥4 字节的时间 

地址码 = 1 字节 

功能码 = 1 字节 

数据区 = N 字节 

错误校验 = 16 位CRC 码 

结束结构 ≥4 字节的时间 

地址码:为变送器的地址,在通讯网络中是唯一的(出厂默认0x01)。 

功能码:主机所发指令功能指示,本变送器只用到功能码0x03(读取寄存器数据)。

数据区:数据区是具体通讯数据,注意16bits数据高字节在前! 

CRC码:二字节的校验码。

注意:此通讯协议只适用于我购买过的那款风速风向仪,不同厂家协议不同。

主机问询帧结构:

地址码 功能码 寄存器起始地址 寄存器长度 校验码低位 校验码高位
1字节 1字节 2字节 2字节 1字节 1字节

从机应答帧结构:

地址码 功能码 有效字节数 数据一区 第二数据区 第N数据区 校验码
1字节 1字节 1字节 2字节 2字节 2字节 2字节


通讯实例:

读取设备地址0x01的风向

问询帧:
地址码 功能码 起始地址 数据长度 CRC低位 CRC高位
0x01 0x03 0x00 0x00 0x00 0x02 0xC4 0x0B


应答帧:(例如读到风向值(0-7档)为2,(0-360°)为90°)
地址码 功能码 返回字节数 风向(0-7档) 风向(0-360°) CRC低位 CRC高位
0x01 0x03 0x04 0x00 0x02 0x00 0x5A 0xDB 0xC8
风向计算:

(0-7档):0002H(十六进制)= 2=> 风向 = 东风 

(0-360°):005AH (十六进制)= 90=> 风向= 东风

读取设备地址0x01的风速值

问询帧:
地址码 功能码 起始地址 数据长度 CRC低位 CRC高位
0x01 0x03 0x00 0x00 0x00 0x01 0x84 0x0A
应答帧:(例如读到当前风速为8.6m/s)
地址码 功能码 返回字节数 当前风速值 CRC低位 CRC高位
0x01 0x03 0x02 0x00 0x56 0x38 0x7A
风速计算:

当前风速:0056H(十六进制)= 86=> 风速 = 8.6m/s

硬件连接

  • 风速和风向变速器12V供电;
  • 我们使用一个485接口,将风速和风向变速器并联到了一起。

由于RS485的子设备之间的设备地址不能相同,所以我们将风速仪的地址设为了1,风向仪的地址设为了2。

RS485总线参考电路

要想获取风速或风向值,我们要经过如下三步操作:

(1)发送问询帧:

if(times%10==1){           times2++;             if(times2%10==0)       {              //求风速              sprintf(dtbuf, "%c%c%c%c%c%c%c%c", 0x01,0x03,0x00,0x00,0x00,0x01,0x84,0x0A);              MAX485DE=1;              USART2_OUT((u8 *)dtbuf, 8);              MAX485DE=0;                    }       else if(times2%10==5)       {              //求风向              sprintf(dtbuf, "%c%c%c%c%c%c%c%c", 0x02,0x03,0x00,0x00,0x00,0x02,0xC4,0x38);              MAX485DE=1;              USART2_OUT((u8 *)dtbuf, 8);              MAX485DE=0;       }}

(2)接收串口数据:

u16 USART2_RX_STA=0;         void USART2_IRQHandler(void){       u8 res;                if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)       {              res =USART_ReceiveData(USART2);                      if(USART2_RX_STA<USART2_MAX_RECV_LEN)              {                     TIM_SetCounter(TIM2,0);                       if(USART2_RX_STA==0)                            TIM2_Set(1);                      USART2_RX_BUF[USART2_RX_STA++]=res;               }              else              {                     USART2_RX_STA|=1<<15              }       }                                                                           }

(3)解析数据帧:

//解析RS485信息if(USART2_RX_STA&0x8000){       uart2Len=USART2_RX_STA&0x3f             if(uart2Len==7)       {              nCRC16 = crc16(USART2_RX_BUF,5);                           checkBitHig=(nCRC16>>8)&0xFF;              checkBitLow=nCRC16&0xFF               if(checkBitHig==USART2_RX_BUF[5]&&checkBitLow==USART2_RX_BUF[6])              {                     printf("收到风速数据包\r\n");                                         u16Value = USART2_RX_BUF[3] * 256 + USART2_RX_BUF[4];                      stuAliOSIoT.WindSpeed = u16Value/10.0;              }       }       else if(uart2Len==9)       {              nCRC16 = crc16(USART2_RX_BUF,7);                           checkBitHig=(nCRC16>>8)&0xFF;              checkBitLow=nCRC16&0xFF;               if(checkBitHig==USART2_RX_BUF[7]&&checkBitLow==USART2_RX_BUF[8])              {                     printf("收到风向数据包\r\n");                      stuAliOSIoT.WindDirection = USART2_RX_BUF[4];              }       }             USART2_RX_STA=0;          memset(USART2_RX_BUF, 0, sizeof(USART2_RX_BUF)); }

上面函数返回的数据帧,首先要对返回的数据进行CRC校验,只有合法的数据帧我们才会对数据帧进行解析,防止出现脏包。


推荐阅读:
STM32单片机最小系统详解
STM32F103 串口的使用方法
STM32中精确延时函数的实现




免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭