E70_433半双工无线模组,伪全双工方案
前言
要搞一个远程数据传输,性价比高的模块是433模块类型,一开始选用的是E70_433模组但是后来发现需要能够全双工,E62模块大概要贵50块钱,因此就继续尝试用E70模组,看看能不能降一点成本,因此就有了以下这个方案_φ_(..) 写作业
如果是全双工模块外侧输入数据可以直接接入串口:
A-(串口)-E62_433——(空中信道)
但是因为是半双工因此我需要加入一个mcu(stm32)控制串口
A-(串口)-stm32-(串口)-E70_433——(空中信道)
本文的设计内容为stm32里的转发程序
架构设计
全双工意味着输入的时候可以输出,半双工意味着只能选择输入或者输入,因此如果半双工切换状态的速度够快,在长的时间尺度上就可以实现全双工的效果。
外侧输入模块
首先,外侧流入数据的速度必须低于433模块数据吞吐的速度因为433模组切换状态和发送都需要时间。
其次,通讯可能会锻炼,比如突然有强信号干扰,因此必须有一个合适大小的数据缓存区域,为了方便存储和读取,必须采用队列存储方式
最后,注意中断
外侧输出模块
首先,由于433速度大于外侧数据吞吐速度,因此必须有一个合适大小的数据缓存区域(需要略大于输入缓存区)
其次,为了加快通讯速度,必须采用中断发送而不是阻塞发送,因此需要使用队列存贮方式。
最后,注意中断
内侧发帧模块
两组433间的通讯认为是内侧通讯,这里主要执行的功能是读取外侧输入模块封存的数据帧和内侧接受模块封存的数据帧,拼接完成后组包对外发送。
内侧接受模块
两组433间的通讯认为是内侧通讯,这里主要执行的功能是接受另一侧433模块传来的数据包。当数据包正常时,将数据解包封存进入外侧发送模块,并且将外侧数据封存一帧以实现连续传输;当数据包不正常时(缺头,缺尾,缺身子,长度错误…等等)丢弃这一帧数据,立即回传一个重发信号包,以确保数据的稳定性
实现代码
通用宏定义
#define BUFF_LEN_B 5000
#define BUFF_LEN_O 6000
#define BUFF_LEN 200
#define FRAME_CLUB_MAX 49 //帧组最大数量
#define M_TRUE 0x5a //未启用
#define M_FALSE 0xa5 //未启用
#define TRUE 1
#define FALSE 0
#define PPP_FLAG 0x7e //ppp协议的帧头和帧尾部
#define PPP_START 0xFF //ppp协议的帧的开始
#define E70_STATE_LISTEN 0x34 //433模块状态 接受数据包完成
#define E70_STATE_SEND 0x43 //433模块状态 发送数据包完成
#define E70_STATE_START 0x00 //433模块状态 准备建立通路
#define E70_STATE_OVERTIME 0x0E //433模块状态 接受数据超时请求重发 新增:数据错误请求重发
#define E70_STATE_LISTEN_E 0x3E //433模块状态 接受丢包反馈完成
#define E70_STATE_RESEND 0xE3 //433模块状态 重新发送数据包完成
#define PACK_MAX_DATA_LEN 100 //设定433模组间发送最大数据长度
#define PACK_HEAD_lEN 2 //设定包的头字节长度
#define PACK_LEN_lEN 2 //设定包的长度字节长度
#define PACK_NUMBER_lEN 2 //设定包的序号字节长度
#define PACK_FUNCTION_lEN 1 //设定包的类别字节长度
#define PACK_END_lEN 2 //设定包的结尾长度
#define PACK_OUTDATA_LEN (PACK_HEAD_lEN +\
PACK_LEN_lEN+\
PACK_NUMBER_lEN+\
PACK_FUNCTION_lEN+\
PACK_END_lEN)
//设定433模组间除数据外的长度
#define PACK_MAX_LEN (PACK_OUTDATA_LEN + PACK_MAX_DATA_LEN)
//设定433模组最大的数据长度
#define PACK_HEAD_DATA 0x1234 //设定433模组包头
#define PACK_END_DATA 0x4321 //设定433模组包头
#define PACK_FUNCTION_WIFI 0x01 //设定433模组包功能:wifi方面启动发包 wifi start (未启用)
#define PACK_FUNCTION_DATA 0x02 //设定433模组包功能:数值 data
#define PACK_FUNCTION_NULL 0x03 //设定433模组包功能:空 null (未启用)
#define PACK_FUNCTION_4G 0x04 //设定433模组包功能:4g方面启动发包 4g start (未启用)
#define PACK_FUNCTION_RESEND 0x05 //设定433模组包功能:接受方重新发送上一包数据
#define LOSE_HEAD_COUNT 0x02 //设定包头丢失最大计数
#define LOSE_HEAD_MODE_FINE 0x00 //设定包头丢失模式:无异常
#define LOSE_HEAD_MODE_WAIT 0x01 //设定包头丢失模式:等待判断
#define LOSE_HEAD_MODE_GET 0x02 //设定包头丢失模式:获取包尾
#define LOSE_HEAD_MODE_OUT 0x03 //设定包头丢失模式:获取超时
#define LOSE_TAIL_MODE_FINE 0x00 //设定包尾丢失模式:无异常
#define LOSE_TAIL_MODE_WAIT 0x01 //设定包尾丢失模式:等待判断
#define LOSE_TAIL_MODE_GET 0x02 //设定包尾丢失模式:获取包尾
#define LOSE_TAIL_MODE_OUT 0x03 //设定包尾丢失模式:获取超时
#define E70_TIME_OUT 500 // (单位是ms)
#define EC20_TIME_OUT 200 // (单位是ms)
#define LOSE_HEAD_TIME_OUT 100 // (单位是ms)
#define LOSE_TAIL_TIME_OUT 100 // (单位是ms)
#define LOSE_PACK_TIME_OUT 200 // (单位是ms) 19200 帧间隔应该近似62.5m
struct _LOSE_HEAD_
{
__IO u32 Time; //包头丢失超时时间
__IO uint8_t Count; //帧头丢失计数
__IO uint8_t EndCount; //帧尾获取计数
__IO uint8_t Mode; //帧头丢失种类 //0.正常,1.等待判断,2.获取包尾,3.超时判别
};
struct _LOSE_TAIL_
{
__IO u32 Time; //帧尾丢失超时时间
__IO uint8_t Count; //帧头丢失计数
__IO uint8_t EndCount; //帧尾获取计数
__IO uint8_t Mode; //帧尾丢失种类 //0.正常,1.等待判断,2.获取包尾,3.超时判别
};
#define LOSE_HEAD _LOSE_HEAD_
#define LOSE_TAIL _LOSE_TAIL_
#define OUTSIDE USART2
#define INSIDE USART1
#define OUTSIDE_TX_BUFF USART2_TX_BUFF
#define OUTSIDE_RX_BUFF USART2_RX_BUFF
#define INSIDE_TX_BUFF USART1_TX_BUFF
#define INSIDE_RX_BUFF USART1_RX_BUFF
#define OUTSIDE_TX_LEN USART2_TX_LEN
#define OUTSIDE_RX_LEN USART2_RX_LEN
#define INSIDE_TX_LEN USART1_TX_LEN
#define INSIDE_RX_LEN USART1_RX_LEN
#define OUTSIDE_TX_QUEUE_LEN USART2_TX_QUEUE_LEN
#define OUTSIDE_TX_END_LEN USART2_TX_END_LEN
#define g_sysOutTime g_sysMTime
// 433 模块数据包接受完成后就是等待数据发送,数据发送完成后就是等待接受数据包,来回通讯
// 433 (send) ->- 433 (start) to 433 (send) --- 433 (listen) start mode
// 433 (send) -<- 433 (send) to 433 (listen) --- 433 (send)
// 433 (send) ->- 433 (send) to 433 (send) --- 433 (listen)
// or
// 433 (send) ->- 433 (send) to 433 (send) --- 433 (overtime)
// 433 (send) -<- 433 (send) to 433 (lis_e) --- 433 (send)
// 433 (re_s) ->- 433 (send) to 433 (re_s) --- 433 (listen) resend lost pack
// or
// 433 (re_s) ->- 433 (send) to 433 (re_s) --- 433 (overtime)
// 433 (re_s) -<- 433 (send) to 433 (listen) --- 433 (send) jump lost pack
代码解析
以上建一个.h文件丢入,然后#include
就可以了
其中OUTSIDE
是对外侧连接的串口
其中INSIDE
是对内侧连接的串口
其余有问题请留言_(´ཀ`」∠)_加班
通用工具函数
//在字符串1里找字符串2,返回字符串2结束在字符串1的位置,找不到时反馈0
uint16_t CompareString(uint8_t* Str1 ,uint8_t * Str2 ,uint16_t Str1_len,uint16_t Str2_len)
{
uint16_t outLen = 0;
uint16_t startLen = 0;
uint16_t i = 0;
if(Str1_len<Str2_len||Str2_len==0||Str1_len==0) //校验异常
return 0;
startLen=Str1_len-Str2_len;
for(i=0;i<=startLen;i++)
{
if(*(Str1+i)==*Str2) //找到起始字符
{
for(outLen=0;outLen<Str2_len;outLen++)
{
if(*(Str1+i+outLen)!=*(Str2+outLen))
{
// printf("[test] i=%d, outLen=%d,*(Str1+i+outLen)=%x,*(Str2+outLen)=%x\r\n",
// i,outLen,*(Str1+i+outLen),*(Str2+outLen));
break;
}
}
if(outLen==Str2_len)
return outLen+i; //待验证
}
}
return 0;
}
//在字符串1里找字符串2,返回字符串2结束在字符串1的位置,找不到时反馈0
uint16_t GetPackLen(uint8_t* Str1,uint16_t len)
{
uint16_t outPackLen = 0;
uint16_t i = 0;
uint8_t temp = 0;
if(len==0)
return 0; //return