本文仅为学习笔记,前面介绍DL-LN33的通信协议,第二部分使用stm32f103VET6简单操控DL-LN33。在产品说明书中有模块更详细,细致的描述。
简介
DL-LN33模块是一个无线通信模块,他的通信协议和zigbee的模块类似,但并不是严格的zigbee通信协议。
好处是,无需学习zigbee通信协议,通过串口向模块发送指令,即可完成传输数据的任务,模块上电后,会自动寻找通信范围内的设备,可谓上电自组网。
通信协议
USART协议格式
DL-LN33使用Uart作为数据交互接口,使用异步通信,所以要规定起始位,停止位和校验位以便通信,通信格式如下:
位名 | 宽度(位) |
---|---|
起始位 | 1 |
数据位 | 8 |
停止位 | 1 |
校验位 | 0 |
其端口波特率可调,只要有串口功能的单片机都可以使用DL-LN33通信。
包分隔
通过串口向DL-LN33发送不同的数据,就会产生不同的效果。这里,发送的数据需要符合一定的规则,如要求DL-LN33完成如下任务
把数据 00 AE 13 33 发往地址为0003的模块,目标端口号为90,源端口号为91
我们发送的数据如下:
对应的描述为:
要注意以下两点:
- 目标地址为两个字节,先传输低8位,再传输高8位。
- 传输时,若数据,地址,或端口号出现 FF,则用 FE FD 代替;若出现 FE 则用 FE FC 代替。这被称为 “转义”。
- 转义不改变数据长度:如用上例发送 09 FF,因数据中有 FF,转义为 09 FE FD,数据长度仍为2字节。
端口
DL-LN33设计了端口的概念,端口号的取值为 0x00 ~ 0xFF,其中0x00 ~ 0x7F,被内部程序占用,0x80 ~ 0xFF 可以用于传输数据。这样带来的好处是,接收信息MCU可以根据不同的端口号采取不同的处理方式。
举例
-
节点间的数据传输
MCU采集到温度为23(0x17),湿度为60(0x3C)。使用A0端口传输温度,A1端口传输温度;MCU的地址为0001,电脑地址为0x000F.
MCU发送给模块的数据为:
电脑接收到的数据为:
可以看见,当DL-LN33发送数据时,会把指令中目标地址替换为自己的地址发送出去。 -
给内部端口发送数据
当发送 FE 05 91 20 03 00 0A FF时,地址为0300的模块会点亮自带红灯一秒。 -
信息指令
向模块内部端口发送某些信号可以获得模块的信息。如发送 FE 05 90 21 00 00 01 FF,模块会通过其Tx引脚返回自己的地址。如返回 FE 07 21 90 00 00 21 0F 00 FF。标红的地方就是地址。
在说明书中,对各种指令有更详细的描述。 -
设置指令
向模块发送某些指令,可以修改模块的信息。如发送 :FE 07 90 21 00 00 1F 00 FF,可把地址设置为 0x001F。发出指令后,模块会返回响应包,若响应包的数据部分为0x00 则表示修改成功。
在发送设置指令后必须发送重启指令 FE 05 90 21 00 00 10 FF,才能成功设置。
在说明书中,对各种指令有更详细的描述。
开始编程
基于stm32f103VET6,使用固件库编程,使用野火指南者教程中USART部分代码。
完成:使用stm32的USART2向DL-LN33模块发送查询地址指令,DL-LN33返回数据给stm32的USART2,触发中断,在中断中使用USART1把数据返回给电脑。
硬件连接
使用指南者开发板,USART1已经通过USART转串口连接到电脑,USART2的Tx引脚为PA2,连接模块的Rx;USART2的Rx引脚为PA3,连接模块的Tx;最后为模块上电。
main函数
#include "stm32f10x.h"
#include "bsp_usart.h"
int main(void)
{
//查询地址的指令
uint8_t a[8] = {0xFE,0x05,0X90,0X21,0x00,0x00,0X01,0XFF};
USART1_Config(); //初始化USART1,不开启中断
USART2_Config(); //初始化USART2,其中配置了中断
Usart_SentArray(USART2,a,8);//使用发送数组的函数
while(1)
{
}
}
中断服务函数
void USART2_IRQHandler(void)
{
uint8_t ucTemp;
if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)
{
ucTemp = USART_ReceiveData(USART2);
USART_SendData(USART1,ucTemp);
}
}