ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

STM32移植BACnet协议栈实战:低成本DDC控制器开发指南

STM32移植BACnet协议栈实战:低成本DDC控制器开发指南 1. 项目缘起与整体方案设计1.1 为什么要在STM32上跑BACnet DDC楼宇自控这个行当里DDC控制器是绝对的主力选手。传统上大家用的都是江森、霍尼韦尔、西门子这些品牌的成品价格高、交期长而且很多时候功能冗余得厉害——一个风机盘管控制要花大几百甚至上千块。我最早接触BACnet是在一个改造项目上甲方要求把老旧的独立温控器接入楼宇自控系统原厂方案报价直接把我劝退了。后来琢磨着自己用STM32搭一个成本能压到几十块钱而且协议栈完全可控想怎么改就怎么改。BACnet本身是楼宇自控领域最主流的通信协议之一ASHRAE 135标准定义的东西支持多种物理层——MS/TP走RS-485、BACnet/IP走以太网。DDC控制器的核心任务就三件事采集传感器数据、执行控制逻辑、跟上层系统通信。STM32做前两件事绰绰有余第三件事需要协议栈支持。BACnet协议栈有开源的、有商业的我选的是开源的BACnet Stack移植到STM32上跑配合W5500以太网芯片实现BACnet/IP通信。这个方案适合谁呢如果你有STM32开发基础想进入楼宇自控领域或者手头有项目需要低成本定制DDC那这套东西值得花时间搞一搞。不需要你精通BACnet协议的全部细节但基本的对象、属性、服务这几个概念得理解。Yabe工具是Windows上的BACnet测试客户端用来验证你的设备能不能被正常发现和读写相当于调试阶段的“眼睛”。1.2 硬件选型与核心器件解析硬件这块我踩过不少坑最终定下来的方案是STM32F407VGT6加W5500。为什么选F407首先它有以太网MAC虽然我们外挂W5500用SPI但F407的RAM有192KB跑BACnet协议栈加应用逻辑绰绰有余。F103系列也能跑但RAM只有20KB协议栈一跑就捉襟见肘了。F407的主频168MHz处理BACnet的编解码和定时任务毫无压力。W5500是WIZnet出的硬件TCP/IP芯片SPI接口内置10/100M以太网PHY和MAC。选它而不是用STM32自带的以太网MAC加外部PHY主要原因是软件工作量小——W5500把TCP/IP协议栈做在硬件里了MCU只需要通过SPI读写socket寄存器就行。对于BACnet/IP来说底层就是UDP通信W5500的UDP socket用起来很顺手。而且W5500的参考电路很成熟网上能找到大量现成的原理图照着画基本不会出问题。这里要重点说一下W5500的参考电路。晶振用25MHz的负载电容根据晶振规格书来一般12pF到22pF之间。RXIP/RXIN和TXOP/TXON这两对差分信号线要严格等长阻抗控制到50欧姆。网络变压器用常见的HR911105A或者HanRun的集成RJ45座内部自带变压器和LED。SPI接口的四根线——CS、SCK、MISO、MOSI——走线尽量短如果距离超过10厘米建议加串联电阻匹配。复位电路用10K上拉加100nF电容保证上电复位可靠。电源部分W5500是3.3V供电电流大概150mA左右。STM32F407也是3.3V但内核电流加上外设整体功耗在200mA到300mA之间。我用的是AMS1117-3.3输入5V输出3.3V。这里有个细节AMS1117的输出电容如果用钽电容ESR在1欧姆左右环路稳定性好换成陶瓷电容的话ESR太低可能导致振荡。我实测用10uF钽电容加100nF陶瓷电容并联输出很稳。如果非要用陶瓷电容建议选X5R或X7R材质容量至少22uF并且加一个1欧姆的串联电阻来模拟ESR。1.3 软件架构与协议栈选型软件架构分三层底层驱动、BACnet协议栈、应用逻辑。底层驱动包括W5500的SPI驱动、定时器驱动、串口调试驱动。BACnet协议栈我移植的是开源的BACnet Stack版本0.8.6这个版本比较稳定代码量适中裁剪后大概占用60KB Flash和15KB RAM。应用逻辑就是DDC的具体控制策略比如PID调节、时间表、报警处理这些。为什么选BACnet Stack而不是自己从头写BACnet协议本身很复杂光是对象类型就有几十种服务有几十个自己写工作量太大而且容易出兼容性问题。开源栈虽然代码风格一般但功能完整跟Yabe这类标准客户端对接没问题。移植的主要工作是实现底层的数据收发接口和定时器接口协议栈本身跟硬件无关。BACnet/IP的通信流程是这样的设备上电后协议栈会周期性地发送I-Am广播告诉网络里的其他设备“我在这里”。Yabe收到广播后就能在设备列表里看到你的设备。然后Yabe可以发送Who-Is广播来主动发现设备你的设备收到后回复I-Am。建立连接后Yabe可以读取设备对象的属性比如对象列表、设备名称、厂商ID这些。你也可以在代码里定义自己的模拟输入、模拟输出、二进制输入、二进制输出对象Yabe就能读写这些对象的Present Value属性。2. 核心细节解析与实操要点2.1 W5500驱动移植的关键步骤W5500的驱动移植是整个项目的地基这块搞不定后面都白搭。SPI接口配置成模式0或者模式3都行W5500两种都支持。我习惯用模式0CPOL0CPHA0数据在SCK上升沿采样。SPI时钟频率不要超过30MHz我一般设到10MHz左右稳定可靠。STM32F407的SPI1挂载在APB2总线上84MHz时钟分频到10.5MHz。W5500的寄存器访问分两个阶段先发地址阶段再发数据阶段。地址阶段发3个字节第一个字节是地址的高8位第二个字节是地址的低8位第三个字节是控制字节包含块选择位和读写标志。数据阶段就是读或写1个字节。这个时序一定要严格按照数据手册来我一开始地址阶段多发了一个字节结果读出来的全是0xFF查了半天才发现是时序错了。W5500初始化流程先硬件复位拉低RST引脚至少500us然后拉高等待至少1ms让内部PLL锁定。然后软件复位写MR寄存器的RST位等待复位完成。接着设置网络信息网关地址、子网掩码、本机IP、MAC地址。MAC地址可以随便设但建议用STM32的UID生成保证唯一性。然后设置重试时间和重试次数一般重试时间200ms重试次数3次。最后打开需要的socket设置协议为UDP绑定本地端口。BACnet/IP默认端口是47808十六进制是0xBAC0。Socket的收发数据通过W5500的TX/RX缓冲区进行。每个socket有2KB的TX缓冲和2KB的RX缓冲总共8个socket。对于BACnet/IP一个socket就够了。发送数据时先写TX写指针寄存器然后通过SPI把数据写进TX缓冲区最后写TX命令寄存器启动发送。接收数据时读RX接收长度寄存器然后从RX缓冲区读数据最后写RX命令寄存器释放缓冲区。这个过程要仔细处理指针回绕W5500的缓冲区是环形的写指针到末尾会自动回到开头。2.2 BACnet协议栈的裁剪与配置BACnet Stack的源码结构比较清晰核心文件是bacnet.h、bacnet.c、apdu.c、npdu.c这些。移植到STM32上首先要裁剪掉不需要的部分。比如MS/TP相关的代码可以全部去掉因为我们只用BACnet/IP。BBMDBACnet广播管理设备的功能也可以去掉除非你的网络跨网段。还有一些不常用的对象类型和服务都可以在编译选项里关掉。协议栈需要两个硬件相关的接口一个是数据发送函数一个是定时器。数据发送函数在bacnet.c里有个弱定义你需要在自己的代码里实现一个同名的强定义函数把数据通过W5500发出去。定时器方面协议栈需要一个毫秒级的时基我用STM32的TIM2做一个1ms的定时中断在中断里维护一个全局的毫秒计数器。协议栈的主循环里会调用bacnet_task函数这个函数内部会检查各种超时比如APDU重传超时、设备发现超时这些。设备对象的配置在device.c里。你需要设置设备实例号Device Instance Number这个号在整个BACnet网络里必须唯一。厂商ID可以填999表示非标厂商。设备名称可以填“STM32 DDC Controller”。对象列表里要包含你实际用到的对象比如AI-0到AI-7表示8路模拟输入AO-0到AO-3表示4路模拟输出BI-0到BI-7表示8路二进制输入BO-0到BO-3表示4路二进制输出。每个对象都要有Present Value属性这是Yabe读写的主要属性。模拟输入对象的配置要注意Present Value的类型是Real单位可以设成degreesCelsius摄氏度。COV增量Change of Value Increment设成0.5意思是温度变化超过0.5度就主动上报。可靠性属性设成no-fault-detected。模拟输出对象除了Present Value还要有Relinquish Default属性这个属性在收到Relinquish服务时决定输出回到什么值。二进制对象类似Present Value是枚举类型active和inactive两种状态。2.3 Yabe工具的安装与网络配置Yabe是SourceForge上的开源项目全称是“Yet Another BACnet Explorer”。下载下来是个压缩包解压后直接运行Yabe.exe就行不需要安装。运行之前要确保你的电脑跟STM32设备在同一个网段。比如STM32的IP是192.168.1.100子网掩码255.255.255.0那电脑的IP就设成192.168.1.101子网掩码一样。如果电脑有多张网卡要在Yabe的设置里指定用哪张网卡发广播。Yabe启动后界面分左右两栏。左边是设备树右边是属性列表。第一次用的时候点菜单里的“Add Device”输入设备的IP和端口。BACnet/IP默认端口是47808但Yabe里填的时候要注意有些版本要求填十进制有些要求填十六进制。我用的版本是填十进制47808。添加完设备后点“Who-Is”按钮Yabe会发广播你的STM32设备收到后回复I-Am然后设备就会出现在设备树里。如果设备没出现先检查网络连通性。在电脑上ping一下STM32的IP能ping通说明物理层和网络层没问题。然后检查W5500的socket状态在代码里读一下Sn_SR寄存器应该是SOCK_UDP状态。再检查BACnet端口有没有被占用47808端口如果被其他程序占了W5500就绑定不上。最后检查Yabe的广播地址有些版本默认广播到255.255.255.255如果你的网络不支持全局广播要改成子网广播地址比如192.168.1.255。Yabe里读取属性很简单在设备树里展开设备对象选中某个对象右边就会列出所有属性。双击Present Value就能看到当前值。写入属性的话右键点属性选“Write Property”输入要写的值点确定。如果写入失败Yabe会弹错误码比如“Error: Write Access Denied”说明这个属性是只读的或者你的设备没有实现WriteProperty服务。BACnet的错误码很详细根据错误码基本能定位问题。3. 实操过程与核心环节实现3.1 硬件焊接与上电测试PCB打样回来之后先别急着焊所有的件。第一步只焊电源部分AMS1117、输入输出电容、电源指示灯。焊完用万用表测一下3.3V输出应该在3.25V到3.35V之间。如果电压不对先检查AMS1117的焊接有没有虚焊输入输出有没有短路。我遇到过一回输出只有1.2V查了半天发现是输出电容焊反了钽电容是有极性的焊反了相当于短路。电源正常后焊STM32和它的外围8MHz晶振、两个22pF负载电容、复位电路、BOOT0和BOOT1的下拉电阻、SWD调试接口。焊完先不焊W5500用ST-Link连上看能不能识别到芯片。如果识别不到检查SWDIO和SWCLK有没有接反复位引脚有没有被拉低。STM32F407的BOOT0必须接地否则从系统存储器启动ST-Link就连不上。STM32能识别后焊W5500和它的外围25MHz晶振、负载电容、网络变压器、RJ45座、SPI上拉电阻。W5500的SPI接口建议加上拉电阻CS、SCK、MOSI各一个10K上拉到3.3VMISO不用。网络变压器的中心抽头要接3.3V通过一个0.1uF电容去耦。RJ45座的LED引脚通过限流电阻接到3.3V绿灯表示连接黄灯表示活动。全部焊完后上电先测W5500的3.3V供电然后测晶振有没有起振。用示波器看25MHz晶振引脚应该有正弦波峰峰值大概1V左右。如果没有起振检查负载电容和晶振本身。W5500的晶振电路比较敏感负载电容不匹配的话可能不起振。我试过用22pF的负载电容起振很慢换成15pF就正常了。具体值要看晶振的规格书一般负载电容是12pF到18pF。3.2 底层驱动代码实现SPI驱动先写。STM32F407的SPI1初始化GPIOA的PA5、PA6、PA7配置成复用推挽输出PA4配置成普通推挽输出做CS。SPI参数主机模式、8位数据、CPOL0、CPHA0、预分频到10.5MHz、MSB先行。初始化完先读W5500的版本寄存器地址0x0039应该读到0x04。读不到的话检查SPI时序和CS控制。W5500的读写函数封装成两个w5500_read和w5500_write。读函数先拉低CS发地址高8位、地址低8位、控制字节块选择读标志然后发一个dummy字节读回数据最后拉高CS。写函数类似只是控制字节是写标志最后一个字节是要写的数据。控制字节的格式最高位是读写标志1读0写第3到第7位是块选择0是通用寄存器1是socket0寄存器2是socket0 TX缓冲3是socket0 RX缓冲以此类推。网络参数配置函数先软件复位写MR寄存器的RST位延时10ms。然后写GAR网关地址、SUBR子网掩码、SHAR本机MAC、SIPR本机IP。MAC地址我用STM32的UID生成UID在0x1FFF7A10地址96位取低48位最高字节或上0x02表示本地管理地址。然后写RTR重试时间和RCR重试次数RTR设2000200msRCR设3。最后写SIMRsocket中断掩码打开socket0的中断。Socket初始化写Sn_MR寄存器设成UDP模式打开广播接收。写Sn_PORT寄存器设成47808。写Sn_CR寄存器执行OPEN命令。等待Sn_SR变成SOCK_UDP。然后就可以收发了。发送数据先读Sn_TX_FSR空闲发送缓冲大小确认够用然后写Sn_TX_WR发送写指针通过SPI把数据写进TX缓冲再更新Sn_TX_WR最后写Sn_CR执行SEND命令。接收数据读Sn_RX_RSR接收数据大小如果大于0读Sn_RX_RD接收读指针从RX缓冲读数据更新Sn_RX_RD写Sn_CR执行RECV命令。3.3 BACnet应用层逻辑实现应用层的主循环里做三件事调用bacnet_task处理协议栈事务、执行DDC控制逻辑、处理传感器采集。bacnet_task要周期调用我放在1ms定时中断里设个标志位主循环里检测到标志就调用。DDC控制逻辑我实现了一个简单的PID控制器用于模拟输出。传感器采集用ADCSTM32F407有3个ADC12位精度我用了8个通道接NTC热敏电阻和4-20mA信号。模拟输入对象的Present Value更新ADC采样值经过换算得到实际物理量然后调用bacnet的API更新对象属性。比如温度值ADC读到2048对应1.65VNTC分压电路在25度时输出1.65V那2048就对应25度。实际换算要用查表法或者Steinhart-Hart公式我用的是查表加线性插值精度能到0.1度。更新完属性后如果变化超过COV增量协议栈会自动发送COV通知给订阅了的客户端。模拟输出对象的控制Yabe写入Present Value后协议栈会调用一个回调函数你在回调里读取写入的值然后设置PWM占空比或者DAC输出。我用的PWMTIM4的四个通道频率1kHz占空比0到100%对应输出0到10V。0到10V的转换用RC滤波加运放PWM经过两级RC滤波得到0到3.3V再通过运放放大到0到10V。运放用LM358单电源供电同相放大增益3.03倍。二进制输入对象接干接点或者光耦隔离的数字信号。STM32的GPIO配置成上拉输入外部接光耦的集电极光耦导通时GPIO被拉低对应active状态。二进制输出对象GPIO配置成推挽输出通过ULN2003驱动继电器。继电器选5V的ULN2003的COM脚接5V加续流二极管。每个输出通道加一个LED指示灯方便调试。3.4 Yabe联调与功能验证硬件和软件都准备好后开始联调。先给STM32上电用串口打印调试信息看W5500初始化是否成功IP地址是多少。然后打开电脑的命令行ping一下STM32的IP。如果ping不通检查网线、IP设置、W5500的socket状态。ping通后打开Yabe添加设备点Who-Is。正常情况下设备树里会出现你的设备设备名称是“STM32 DDC Controller”实例号是你设的那个。展开设备对象找到Analog Input 0双击Present Value应该能看到当前温度值。如果显示“Error: Unknown Object”说明对象列表里没有这个对象检查device.c里的对象列表配置。如果显示“Error: Timeout”说明通信有问题检查W5500的socket有没有收到数据可以在代码里加打印看接收缓冲里有没有数据。如果Yabe能读到值但写不进去检查对象有没有实现WriteProperty服务模拟输入对象默认是只读的要改成可写需要在代码里设置。测试COV功能在Yabe里右键点Analog Input 0选“Subscribe COV”设置订阅时间和COV增量。然后用手捏住NTC热敏电阻温度上升超过COV增量后Yabe会自动收到通知Present Value自动更新。如果没收到通知检查协议栈的COV处理逻辑确认订阅时有没有正确保存订阅信息。COV通知是BACnet的一个重要功能楼宇自控系统里大量使用调试的时候要重点验证。测试二进制输出在Yabe里找到Binary Output 0右键选“Write Property”Present Value写active点确定。应该能听到继电器吸合的声音对应的LED点亮。如果没反应检查GPIO配置和ULN2003的焊接。写inactive继电器释放。测试模拟输出Analog Output 0写50用万用表测输出端子应该是5V左右。写100应该是10V。如果输出不对检查PWM占空比和运放电路。4. 常见问题与排查技巧实录4.1 W5500通信异常问题汇总W5500用几天后连不上、ping断断续续这个问题我遇到过好几次。最常见的原因是SPI通信受干扰。W5500的SPI时钟线如果走线太长或者跟其他高速信号线平行走容易耦合噪声。解决办法SPI线尽量短包地处理SCK线上串一个22欧姆的电阻。另外W5500的电源去耦要做好每个电源引脚旁边放一个100nF电容整体再放一个10uF电容。第二个原因是W5500的socket缓冲区溢出。如果接收数据后没有及时释放缓冲区RX缓冲满了之后W5500就不再接收新数据了。解决办法在接收处理函数里确保每次读完数据都执行RECV命令。如果数据处理耗时较长可以先把数据拷贝到自己的缓冲区立即执行RECV然后再慢慢处理。我一般开一个256字节的接收缓冲收到数据后马上拷贝出来然后释放W5500的缓冲。第三个原因是网络风暴。如果网络里有设备在大量广播W5500的接收缓冲很快就会被填满。解决办法在W5500的MR寄存器里打开广播过滤只接收特定端口的广播。BACnet/IP的广播端口是47808其他端口的广播直接丢弃。另外可以在应用层加一个简单的过滤只处理BACnet/IP格式的数据包其他数据包直接忽略。还有一个隐蔽的问题W5500的晶振不起振或者频率偏移。25MHz晶振如果负载电容不匹配起振时间会很长甚至不起振。表现就是W5500初始化偶尔失败或者通信时好时坏。解决办法用示波器测晶振引脚看波形是否稳定。如果起振慢减小负载电容。如果频率偏移大换一个精度更高的晶振比如±10ppm的。4.2 BACnet协议栈调试常见错误BACnet协议栈移植过程中最常见的错误是字节序问题。BACnet协议规定网络字节序是大端STM32是小端所以所有多字节数据都要转换。协议栈内部已经处理了大部分转换但在应用层读写属性时要注意。比如你从ADC读到一个16位值要存到Real类型的Present Value里需要先转成float再转成网络字节序。我一开始忘了转Yabe读到的值全是乱的。第二个常见错误是对象实例号冲突。BACnet网络里每个对象的实例号必须唯一如果你定义了两个Analog Input 0协议栈会报错。解决办法在device.c里仔细检查对象列表确保每个对象的实例号不重复。我一般用宏定义来管理比如AI_TEMP_ROOM的实例号是0AI_TEMP_SUPPLY的实例号是1这样不容易搞混。第三个错误是APDU长度超限。BACnet的APDU最大长度是1476字节如果超过这个长度协议栈会分片。但有些客户端不支持分片就会报错。解决办法尽量把对象属性控制在合理范围内不要在一个响应里返回太多数据。如果确实需要返回大量数据可以分多次读取或者用ReadPropertyMultiple服务。第四个错误是设备实例号重复。如果你的网络里有两个设备用了同一个实例号Yabe会发现两个设备但只能看到一个或者两个设备互相冲突。解决办法设备实例号用DIP开关或者EEPROM配置保证每个设备不一样。我一般用STM32的UID低16位作为设备实例号这样基本不会重复。4.3 Yabe工具使用中的坑Yabe的版本很多不同版本的行为有差异。我推荐用0.9.2版本比较稳定。有些新版本在Windows 10上会有兼容性问题比如界面显示不全、按钮点不动。解决办法右键Yabe.exe属性里设置兼容模式为Windows 7勾选“以管理员身份运行”。如果还是不行换一个版本试试。Yabe添加设备时IP地址和端口要填对。端口默认是47808但有些版本要求填十六进制0xBAC0。如果填错了Yabe会一直显示“Device not found”。解决办法先确认Yabe的版本看它的文档里端口怎么填。如果不确定两个都试试。另外如果电脑有防火墙要允许Yabe通过防火墙否则广播包发不出去。Yabe读取属性时如果设备响应慢Yabe会超时。默认超时时间是3秒如果网络延迟大或者设备处理慢就会报“Timeout”。解决办法在Yabe的设置里把超时时间改大比如10秒。另外如果设备同时处理多个请求可能会来不及响应可以在协议栈里加一个请求队列按顺序处理。Yabe写入属性时如果属性是只读的会报“Write Access Denied”。解决办法在代码里把对象的WriteProperty服务打开。对于模拟输入对象默认是只读的要改成可写需要修改对象属性。但要注意模拟输入对象通常不应该可写因为它是传感器输入。如果要测试写入可以用模拟输出对象或者模拟值对象。4.4 常见问题速查表现象可能原因排查方法解决方案W5500初始化失败SPI时序错误读版本寄存器检查SPI模式、CS控制ping断断续续SPI受干扰示波器看SCK波形缩短SPI线、加串联电阻Yabe找不到设备广播地址不对检查Yabe设置改子网广播地址读属性超时设备处理慢串口打印调试加大Yabe超时时间写属性被拒绝属性只读检查对象配置打开WriteProperty服务COV通知收不到订阅未保存检查订阅处理保存订阅信息并定时检查模拟输出不准PWM滤波不足万用表测输出增加RC滤波级数设备实例号冲突配置重复检查device.c用UID生成实例号4.5 实操心得与避坑建议第一个心得调试BACnet一定要有耐心协议栈的日志很有用。BACnet Stack支持调试输出可以在编译选项里打开DEBUG协议栈会把收发的每个APDU都打印出来。通过串口看这些日志能快速定位是发送问题还是接收问题。我一般把日志级别设成3只打印错误和重要事件避免日志太多影响实时性。第二个心得W5500的SPI驱动要加超时机制。如果W5500死机了SPI读写会一直等待导致整个系统卡死。解决办法在SPI读写函数里加一个超时计数器超过一定次数就返回错误然后复位W5500。我设的超时是1000次循环大概1ms左右。如果超时拉低W5500的RST引脚重新初始化。第三个心得BACnet对象的值更新要加锁。如果主循环和中断都在更新同一个对象可能会出现数据竞争。解决办法在更新对象属性时关中断更新完再开中断。或者用一个标志位主循环里统一更新。我一般用后者中断里只设标志主循环里处理。第四个心得Yabe的COV订阅要定期刷新。BACnet的COV订阅有生命周期默认是60秒过期后设备就不再发送通知了。Yabe会自动刷新订阅但如果网络不稳定刷新可能失败。解决办法在设备端记录订阅的剩余时间快过期时主动发送通知提醒客户端刷新。或者把订阅生命周期设长一点比如300秒。第五个心得PCB布局对W5500的稳定性影响很大。W5500的晶振要尽量靠近芯片负载电容的地要跟芯片的地单点连接。网络变压器的差分线要等长阻抗控制到50欧姆。RJ45座要靠近板边方便插网线。电源部分要远离晶振和差分线避免干扰。我第一版PCB没注意这些W5500经常掉线第二版改了布局就稳定了。第六个心得STM32的Flash和RAM要留足余量。BACnet协议栈加上应用逻辑Flash大概占80KBRAM大概占25KB。STM32F407有1MB Flash和192KB RAM余量很足。但如果用F103Flash只有64KB或128KBRAM只有20KB就很紧张了。建议至少用F103RC或F103REFlash 256KB以上RAM 48KB以上。第七个心得调试的时候先用静态IP别用DHCP。DHCP会增加不确定性调试阶段用静态IP更可控。等基本功能都调通了再考虑加DHCP。W5500支持DHCP但需要额外的代码而且DHCP服务器如果响应慢会影响设备启动时间。楼宇自控里一般用静态IP因为设备位置固定IP也固定。第八个心得BACnet的设备名称和对象名称要规范。设备名称建议用“楼栋-楼层-房间-设备类型”的格式比如“A-3F-301-FCU”。对象名称也要有意义比如“RoomTemp”、“SupplyTemp”、“FanSpeed”。这样在Yabe里一看就知道是什么调试和维护都方便。我见过有人用“AI0”、“AI1”这种命名过两天自己都忘了哪个是哪个。第九个心得W5500的socket要加心跳机制。如果网络断开W5500的socket可能还保持着连接状态但实际上已经不通了。解决办法定期发送一个心跳包比如每30秒发一个Who-Is广播如果连续3次没有收到任何响应就复位W5500重新初始化。这个机制能自动恢复大部分网络异常。第十个心得代码要模块化方便移植。W5500驱动、BACnet协议栈、应用逻辑分成三个独立的模块模块之间通过接口函数通信。这样如果换MCU或者换以太网芯片只需要改驱动模块协议栈和应用逻辑不用动。我后来把W5500换成LAN8720只改了半天就搞定了就是因为模块化做得好。
返回列表